https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ef3e7a3717e13a97a652a9...
commit ef3e7a3717e13a97a652a961e5217a249778f4d4 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sun Feb 28 12:45:16 2021 +0900 Commit: GitHub noreply@github.com CommitDate: Sun Feb 28 12:45:16 2021 +0900
[SDK][ATL] Implement UnsubclassWindow methods (#3492)
I want UnsubclassWindow methods. - Implement CWindowImpl::UnsubclassWindow method. - Implement CContainedWindowT::UnsubclassWindow method. - Add SubclassWindow testcase to atl_apitest test program. - Fix generic text mapping of <atlwin.h>. CORE-9281 --- modules/rostests/apitests/atl/CMakeLists.txt | 3 +- modules/rostests/apitests/atl/SubclassWindow.cpp | 428 +++++++++++++++++++++ modules/rostests/apitests/atl/devenv/.gitignore | 16 + modules/rostests/apitests/atl/devenv/ATLTest.sln | 10 + .../apitests/atl/devenv/SubclassWindow.vcxproj | 189 +++++++++ modules/rostests/apitests/atl/testlist.c | 2 + sdk/lib/atl/atlwin.h | 89 +++-- 7 files changed, 712 insertions(+), 25 deletions(-)
diff --git a/modules/rostests/apitests/atl/CMakeLists.txt b/modules/rostests/apitests/atl/CMakeLists.txt index 555529b7e38..8f12a5071aa 100644 --- a/modules/rostests/apitests/atl/CMakeLists.txt +++ b/modules/rostests/apitests/atl/CMakeLists.txt @@ -16,7 +16,8 @@ list(APPEND SOURCE CRegKey.cpp CSimpleArray.cpp CSimpleMap.cpp - CString.cpp) + CString.cpp + SubclassWindow.cpp)
list(APPEND PCH_SKIP_SOURCE testlist.c) diff --git a/modules/rostests/apitests/atl/SubclassWindow.cpp b/modules/rostests/apitests/atl/SubclassWindow.cpp new file mode 100644 index 00000000000..f372b1e7f9e --- /dev/null +++ b/modules/rostests/apitests/atl/SubclassWindow.cpp @@ -0,0 +1,428 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for SubclassWindow/UnsubclassWindow + * PROGRAMMER: Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#ifdef HAVE_APITEST + #include <apitest.h> + #define ATLASSUME(x) /*empty*/ + #define ATLASSERT(x) /*empty*/ +#else + #include "atltest.h" + #define ATLASSUME(x) do { \ + trace("ATLASSUME(%s) %s.\n", #x, ((x) ? "success" : "failure")); \ + } while (0) + #define ATLASSERT(x) do { \ + trace("ATLASSERT(%s) %s.\n", #x, ((x) ? "success" : "failure")); \ + } while (0) +#endif + +#include <atlbase.h> +#include <atlwin.h> + +#ifdef _WIN64 + #define INVALID_HWND ((HWND)(ULONG_PTR)0xDEADBEEFDEADBEEFULL) +#else + #define INVALID_HWND ((HWND)(ULONG_PTR)0xDEADBEEF) +#endif + +static BOOL s_flag = TRUE; + +class CMyCtrl1 : public CWindowImpl<CMyCtrl1, CWindow> +{ +public: + static LPCWSTR GetWndClassName() + { + if (s_flag) + return L"EDIT"; + else + return L"STATIC"; + } + + CMyCtrl1() + { + } + virtual ~CMyCtrl1() + { + } + + BEGIN_MSG_MAP(CMyCtrl1) + END_MSG_MAP() +}; + +class CMyCtrl2 + : public CContainedWindowT<CWindowImpl<CMyCtrl2, CWindow> > +{ +public: + static LPCWSTR GetWndClassName() + { + if (s_flag) + return L"EDIT"; + else + return L"STATIC"; + } + + CMyCtrl2() : CContainedWindowT<CWindowImpl<CMyCtrl2, CWindow> >(this) + { + } + virtual ~CMyCtrl2() + { + } + + BEGIN_MSG_MAP(CMyCtrl2) + END_MSG_MAP() +}; + +static HWND MyCreateWindow(DWORD style) +{ + return CreateWindowW(L"EDIT", NULL, style, + CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, + NULL, NULL, GetModuleHandleW(NULL), NULL); +} + +static LRESULT CALLBACK +MyWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return 0; +} + +START_TEST(SubclassWindow) +{ + const DWORD style = WS_POPUPWINDOW | ES_MULTILINE; + HWND hwnd1, hwnd2; + WNDPROC fn1, fn2; + BOOL b; + trace("DefWindowProcA == %p\n", DefWindowProcA); + trace("DefWindowProcW == %p\n", DefWindowProcW); + trace("MyWindowProc == %p\n", MyWindowProc); + + // + // Ctrl1 + // + { + CMyCtrl1 Ctrl1; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl1.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + hwnd2 = Ctrl1.UnsubclassWindow(); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 != fn2, "fn1 == fn2\n"); + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + DestroyWindow(hwnd2); + ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); + } + + { + CMyCtrl1 Ctrl1; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl1.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + DestroyWindow(hwnd1); // destroy now + hwnd2 = Ctrl1.UnsubclassWindow(); + ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); + fn2 = Ctrl1.m_pfnSuperWindowProc; + ok(fn2 == fn1, "fn2 was %p\n", fn2); + DestroyWindow(hwnd2); + ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); + } + + { + CMyCtrl1 Ctrl1; + s_flag = FALSE; // "STATIC" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl1.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + hwnd2 = Ctrl1.UnsubclassWindow(); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 != fn2, "fn1 == fn2\n"); + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + DestroyWindow(hwnd2); + ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); + } + + { + CMyCtrl1 Ctrl1; + s_flag = FALSE; // "STATIC" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl1.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + DestroyWindow(hwnd1); // destroy now + hwnd2 = Ctrl1.UnsubclassWindow(); + ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); + fn2 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 == fn2, "fn1 != fn2\n"); + DestroyWindow(hwnd2); + ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); + } + + { + CMyCtrl1 Ctrl1; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl1.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); + Ctrl1.m_pfnSuperWindowProc = MyWindowProc; + hwnd2 = Ctrl1.UnsubclassWindow(); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl1.m_pfnSuperWindowProc; + ok(fn1 == fn2, "fn2 was %p\n", fn2); + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + DestroyWindow(hwnd2); + ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); + } + + // + // Ctrl2 (Not Forced) + // + { + CMyCtrl2 Ctrl2; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + hwnd2 = Ctrl2.UnsubclassWindow(FALSE); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != fn2, "fn1 == fn2\n"); + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + } + + { + CMyCtrl2 Ctrl2; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + DestroyWindow(hwnd1); // destroy now + hwnd2 = Ctrl2.UnsubclassWindow(FALSE); + ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == fn2, "fn1 == fn2\n"); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + } + + { + CMyCtrl2 Ctrl2; + s_flag = FALSE; // "STATIC" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + hwnd2 = Ctrl2.UnsubclassWindow(FALSE); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != fn2, "fn1 == fn2\n"); + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + } + + { + CMyCtrl2 Ctrl2; + s_flag = FALSE; // "STATIC" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + DestroyWindow(hwnd1); // destroy now + hwnd2 = Ctrl2.UnsubclassWindow(FALSE); + ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn2 != DefWindowProc, "fn2 was %p\n", fn2); // ntdll.dll!NtdllEditWndProc_W + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + } + + { + CMyCtrl2 Ctrl2; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + Ctrl2.m_pfnSuperWindowProc = MyWindowProc; + hwnd2 = Ctrl2.UnsubclassWindow(FALSE); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + ok(Ctrl2.m_hWnd == NULL, "hwnd != NULL\n"); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "hwnd != NULL\n"); + } + + // + // Ctrl2 (Forced) + // + { + CMyCtrl2 Ctrl2; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + hwnd2 = Ctrl2.UnsubclassWindow(TRUE); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != fn2, "fn1 == fn2\n"); + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + } + + { + CMyCtrl2 Ctrl2; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + DestroyWindow(hwnd1); // destroy now + hwnd2 = Ctrl2.UnsubclassWindow(TRUE); + ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn2 == fn1, "fn2 was %p\n", fn2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + } + + { + CMyCtrl2 Ctrl2; + s_flag = FALSE; // "STATIC" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + hwnd2 = Ctrl2.UnsubclassWindow(TRUE); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != fn2, "fn1 == fn2\n"); + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + } + + { + CMyCtrl2 Ctrl2; + s_flag = FALSE; // "STATIC" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); + DestroyWindow(hwnd1); // destroy now + hwnd2 = Ctrl2.UnsubclassWindow(TRUE); + ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn2 != DefWindowProc, "fn2 was %p\n", fn2); // ntdll.dll!NtdllEditWndProc_W + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + } + + { + CMyCtrl2 Ctrl2; + s_flag = TRUE; // "EDIT" + hwnd1 = MyCreateWindow(style); + ok(hwnd1 != NULL, "hwnd1 was NULL\n"); + fn1 = Ctrl2.m_pfnSuperWindowProc; + ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); + b = Ctrl2.SubclassWindow(hwnd1); + ok_int(b, TRUE); + ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); + Ctrl2.m_pfnSuperWindowProc = MyWindowProc; + hwnd2 = Ctrl2.UnsubclassWindow(TRUE); + ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); + fn2 = Ctrl2.m_pfnSuperWindowProc; + ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); + ok(Ctrl2.m_hWnd == NULL, "hwnd != NULL\n"); + DestroyWindow(hwnd2); + ok(Ctrl2.m_hWnd == NULL, "hwnd != NULL\n"); + } +} diff --git a/modules/rostests/apitests/atl/devenv/.gitignore b/modules/rostests/apitests/atl/devenv/.gitignore new file mode 100644 index 00000000000..15eeeeb1607 --- /dev/null +++ b/modules/rostests/apitests/atl/devenv/.gitignore @@ -0,0 +1,16 @@ +*.opendb +*.db +x64/ +.vs/ +CAtlArray/ +CAtlFileMapping/ +CAtlList/ +CComHeapPtr/ +CComObject/ +CComQIPtr/ +CHeapPtrList/ +CImage/ +CSimpleArray/ +CSimpleMap/ +CString/ +SubclassWindow/ diff --git a/modules/rostests/apitests/atl/devenv/ATLTest.sln b/modules/rostests/apitests/atl/devenv/ATLTest.sln index 8fd0e07a092..9811121c7fd 100644 --- a/modules/rostests/apitests/atl/devenv/ATLTest.sln +++ b/modules/rostests/apitests/atl/devenv/ATLTest.sln @@ -25,6 +25,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CHeapPtrList", "CHeapPtrLis EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CComHeapPtr", "CComHeapPtr.vcxproj", "{F10E34E3-FB53-4650-985A-28BD1905D65C}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SubclassWindow", "SubclassWindow.vcxproj", "{ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -121,6 +123,14 @@ Global {F10E34E3-FB53-4650-985A-28BD1905D65C}.Release|x64.Build.0 = Release|x64 {F10E34E3-FB53-4650-985A-28BD1905D65C}.Release|x86.ActiveCfg = Release|Win32 {F10E34E3-FB53-4650-985A-28BD1905D65C}.Release|x86.Build.0 = Release|Win32 + {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Debug|x64.ActiveCfg = Debug|x64 + {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Debug|x64.Build.0 = Debug|x64 + {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Debug|x86.ActiveCfg = Debug|Win32 + {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Debug|x86.Build.0 = Debug|Win32 + {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Release|x64.ActiveCfg = Release|x64 + {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Release|x64.Build.0 = Release|x64 + {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Release|x86.ActiveCfg = Release|Win32 + {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/modules/rostests/apitests/atl/devenv/SubclassWindow.vcxproj b/modules/rostests/apitests/atl/devenv/SubclassWindow.vcxproj new file mode 100644 index 00000000000..5b1569b871c --- /dev/null +++ b/modules/rostests/apitests/atl/devenv/SubclassWindow.vcxproj @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}</ProjectGuid> + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> + <Keyword>AtlProj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140_xp</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <IgnoreImportLibrary>true</IgnoreImportLibrary> + <LinkIncremental>true</LinkIncremental> + <IntDir>$(ProjectName)$(Configuration)</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <IgnoreImportLibrary>true</IgnoreImportLibrary> + <LinkIncremental>true</LinkIncremental> + <IntDir>$(ProjectName)$(Platform)$(Configuration)</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <IgnoreImportLibrary>true</IgnoreImportLibrary> + <LinkIncremental>false</LinkIncremental> + <IntDir>$(ProjectName)$(Configuration)</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <IgnoreImportLibrary>true</IgnoreImportLibrary> + <LinkIncremental>false</LinkIncremental> + <IntDir>$(ProjectName)$(Platform)$(Configuration)</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <ResourceCompile> + <Culture>0x0409</Culture> + <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <ResourceCompile> + <Culture>0x0409</Culture> + <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <ResourceCompile> + <Culture>0x0409</Culture> + <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <ResourceCompile> + <Culture>0x0409</Culture> + <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="../SubclassWindow.cpp"> + <RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MultiThreaded</RuntimeLibrary> + <RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MultiThreaded</RuntimeLibrary> + <RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MultiThreadedDebug</RuntimeLibrary> + <RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MultiThreadedDebug</RuntimeLibrary> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\resource.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\atl_apitest.rc" /> + </ItemGroup> + <ItemGroup> + <None Include="..\cstring.inl" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/modules/rostests/apitests/atl/testlist.c b/modules/rostests/apitests/atl/testlist.c index 028063f826e..213ce2419c4 100644 --- a/modules/rostests/apitests/atl/testlist.c +++ b/modules/rostests/apitests/atl/testlist.c @@ -16,6 +16,7 @@ extern void func_CRegKey(void); extern void func_CSimpleArray(void); extern void func_CSimpleMap(void); extern void func_CString(void); +extern void func_SubclassWindow(void);
const struct test winetest_testlist[] = { @@ -34,5 +35,6 @@ const struct test winetest_testlist[] = { "CSimpleArray", func_CSimpleArray }, { "CSimpleMap", func_CSimpleMap }, { "CString", func_CString }, + { "SubclassWindow", func_SubclassWindow }, { 0, 0 } }; diff --git a/sdk/lib/atl/atlwin.h b/sdk/lib/atl/atlwin.h index 70f0413b41a..d8994988d40 100644 --- a/sdk/lib/atl/atlwin.h +++ b/sdk/lib/atl/atlwin.h @@ -1482,28 +1482,49 @@ public:
BOOL SubclassWindow(HWND hWnd) { - CWindowImplBaseT<TBase, TWinTraits> *pThis; - WNDPROC newWindowProc; - WNDPROC oldWindowProc; - BOOL result; - ATLASSERT(m_hWnd == NULL); ATLASSERT(::IsWindow(hWnd));
+ CWindowImplBaseT<TBase, TWinTraits> *pThis; pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this);
- result = m_thunk.Init(GetWindowProc(), this); + BOOL result = m_thunk.Init(GetWindowProc(), this); if (result == FALSE) return FALSE; - newWindowProc = m_thunk.GetWNDPROC(); - oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc))); + + WNDPROC newWindowProc = m_thunk.GetWNDPROC(); + WNDPROC oldWindowProc = reinterpret_cast<WNDPROC>( + ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc))); if (oldWindowProc == NULL) return FALSE; - m_pfnSuperWindowProc = oldWindowProc; + + pThis->m_pfnSuperWindowProc = oldWindowProc; pThis->m_hWnd = hWnd; return TRUE; }
+ HWND UnsubclassWindow(BOOL bForce = FALSE) + { + ATLASSERT(m_hWnd != NULL); + ATLASSERT(::IsWindow(m_hWnd)); + + CWindowImplBaseT<TBase, TWinTraits>* pThis; + pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this); + + HWND hwndOld = pThis->m_hWnd; + WNDPROC oldWindowProc = m_thunk.GetWNDPROC(); + WNDPROC subclassedProc = reinterpret_cast<WNDPROC>( + ::GetWindowLongPtr(hwndOld, GWLP_WNDPROC)); + if (!bForce && oldWindowProc != subclassedProc) + return NULL; + + ::SetWindowLongPtr(hwndOld, GWLP_WNDPROC, + (LONG_PTR)pThis->m_pfnSuperWindowProc); + pThis->m_pfnSuperWindowProc = ::DefWindowProc; + pThis->m_hWnd = NULL; + return hwndOld; + } + virtual WNDPROC GetWindowProc() { return WindowProc; @@ -1609,7 +1630,7 @@ public: MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this; if (rect.m_lpRect == NULL) rect.m_lpRect = &TBase::rcDefault; - hWnd = ::CreateWindowEx(dwExStyle, reinterpret_cast<LPCWSTR>(MAKEINTATOM(atom)), szWindowName, dwStyle, rect.m_lpRect->left, + hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWindowName, dwStyle, rect.m_lpRect->left, rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left, rect.m_lpRect->bottom - rect.m_lpRect->top, hWndParent, MenuOrID.m_hMenu, _AtlBaseModule.GetModuleInstance(), lpCreateParam);
@@ -1681,7 +1702,7 @@ public: m_pCurrentMsg = NULL; }
- CContainedWindowT(LPTSTR lpszClassName, CMessageMap *pObject, DWORD dwMsgMapID = 0) + CContainedWindowT(LPCTSTR lpszClassName, CMessageMap *pObject, DWORD dwMsgMapID = 0) { m_lpszClassName = lpszClassName; m_pfnSuperWindowProc = ::DefWindowProc; @@ -1697,28 +1718,48 @@ public:
BOOL SubclassWindow(HWND hWnd) { - CContainedWindowT<TBase> *pThis; - WNDPROC newWindowProc; - WNDPROC oldWindowProc; - BOOL result; - ATLASSERT(m_hWnd == NULL); ATLASSERT(::IsWindow(hWnd));
+ CContainedWindowT<TBase> *pThis; pThis = reinterpret_cast<CContainedWindowT<TBase> *>(this);
- result = m_thunk.Init(WindowProc, pThis); + BOOL result = m_thunk.Init(WindowProc, pThis); if (result == FALSE) return FALSE; - newWindowProc = m_thunk.GetWNDPROC(); - oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc))); + + WNDPROC newWindowProc = m_thunk.GetWNDPROC(); + WNDPROC oldWindowProc = reinterpret_cast<WNDPROC>( + ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc))); if (oldWindowProc == NULL) return FALSE; - m_pfnSuperWindowProc = oldWindowProc; + + pThis->m_pfnSuperWindowProc = oldWindowProc; pThis->m_hWnd = hWnd; return TRUE; }
+ HWND UnsubclassWindow(BOOL bForce = FALSE) + { + ATLASSERT(m_hWnd != NULL); + ATLASSERT(::IsWindow(m_hWnd)); + + CContainedWindowT<TBase>* pThis; + pThis = reinterpret_cast<CContainedWindowT<TBase>*>(this); + HWND hwndOld = pThis->m_hWnd; + + WNDPROC subclassedProc = reinterpret_cast<WNDPROC>( + ::GetWindowLongPtr(hwndOld, GWLP_WNDPROC)); + if (!bForce && m_thunk.GetWNDPROC() != subclassedProc) + return NULL; + + ::SetWindowLongPtr(hwndOld, GWLP_WNDPROC, + (LONG_PTR)pThis->m_pfnSuperWindowProc); + pThis->m_pfnSuperWindowProc = ::DefWindowProc; + pThis->m_hWnd = NULL; + return hwndOld; + } + static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CContainedWindowT<TBase> *pThis; @@ -1897,13 +1938,13 @@ static ATL::CWndClassInfo& GetWndClassInfo()
struct _ATL_WNDCLASSINFOW { - WNDCLASSEXW m_wc; - LPCWSTR m_lpszOrigName; + WNDCLASSEX m_wc; + LPCTSTR m_lpszOrigName; WNDPROC pWndProc; - LPCWSTR m_lpszCursorID; + LPCTSTR m_lpszCursorID; BOOL m_bSystemCursor; ATOM m_atom; - WCHAR m_szAutoName[sizeof("ATL:") + sizeof(void *) * 2]; // == 4 characters + NULL + number of hexadecimal digits describing a pointer. + TCHAR m_szAutoName[sizeof("ATL:") + sizeof(void *) * 2]; // == 4 characters + NULL + number of hexadecimal digits describing a pointer.
ATOM Register(WNDPROC *p) {