ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

atlwin.h
Go to the documentation of this file.
00001 /*
00002  * ReactOS ATL
00003  *
00004  * Copyright 2009 Andrew Hill <ash77@reactos.org>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #pragma once
00022 
00023 #ifdef __GNUC__
00024 #define GCCU(x) x __attribute__((unused))
00025 #define Unused(x)
00026 #else
00027 #define GCCU(x) (x) 
00028 #define Unused(x)   (x);
00029 #endif // __GNUC__
00030 
00031 #ifdef SetWindowLongPtr
00032 #undef SetWindowLongPtr
00033 inline LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
00034 {
00035     return SetWindowLong(hWnd, nIndex, (LONG)dwNewLong);
00036 }
00037 #endif
00038 
00039 #ifdef GetWindowLongPtr
00040 #undef GetWindowLongPtr
00041 inline LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex)
00042 {
00043     return (LONG_PTR)GetWindowLong(hWnd, nIndex);
00044 }
00045 #endif
00046 
00047 namespace ATL
00048 {
00049 
00050 struct _ATL_WNDCLASSINFOW;
00051 typedef _ATL_WNDCLASSINFOW CWndClassInfo;
00052 
00053 template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0>
00054 class CWinTraits
00055 {
00056 public:
00057     static DWORD GetWndStyle(DWORD dwStyle)
00058     {
00059         if (dwStyle == 0)
00060             return t_dwStyle;
00061         return dwStyle;
00062     }
00063 
00064     static DWORD GetWndExStyle(DWORD dwExStyle)
00065     {
00066         if (dwExStyle == 0)
00067             return t_dwExStyle;
00068         return dwExStyle;
00069     }
00070 };
00071 
00072 typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0> CControlWinTraits;
00073 typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> CFrameWinTraits;
00074 typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_MDICHILD> CMDIChildWinTraits;
00075 
00076 template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0, class TWinTraits = CControlWinTraits>
00077 class CWinTraitsOR
00078 {
00079 public:
00080     static DWORD GetWndStyle(DWORD dwStyle)
00081     {
00082         return dwStyle | t_dwStyle | TWinTraits::GetWndStyle(dwStyle);
00083     }
00084 
00085     static DWORD GetWndExStyle(DWORD dwExStyle)
00086     {
00087         return dwExStyle | t_dwExStyle | TWinTraits::GetWndExStyle(dwExStyle);
00088     }
00089 };
00090 
00091 class _U_MENUorID
00092 {
00093 public:
00094     HMENU                                   m_hMenu;
00095 public:
00096     _U_MENUorID(HMENU hMenu)
00097     {
00098         m_hMenu = hMenu;
00099     }
00100 
00101     _U_MENUorID(UINT nID)
00102     {
00103         m_hMenu = (HMENU)(UINT_PTR)nID;
00104     }
00105 };
00106 
00107 class _U_RECT
00108 {
00109 public:
00110     LPRECT                                  m_lpRect;
00111 public:
00112     _U_RECT(LPRECT lpRect)
00113     {
00114         m_lpRect = lpRect;
00115     }
00116 
00117     _U_RECT(RECT &rc)
00118     {
00119         m_lpRect = &rc;
00120     }
00121 };
00122 
00123 struct _ATL_MSG : public MSG
00124 {
00125 public:
00126     BOOL                                    bHandled;
00127 public:
00128     _ATL_MSG(HWND hWnd, UINT uMsg, WPARAM wParamIn, LPARAM lParamIn, BOOL bHandledIn = TRUE)
00129     {
00130         hwnd = hWnd;
00131         message = uMsg;
00132         wParam = wParamIn;
00133         lParam = lParamIn;
00134         time = 0;
00135         pt.x = 0;
00136         pt.y = 0;
00137         bHandled = bHandledIn;
00138     }
00139 };
00140 
00141 #if defined(_M_IX86)
00142 
00143 #pragma pack(push,1)
00144 struct thunkCode
00145 {
00146     DWORD                                   m_mov;
00147     DWORD                                   m_this;
00148     BYTE                                    m_jmp;
00149     DWORD                                   m_relproc;
00150 };
00151 #pragma pack(pop)
00152 
00153 class CWndProcThunk
00154 {
00155 public:
00156     thunkCode                               m_thunk;
00157     _AtlCreateWndData                       cd;
00158 public:
00159     BOOL Init(WNDPROC proc, void *pThis)
00160     {
00161         m_thunk.m_mov = 0x042444C7;
00162         m_thunk.m_this = PtrToUlong(pThis);
00163         m_thunk.m_jmp = 0xe9;
00164         m_thunk.m_relproc = DWORD(reinterpret_cast<char *>(proc) - (reinterpret_cast<char *>(this) + sizeof(thunkCode)));
00165         return TRUE;
00166     }
00167 
00168     WNDPROC GetWNDPROC()
00169     {
00170         return reinterpret_cast<WNDPROC>(&m_thunk);
00171     }
00172 };
00173 
00174 #elif _AMD64_ //WARNING: NOT VERIFIED
00175 #pragma pack(push,1)
00176 struct thunkCode
00177 {
00178     DWORD_PTR                               m_mov;
00179     DWORD_PTR                               m_this;
00180     BYTE                                    m_jmp;
00181     DWORD_PTR                               m_relproc;
00182 };
00183 #pragma pack(pop)
00184 
00185 class CWndProcThunk
00186 {
00187 public:
00188     thunkCode                               m_thunk;
00189     _AtlCreateWndData                       cd;
00190 public:
00191     BOOL Init(WNDPROC proc, void *pThis)
00192     {
00193         m_thunk.m_mov = 0xffff8000042444C7LL;
00194         m_thunk.m_this = (DWORD_PTR)pThis;
00195         m_thunk.m_jmp = 0xe9;
00196         m_thunk.m_relproc = DWORD_PTR(reinterpret_cast<char *>(proc) - (reinterpret_cast<char *>(this) + sizeof(thunkCode)));
00197         return TRUE;
00198     }
00199 
00200     WNDPROC GetWNDPROC()
00201     {
00202         return reinterpret_cast<WNDPROC>(&m_thunk);
00203     }
00204 };
00205 #else
00206 #error ARCH not supported
00207 #endif
00208 
00209 class CMessageMap
00210 {
00211 public:
00212     virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID) = 0;
00213 };
00214 
00215 class CWindow
00216 {
00217 public:
00218     HWND                                    m_hWnd;
00219     static RECT                             rcDefault;
00220 public:
00221     CWindow(HWND hWnd = NULL)
00222     {
00223         m_hWnd = hWnd;
00224     }
00225 
00226     operator HWND() const
00227     {
00228         return m_hWnd;
00229     }
00230 
00231     static LPCTSTR GetWndClassName()
00232     {
00233         return NULL;
00234     }
00235 
00236     HDC BeginPaint(LPPAINTSTRUCT lpPaint)
00237     {
00238         ATLASSERT(::IsWindow(m_hWnd));
00239         return ::BeginPaint(m_hWnd, lpPaint);
00240     }
00241 
00242     BOOL DestroyWindow()
00243     {
00244         ATLASSERT(::IsWindow(m_hWnd));
00245 
00246         if (!::DestroyWindow(m_hWnd))
00247             return FALSE;
00248 
00249         m_hWnd = NULL;
00250         return TRUE;
00251     }
00252 
00253     void EndPaint(LPPAINTSTRUCT lpPaint)
00254     {
00255         ATLASSERT(::IsWindow(m_hWnd));
00256         ::EndPaint(m_hWnd, lpPaint);
00257     }
00258 
00259     BOOL GetClientRect(LPRECT lpRect) const
00260     {
00261         ATLASSERT(::IsWindow(m_hWnd));
00262         return ::GetClientRect(m_hWnd, lpRect);
00263     }
00264 
00265     CWindow GetParent() const
00266     {
00267         ATLASSERT(::IsWindow(m_hWnd));
00268         return CWindow(::GetParent(m_hWnd));
00269     }
00270 
00271     BOOL Invalidate(BOOL bErase = TRUE)
00272     {
00273         ATLASSERT(::IsWindow(m_hWnd));
00274         return ::InvalidateRect(m_hWnd, NULL, bErase);
00275     }
00276 
00277     BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE)
00278     {
00279         ATLASSERT(::IsWindow(m_hWnd));
00280         return ::InvalidateRect(m_hWnd, lpRect, bErase);
00281     }
00282 
00283     BOOL IsWindow() const
00284     {
00285         return ::IsWindow(m_hWnd);
00286     }
00287 
00288     BOOL KillTimer(UINT_PTR nIDEvent)
00289     {
00290         ATLASSERT(::IsWindow(m_hWnd));
00291         return ::KillTimer(m_hWnd, nIDEvent);
00292     }
00293 
00294     BOOL LockWindowUpdate(BOOL bLock = TRUE)
00295     {
00296         ATLASSERT(::IsWindow(m_hWnd));
00297         if (bLock)
00298             return ::LockWindowUpdate(m_hWnd);
00299         return ::LockWindowUpdate(NULL);
00300     }
00301 
00302     BOOL ScreenToClient(LPPOINT lpPoint) const
00303     {
00304         ATLASSERT(::IsWindow(m_hWnd));
00305         return ::ScreenToClient(m_hWnd, lpPoint);
00306     }
00307 
00308     LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
00309     {
00310         ATLASSERT(::IsWindow(m_hWnd));
00311         return ::SendMessage(m_hWnd, message, wParam, lParam);
00312     }
00313 
00314     static LRESULT SendMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
00315     {
00316         ATLASSERT(::IsWindow(hWnd));
00317         return ::SendMessage(hWnd, message, wParam, lParam);
00318     }
00319 
00320     HWND SetCapture()
00321     {
00322         ATLASSERT(::IsWindow(m_hWnd));
00323         return ::SetCapture(m_hWnd);
00324     }
00325 
00326     HWND SetFocus()
00327     {
00328         ATLASSERT(::IsWindow(m_hWnd));
00329         return ::SetFocus(m_hWnd);
00330     }
00331 
00332     UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse, void (CALLBACK *lpfnTimer)(HWND, UINT, UINT_PTR, DWORD) = NULL)
00333     {
00334         ATLASSERT(::IsWindow(m_hWnd));
00335         return ::SetTimer(m_hWnd, nIDEvent, nElapse, reinterpret_cast<TIMERPROC>(lpfnTimer));
00336     }
00337 
00338     BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags)
00339     {
00340         ATLASSERT(::IsWindow(m_hWnd));
00341         return ::SetWindowPos(m_hWnd, hWndInsertAfter, x, y, cx, cy, nFlags);
00342     }
00343 
00344     BOOL SetWindowText(LPCTSTR lpszString)
00345     {
00346         ATLASSERT(::IsWindow(m_hWnd));
00347         return ::SetWindowText(m_hWnd, lpszString);
00348     }
00349 
00350     BOOL ShowWindow(int nCmdShow)
00351     {
00352         ATLASSERT(::IsWindow(m_hWnd));
00353         return ::ShowWindow(m_hWnd, nCmdShow);
00354     }
00355 
00356     BOOL UpdateWindow()
00357     {
00358         ATLASSERT(::IsWindow(m_hWnd));
00359         return ::UpdateWindow(m_hWnd);
00360     }
00361 };
00362 
00363 _declspec(selectany) RECT CWindow::rcDefault = { CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 };
00364 
00365 template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
00366 class CWindowImplBaseT : public TBase, public CMessageMap
00367 {
00368 public:
00369     enum { WINSTATE_DESTROYED = 0x00000001 };
00370     DWORD                                   m_dwState;
00371     const _ATL_MSG                          *m_pCurrentMsg;
00372     CWndProcThunk                           m_thunk;
00373     WNDPROC                                 m_pfnSuperWindowProc;
00374 public:
00375     CWindowImplBaseT()
00376     {
00377         m_dwState = 0;
00378         m_pCurrentMsg = NULL;
00379         m_pfnSuperWindowProc = ::DefWindowProc;
00380     }
00381 
00382     virtual void OnFinalMessage(HWND /* hWnd */)
00383     {
00384     }
00385 
00386     BOOL SubclassWindow(HWND hWnd)
00387     {
00388         CWindowImplBaseT<TBase, TWinTraits> *pThis;
00389         WNDPROC                             newWindowProc;
00390         WNDPROC                             oldWindowProc;
00391         BOOL                                result;
00392 
00393         ATLASSERT(m_hWnd == NULL);
00394         ATLASSERT(::IsWindow(hWnd));
00395 
00396         pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this);
00397 
00398         result = m_thunk.Init(GetWindowProc(), this);
00399         if (result == FALSE)
00400             return FALSE;
00401         newWindowProc = m_thunk.GetWNDPROC();
00402         oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
00403         if (oldWindowProc == NULL)
00404             return FALSE;
00405         m_pfnSuperWindowProc = oldWindowProc;
00406         pThis->m_hWnd = hWnd;
00407         return TRUE;
00408     }
00409 
00410     virtual WNDPROC GetWindowProc()
00411     {
00412         return WindowProc;
00413     }
00414 
00415     static DWORD GetWndStyle(DWORD dwStyle)
00416     {
00417         return TWinTraits::GetWndStyle(dwStyle);
00418     }
00419 
00420     static DWORD GetWndExStyle(DWORD dwExStyle)
00421     {
00422         return TWinTraits::GetWndExStyle(dwExStyle);
00423     }
00424 
00425     LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
00426     {
00427         CWindowImplBaseT<TBase, TWinTraits> *pThis;
00428 
00429         pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(this);
00430         return ::CallWindowProc(m_pfnSuperWindowProc, pThis->m_hWnd, uMsg, wParam, lParam);
00431     }
00432 
00433     static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00434     {
00435         CWindowImplBaseT<TBase, TWinTraits> *pThis;
00436         WNDPROC                             newWindowProc;
00437         WNDPROC                             GCCU(pOldProc);
00438 
00439         pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(_AtlWinModule.ExtractCreateWndData());
00440         ATLASSERT(pThis != NULL);
00441         if (pThis == NULL)
00442             return 0;
00443         pThis->m_thunk.Init(pThis->GetWindowProc(), pThis);
00444         newWindowProc = pThis->m_thunk.GetWNDPROC();
00445         pOldProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
00446         Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
00447         pThis->m_hWnd = hWnd;
00448         return newWindowProc(hWnd, uMsg, wParam, lParam);
00449     }
00450 
00451     static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00452     {
00453         CWindowImplBaseT<TBase, TWinTraits> *pThis = reinterpret_cast<CWindowImplBaseT< TBase, TWinTraits> *>(hWnd);
00454         _ATL_MSG                            msg(pThis->m_hWnd, uMsg, wParam, lParam);
00455         LRESULT                             lResult;
00456         const _ATL_MSG                      *previousMessage;
00457         BOOL                                handled;
00458         LONG_PTR                            saveWindowProc;
00459 
00460         ATLASSERT(pThis != NULL && (pThis->m_dwState & WINSTATE_DESTROYED) == 0 && pThis->m_hWnd != NULL);
00461         if (pThis == NULL || (pThis->m_dwState & WINSTATE_DESTROYED) != 0 || pThis->m_hWnd == NULL)
00462             return 0;
00463 
00464         hWnd = pThis->m_hWnd;
00465         previousMessage = pThis->m_pCurrentMsg;
00466         pThis->m_pCurrentMsg = &msg;
00467 
00468         handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
00469         ATLASSERT(pThis->m_pCurrentMsg == &msg);
00470 
00471         if (handled == FALSE)
00472         {
00473             if (uMsg == WM_NCDESTROY)
00474             {
00475                 saveWindowProc = ::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
00476                 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
00477                 if (pThis->m_pfnSuperWindowProc != ::DefWindowProc && saveWindowProc == ::GetWindowLongPtr(hWnd, GWLP_WNDPROC))
00478                     ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pThis->m_pfnSuperWindowProc));
00479                 pThis->m_dwState |= WINSTATE_DESTROYED;
00480             }
00481             else
00482                 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
00483         }
00484         ATLASSERT(pThis->m_pCurrentMsg == &msg);
00485         pThis->m_pCurrentMsg = previousMessage;
00486         if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
00487         {
00488             pThis->m_dwState &= ~WINSTATE_DESTROYED;
00489             pThis->m_hWnd = NULL;
00490             pThis->OnFinalMessage(hWnd);
00491         }
00492         return lResult;
00493     }
00494 
00495     HWND Create(HWND hWndParent, _U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle,
00496                     _U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam)
00497     {
00498         HWND                                hWnd;
00499 
00500         ATLASSERT(m_hWnd == NULL);
00501         ATLASSERT(atom != 0);
00502         if (atom == 0)
00503             return NULL;
00504         if (m_thunk.Init(NULL, NULL) == FALSE)
00505         {
00506             SetLastError(ERROR_OUTOFMEMORY);
00507             return NULL;
00508         }
00509 
00510         _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
00511         if (MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD) != 0)
00512             MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this;
00513         if (rect.m_lpRect == NULL)
00514             rect.m_lpRect = &TBase::rcDefault;
00515         hWnd = ::CreateWindowEx(dwExStyle, reinterpret_cast<LPCWSTR>(MAKEINTATOM(atom)), szWindowName, dwStyle, rect.m_lpRect->left,
00516                     rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left, rect.m_lpRect->bottom - rect.m_lpRect->top,
00517                     hWndParent, MenuOrID.m_hMenu, _AtlBaseModule.GetModuleInstance(), lpCreateParam);
00518 
00519         ATLASSERT(m_hWnd == hWnd);
00520 
00521         return hWnd;
00522     }
00523 };
00524 
00525 template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
00526 class CWindowImpl : public CWindowImplBaseT<TBase, TWinTraits>
00527 {
00528 public:
00529     static LPCTSTR GetWndCaption()
00530     {
00531         return NULL;
00532     }
00533 
00534     HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0,
00535                     DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
00536     {
00537         CWindowImplBaseT<TBase, TWinTraits> *pThis;
00538         ATOM                                atom;
00539 
00540         ATLASSERT(m_hWnd == NULL);
00541         pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this);
00542 
00543         if (T::GetWndClassInfo().m_lpszOrigName == NULL)
00544             T::GetWndClassInfo().m_lpszOrigName = pThis->GetWndClassName();
00545         atom = T::GetWndClassInfo().Register(&pThis->m_pfnSuperWindowProc);
00546 
00547         if (szWindowName == NULL)
00548             szWindowName = T::GetWndCaption();
00549         dwStyle = T::GetWndStyle(dwStyle);
00550         dwExStyle = T::GetWndExStyle(dwExStyle);
00551 
00552         return CWindowImplBaseT<TBase, TWinTraits>::Create(hWndParent, rect, szWindowName, dwStyle,
00553                         dwExStyle, MenuOrID, atom, lpCreateParam);
00554     }
00555 };
00556 
00557 template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
00558 class CContainedWindowT : public TBase
00559 {
00560 public:
00561     CWndProcThunk                           m_thunk;
00562     LPCTSTR                                 m_lpszClassName;
00563     WNDPROC                                 m_pfnSuperWindowProc;
00564     CMessageMap                             *m_pObject;
00565     DWORD                                   m_dwMsgMapID;
00566     const _ATL_MSG                          *m_pCurrentMsg;
00567 public:
00568     CContainedWindowT(CMessageMap *pObject, DWORD dwMsgMapID = 0)
00569     {
00570         m_lpszClassName = TBase::GetWndClassName();
00571         m_pfnSuperWindowProc = ::DefWindowProc;
00572         m_pObject = pObject;
00573         m_dwMsgMapID = dwMsgMapID;
00574         m_pCurrentMsg = NULL;
00575     }
00576 
00577     CContainedWindowT(LPTSTR lpszClassName, CMessageMap *pObject, DWORD dwMsgMapID = 0)
00578     {
00579         m_lpszClassName = lpszClassName;
00580         m_pfnSuperWindowProc = ::DefWindowProc;
00581         m_pObject = pObject;
00582         m_dwMsgMapID = dwMsgMapID;
00583         m_pCurrentMsg = NULL;
00584     }
00585 
00586     LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
00587     {
00588         CWindowImplBaseT<TBase, TWinTraits> *pThis;
00589 
00590         pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(this);
00591         return ::CallWindowProc(m_pfnSuperWindowProc, pThis->m_hWnd, uMsg, wParam, lParam);
00592     }
00593 
00594     BOOL SubclassWindow(HWND hWnd)
00595     {
00596         CContainedWindowT<TBase>            *pThis;
00597         WNDPROC                             newWindowProc;
00598         WNDPROC                             oldWindowProc;
00599         BOOL                                result;
00600 
00601         ATLASSERT(m_hWnd == NULL);
00602         ATLASSERT(::IsWindow(hWnd));
00603 
00604         pThis = reinterpret_cast<CContainedWindowT<TBase> *>(this);
00605 
00606         result = m_thunk.Init(WindowProc, pThis);
00607         if (result == FALSE)
00608             return FALSE;
00609         newWindowProc = m_thunk.GetWNDPROC();
00610         oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
00611         if (oldWindowProc == NULL)
00612             return FALSE;
00613         m_pfnSuperWindowProc = oldWindowProc;
00614         pThis->m_hWnd = hWnd;
00615         return TRUE;
00616     }
00617 
00618     static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00619     {
00620         CContainedWindowT<TBase>            *pThis;
00621         WNDPROC                             newWindowProc;
00622         WNDPROC                             GCCU(pOldProc);
00623 
00624         pThis = reinterpret_cast<CContainedWindowT<TBase> *>(_AtlWinModule.ExtractCreateWndData());
00625         ATLASSERT(pThis != NULL);
00626         if (pThis == NULL)
00627             return 0;
00628         pThis->m_thunk.Init(WindowProc, pThis);
00629         newWindowProc = pThis->m_thunk.GetWNDPROC();
00630         pOldProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
00631         Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
00632         pThis->m_hWnd = hWnd;
00633         return newWindowProc(hWnd, uMsg, wParam, lParam);
00634     }
00635 
00636     static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00637     {
00638         CContainedWindowT<TBase>            *pThis = reinterpret_cast<CContainedWindowT<TBase> *>(hWnd);
00639         _ATL_MSG                            msg(pThis->m_hWnd, uMsg, wParam, lParam);
00640         LRESULT                             lResult;
00641         const _ATL_MSG                      *previousMessage;
00642         BOOL                                handled;
00643         LONG_PTR                            saveWindowProc;
00644 
00645         ATLASSERT(pThis != NULL && pThis->m_hWnd != NULL && pThis->m_pObject != NULL);
00646         if (pThis == NULL || pThis->m_hWnd == NULL || pThis->m_pObject == NULL)
00647             return 0;
00648 
00649         hWnd = pThis->m_hWnd;
00650         previousMessage = pThis->m_pCurrentMsg;
00651         pThis->m_pCurrentMsg = &msg;
00652 
00653         handled = pThis->m_pObject->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, pThis->m_dwMsgMapID);
00654         ATLASSERT(pThis->m_pCurrentMsg == &msg);
00655 
00656         pThis->m_pCurrentMsg = previousMessage;
00657         if (handled == FALSE)
00658         {
00659             if (uMsg == WM_NCDESTROY)
00660             {
00661                 saveWindowProc = ::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
00662                 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
00663                 if (pThis->m_pfnSuperWindowProc != ::DefWindowProc && saveWindowProc == ::GetWindowLongPtr(hWnd, GWLP_WNDPROC))
00664                     ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pThis->m_pfnSuperWindowProc));
00665                 pThis->m_hWnd = NULL;
00666             }
00667             else
00668                 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
00669         }
00670         return lResult;
00671     }
00672 
00673 };
00674 typedef CContainedWindowT<CWindow>  CContainedWindow;
00675 
00676 #define BEGIN_MSG_MAP(theClass)                                                                                             \
00677 public:                                                                                                                     \
00678     BOOL ProcessWindowMessage(HWND GCCU(hWnd), UINT GCCU(uMsg), WPARAM GCCU(wParam), LPARAM GCCU(lParam), LRESULT &GCCU(lResult), DWORD dwMsgMapID = 0) \
00679     {                                                                                                                       \
00680         BOOL GCCU(bHandled) = TRUE;                                                                                         \
00681         Unused(hWnd);                                                                                                       \
00682         Unused(uMsg);                                                                                                       \
00683         Unused(wParam);                                                                                                     \
00684         Unused(lParam);                                                                                                     \
00685         Unused(lResult);                                                                                                    \
00686         Unused(bHandled);                                                                                                   \
00687         switch(dwMsgMapID)                                                                                                  \
00688         {                                                                                                                   \
00689         case 0:
00690 
00691 #define END_MSG_MAP()                                                                           \
00692             break;                                                                              \
00693         default:                                                                                \
00694             ATLASSERT(FALSE);                                                                   \
00695             break;                                                                              \
00696         }                                                                                       \
00697         return FALSE;                                                                           \
00698     }
00699 
00700 #define MESSAGE_HANDLER(msg, func)                                                              \
00701     if (uMsg == msg)                                                                            \
00702     {                                                                                           \
00703         bHandled = TRUE;                                                                        \
00704         lResult = func(uMsg, wParam, lParam, bHandled);                                         \
00705         if (bHandled)                                                                           \
00706             return TRUE;                                                                        \
00707     }
00708 
00709 #define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func)                                          \
00710     if (uMsg >= msgFirst && uMsg <= msgLast)                                                    \
00711     {                                                                                           \
00712         bHandled = TRUE;                                                                        \
00713         lResult = func(uMsg, wParam, lParam, bHandled);                                         \
00714         if (bHandled)                                                                           \
00715             return TRUE;                                                                        \
00716     }
00717 
00718 #define COMMAND_ID_HANDLER(id, func)                                                            \
00719     if (uMsg == WM_COMMAND && id == LOWORD(wParam))                                             \
00720     {                                                                                           \
00721         bHandled = TRUE;                                                                        \
00722         lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled);                 \
00723         if (bHandled)                                                                           \
00724             return TRUE;                                                                        \
00725     }
00726 
00727 #define COMMAND_RANGE_HANDLER(idFirst, idLast, func)                                            \
00728     if (uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst  && LOWORD(wParam) <= idLast)           \
00729     {                                                                                           \
00730         bHandled = TRUE;                                                                        \
00731         lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled);                 \
00732         if (bHandled)                                                                           \
00733             return TRUE;                                                                        \
00734     }
00735 
00736 #define NOTIFY_CODE_HANDLER(cd, func)                                                           \
00737     if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code)                                      \
00738     {                                                                                           \
00739         bHandled = TRUE;                                                                        \
00740         lResult = func((int)wParam, (LPNMHDR)lParam, bHandled);                                 \
00741         if (bHandled)                                                                           \
00742             return TRUE;                                                                        \
00743     }
00744 
00745 #define NOTIFY_HANDLER(id, cd, func)                                                            \
00746     if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code)   \
00747     {                                                                                           \
00748         bHandled = TRUE;                                                                        \
00749         lResult = func((int)wParam, (LPNMHDR)lParam, bHandled);                                 \
00750         if (bHandled)                                                                           \
00751             return TRUE;                                                                        \
00752     }
00753 
00754 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd)                                        \
00755 static ATL::CWndClassInfo& GetWndClassInfo()                                                    \
00756 {                                                                                               \
00757     static ATL::CWndClassInfo wc =                                                              \
00758     {                                                                                           \
00759         { sizeof(WNDCLASSEX), style, StartWindowProc,                                           \
00760           0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL },              \
00761         NULL, NULL, IDC_ARROW, TRUE, 0, _T("")                                                  \
00762     };                                                                                          \
00763     return wc;                                                                                  \
00764 }
00765 
00766 struct _ATL_WNDCLASSINFOW
00767 {
00768     WNDCLASSEXW                             m_wc;
00769     LPCWSTR                                 m_lpszOrigName;
00770     WNDPROC                                 pWndProc;
00771     LPCWSTR                                 m_lpszCursorID;
00772     BOOL                                    m_bSystemCursor;
00773     ATOM                                    m_atom;
00774     WCHAR                                   m_szAutoName[5 + sizeof(void *)];
00775 
00776     ATOM Register(WNDPROC *p)
00777     {
00778         if (m_wc.hInstance == NULL)
00779             m_wc.hInstance = _AtlBaseModule.GetModuleInstance();
00780         if (m_atom == 0)
00781             m_atom = RegisterClassEx(&m_wc);
00782         return m_atom;
00783     }
00784 };
00785 
00786 }; // namespace ATL

Generated on Sat May 26 2012 04:21:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.