[SDK:ATL] Fix the size of the ATL_WNDCLASSINFOW::m_szAutoName member according to...
[reactos.git] / sdk / lib / atl / atlwin.h
index f384b90..c35c936 100644 (file)
@@ -20,7 +20,7 @@
 
 #pragma once
 
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
 #define GCCU(x)    x __attribute__((unused))
 #define Unused(x)
 #else
@@ -28,6 +28,7 @@
 #define Unused(x)    (x);
 #endif // __GNUC__
 
+#if !defined(_WIN64)
 #ifdef SetWindowLongPtr
 #undef SetWindowLongPtr
 inline LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
@@ -43,10 +44,23 @@ inline LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex)
     return (LONG_PTR)GetWindowLong(hWnd, nIndex);
 }
 #endif
+#endif // !_WIN64
+
+#pragma push_macro("SubclassWindow")
+#undef SubclassWindow
 
 namespace ATL
 {
 
+#ifndef GET_X_LPARAM
+#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+#endif
+#ifndef GET_Y_LPARAM
+#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+#endif
+
+
+
 struct _ATL_WNDCLASSINFOW;
 typedef _ATL_WNDCLASSINFOW CWndClassInfo;
 
@@ -572,6 +586,17 @@ public:
         return ::GetDlgItemText(m_hWnd, nID, lpStr, nMaxCount);
     }
 
+#ifdef __ATLSTR_H__
+    UINT GetDlgItemText(int nID, CSimpleString& string)
+    {
+        HWND item = GetDlgItem(nID);
+        int len = ::GetWindowTextLength(item);
+        len = GetDlgItemText(nID, string.GetBuffer(len+1), len+1);
+        string.ReleaseBuffer(len);
+        return len;
+    }
+#endif
+
     BOOL GetDlgItemText(int nID, BSTR& bstrText) const
     {
         ATLASSERT(::IsWindow(m_hWnd));
@@ -1276,20 +1301,177 @@ public:
 
 __declspec(selectany) RECT CWindow::rcDefault = { CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 };
 
-template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
-class CWindowImplBaseT : public TBase, public CMessageMap
+template <class TBase = CWindow>
+class CWindowImplRoot : public TBase, public CMessageMap
 {
 public:
     enum { WINSTATE_DESTROYED = 0x00000001 };
-    DWORD m_dwState;
-    const _ATL_MSG *m_pCurrentMsg;
+
+public:
     CWndProcThunk m_thunk;
+    const _ATL_MSG *m_pCurrentMsg;
+    DWORD m_dwState;
+
+    CWindowImplRoot()
+        : m_pCurrentMsg(NULL)
+        , m_dwState(0)
+    {
+    }
+
+    virtual ~CWindowImplRoot()
+    {
+    }
+};
+
+
+template <class TBase = CWindow>
+class CDialogImplBaseT : public CWindowImplRoot<TBase>
+{
+public:
+    // + Hacks for gcc
+    using CWindowImplRoot<TBase>::WINSTATE_DESTROYED;
+    // - Hacks for gcc
+
+    virtual ~CDialogImplBaseT()
+    {
+    }
+    virtual DLGPROC GetDialogProc()
+    {
+        return DialogProc;
+    }
+
+    static INT_PTR CALLBACK StartDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+    {
+        CDialogImplBaseT<TBase> *pThis;
+        DLGPROC newDlgProc;
+        DLGPROC GCCU(pOldProc);
+
+        pThis = reinterpret_cast<CDialogImplBaseT<TBase>*>(_AtlWinModule.ExtractCreateWndData());
+        ATLASSERT(pThis != NULL);
+        if (pThis == NULL)
+            return 0;
+        pThis->m_thunk.Init((WNDPROC)pThis->GetDialogProc(), pThis);
+        newDlgProc = reinterpret_cast<DLGPROC>(pThis->m_thunk.GetWNDPROC());
+        pOldProc = reinterpret_cast<DLGPROC>(::SetWindowLongPtr(hWnd, DWLP_DLGPROC, reinterpret_cast<LONG_PTR>(newDlgProc)));
+        Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
+        pThis->m_hWnd = hWnd;
+        return newDlgProc(hWnd, uMsg, wParam, lParam);
+    }
+
+    static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+    {
+        CDialogImplBaseT<TBase> *pThis = reinterpret_cast<CDialogImplBaseT<TBase>*>(hWnd);
+        _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
+        LRESULT lResult = 0;
+        const _ATL_MSG *previousMessage;
+        BOOL handled;
+
+        hWnd = pThis->m_hWnd;
+        previousMessage = pThis->m_pCurrentMsg;
+        pThis->m_pCurrentMsg = &msg;
+
+        handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
+        ATLASSERT(pThis->m_pCurrentMsg == &msg);
+
+        if (handled)
+        {
+            if ((pThis->m_dwState & WINSTATE_DESTROYED) == 0)
+            {
+                ::SetWindowLongPtr(pThis->m_hWnd, DWLP_MSGRESULT, lResult);
+            }
+        }
+        else
+        {
+            if (uMsg == WM_NCDESTROY)
+            {
+                pThis->m_dwState |= WINSTATE_DESTROYED;
+            }
+        }
+
+        ATLASSERT(pThis->m_pCurrentMsg == &msg);
+        pThis->m_pCurrentMsg = previousMessage;
+
+        if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
+        {
+            pThis->m_dwState &= ~WINSTATE_DESTROYED;
+            pThis->m_hWnd = NULL;
+            pThis->OnFinalMessage(hWnd);
+        }
+        return lResult;
+    }
+
+    virtual void OnFinalMessage(HWND)
+    {
+    }
+};
+
+
+template <class T, class TBase = CWindow>
+class CDialogImpl : public CDialogImplBaseT< TBase >
+{
+public:
+    // + Hacks for gcc
+    using CWindowImplRoot<TBase>::m_thunk;
+    using CWindowImplRoot<TBase>::m_hWnd;
+    // - Hacks for gcc
+
+    HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
+    {
+        BOOL result;
+        HWND hWnd;
+        T* pImpl;
+
+        result = m_thunk.Init(NULL, NULL);
+        if (result == FALSE)
+            return NULL;
+
+        _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
+
+        pImpl = static_cast<T*>(this);
+        hWnd = ::CreateDialogParam(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(pImpl->IDD), hWndParent, T::StartDialogProc, dwInitParam);
+        return hWnd;
+    }
+
+    INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
+    {
+        BOOL result;
+        T* pImpl;
+
+        result = m_thunk.Init(NULL, NULL);
+        if (result == FALSE)
+            return -1;
+
+        _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
+
+        pImpl = static_cast<T*>(this);
+        return ::DialogBoxParam(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(pImpl->IDD), hWndParent, T::StartDialogProc, dwInitParam);
+    }
+
+    BOOL EndDialog(_In_ int nRetCode)
+    {
+        return ::EndDialog(m_hWnd, nRetCode);
+    }
+
+    BOOL DestroyWindow()
+    {
+        return ::DestroyWindow(m_hWnd);
+    }
+};
+
+template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
+class CWindowImplBaseT : public CWindowImplRoot<TBase>
+{
+public:
+    // + Hacks for gcc
+    using CWindowImplRoot<TBase>::WINSTATE_DESTROYED;
+    using CWindowImplRoot<TBase>::m_thunk;
+    // - Hacks for gcc
+
     WNDPROC m_pfnSuperWindowProc;
+
 public:
     CWindowImplBaseT()
     {
-        m_dwState = 0;
-        m_pCurrentMsg = NULL;
         m_pfnSuperWindowProc = ::DefWindowProc;
     }
 
@@ -1436,6 +1618,7 @@ public:
     }
 };
 
