https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ef3e7a3717e13a97a652a…
commit ef3e7a3717e13a97a652a961e5217a249778f4d4
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Feb 28 12:45:16 2021 +0900
Commit: GitHub <noreply(a)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(a)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)
{