Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenatlwin.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
1.7.6.1
|