+
 template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
 class CWindowImpl : public CWindowImplBaseT<TBase, TWinTraits>
 {
@@ -1630,6 +1813,15 @@ public:
             return TRUE;                                                                        \
     }
 
+#define COMMAND_HANDLER(id, code, func)                                                         \
+    if (uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam))                   \
+    {                                                                                           \
+        bHandled = TRUE;                                                                        \
+        lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled);                 \
+        if (bHandled)                                                                           \
+            return TRUE;                                                                        \
+    }
+
 #define COMMAND_ID_HANDLER(id, func)                                                            \
     if (uMsg == WM_COMMAND && id == LOWORD(wParam))                                                \
     {                                                                                            \
@@ -1639,6 +1831,15 @@ public:
             return TRUE;                                                                        \
     }
 
+#define COMMAND_CODE_HANDLER(code, func)                                                            \
+    if (uMsg == WM_COMMAND && code == HIWORD(wParam))                                                \
+    {                                                                                            \
+        bHandled = TRUE;                                                                        \
+        lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled);                    \
+        if (bHandled)                                                                            \
+            return TRUE;                                                                        \
+    }
+
 #define COMMAND_RANGE_HANDLER(idFirst, idLast, func)                                            \
     if (uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst  && LOWORD(wParam) <= idLast)            \
     {                                                                                            \
@@ -1666,6 +1867,12 @@ public:
             return TRUE;                                                                        \
     }
 
+#define CHAIN_MSG_MAP(theChainClass) \
+    { \
+        if (theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
+            return TRUE; \
+    }
+
 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd)                                        \
 static ATL::CWndClassInfo& GetWndClassInfo()                                                    \
 {                                                                                                \
@@ -1686,16 +1893,27 @@ struct _ATL_WNDCLASSINFOW
     LPCWSTR m_lpszCursorID;
     BOOL m_bSystemCursor;
     ATOM m_atom;
-    WCHAR m_szAutoName[5 + sizeof(void *)];
+    WCHAR m_szAutoName[sizeof("ATL:") + sizeof(void *) * 2]; // == 4 characters + NULL + number of hexadecimal digits describing a pointer.
 
     ATOM Register(WNDPROC *p)
     {
         if (m_wc.hInstance == NULL)
             m_wc.hInstance = _AtlBaseModule.GetModuleInstance();
         if (m_atom == 0)
+        {
+            if (m_bSystemCursor)
+                m_wc.hCursor = ::LoadCursor(NULL, m_lpszCursorID);
+            else
+                m_wc.hCursor = ::LoadCursor(_AtlBaseModule.GetResourceInstance(), m_lpszCursorID);
+
             m_atom = RegisterClassEx(&m_wc);
+        }
+
         return m_atom;
     }
 };
 
 }; // namespace ATL
+
+#pragma pop_macro("SubclassWindow")
+