[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
This commit is contained in:
Katayama Hirofumi MZ 2021-02-28 12:45:16 +09:00 committed by GitHub
parent 76247390e5
commit ef3e7a3717
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 712 additions and 25 deletions

View file

@ -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)
{