Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1403 lines
44 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLWIN_H__
  11. #define __ATLWIN_H__
  12. #ifndef __cplusplus
  13. #error ATL requires C++ compilation (use a .cpp suffix)
  14. #endif
  15. #ifndef __ATLBASE_H__
  16. #error atlwin.h requires atlbase.h to be included first
  17. #endif
  18. #ifndef WS_EX_NOINHERITLAYOUT
  19. #define WS_EX_NOINHERITLAYOUT 0x00100000L // Disable inheritence of mirroring by children
  20. #endif
  21. #ifndef WS_EX_LAYOUTRTL
  22. #define WS_EX_LAYOUTRTL 0x00400000L // Right to left mirroring
  23. #endif
  24. #ifndef NOMIRRORBITMAP
  25. #define NOMIRRORBITMAP (DWORD)0x80000000 // Do not Mirror the bitmap in this call
  26. #endif
  27. #ifndef LAYOUT_RTL
  28. #define LAYOUT_RTL 0x00000001 // Right to left
  29. #endif
  30. #ifndef LAYOUT_BTT
  31. #define LAYOUT_BTT 0x00000002 // Bottom to top
  32. #endif
  33. #ifndef LAYOUT_VBH
  34. #define LAYOUT_VBH 0x00000004 // Vertical before horizontal
  35. #endif
  36. #ifndef LAYOUT_ORIENTATIONMASK
  37. #define LAYOUT_ORIENTATIONMASK LAYOUT_RTL | LAYOUT_BTT | LAYOUT_VBH
  38. #endif
  39. #ifndef LAYOUT_BITMAPORIENTATIONPRESERVED
  40. #define LAYOUT_BITMAPORIENTATIONPRESERVED 0x00000008
  41. #endif
  42. #ifdef SubclassWindow
  43. #pragma push_macro( "SubclassWindow" )
  44. #define _ATL_REDEF_SUBCLASSWINDOW
  45. #undef SubclassWindow
  46. #endif
  47. #ifndef ATL_NO_NAMESPACE
  48. namespace ATL
  49. {
  50. #endif
  51. /////////////////////////////////////////////////////////////////////////////
  52. // Forward declarations
  53. class CWindow;
  54. class CMessageMap;
  55. class CDynamicChain;
  56. class CWndClassInfo;
  57. template <class T> class CWindowImpl;
  58. template <class T> class CDialogImpl;
  59. class CContainedWindow;
  60. /////////////////////////////////////////////////////////////////////////////
  61. // CWindow - client side for a Windows window
  62. class CWindow
  63. {
  64. public:
  65. HWND m_hWnd;
  66. CWindow(HWND hWnd = NULL)
  67. {
  68. m_hWnd = hWnd;
  69. }
  70. CWindow& operator=(HWND hWnd)
  71. {
  72. m_hWnd = hWnd;
  73. return *this;
  74. }
  75. void Attach(HWND hWndNew)
  76. {
  77. _ASSERTE(::IsWindow(hWndNew));
  78. m_hWnd = hWndNew;
  79. }
  80. HWND Detach()
  81. {
  82. HWND hWnd = m_hWnd;
  83. m_hWnd = NULL;
  84. return hWnd;
  85. }
  86. BOOL DestroyWindow()
  87. {
  88. _ASSERTE(::IsWindow(m_hWnd));
  89. if(!::DestroyWindow(m_hWnd))
  90. return FALSE;
  91. m_hWnd = NULL;
  92. return TRUE;
  93. }
  94. // Attributes
  95. operator HWND() const { return m_hWnd; }
  96. DWORD GetStyle() const
  97. {
  98. _ASSERTE(::IsWindow(m_hWnd));
  99. return (DWORD)::GetWindowLong(m_hWnd, GWL_STYLE);
  100. }
  101. DWORD GetExStyle() const
  102. {
  103. _ASSERTE(::IsWindow(m_hWnd));
  104. return (DWORD)::GetWindowLong(m_hWnd, GWL_EXSTYLE);
  105. }
  106. BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0);
  107. BOOL ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0);
  108. LONG GetWindowLong(int nIndex) const
  109. {
  110. _ASSERTE(::IsWindow(m_hWnd));
  111. return ::GetWindowLong(m_hWnd, nIndex);
  112. }
  113. LONG SetWindowLong(int nIndex, LONG dwNewLong)
  114. {
  115. _ASSERTE(::IsWindow(m_hWnd));
  116. return ::SetWindowLong(m_hWnd, nIndex, dwNewLong);
  117. }
  118. WORD GetWindowWord(int nIndex) const
  119. {
  120. _ASSERTE(::IsWindow(m_hWnd));
  121. return ::GetWindowWord(m_hWnd, nIndex);
  122. }
  123. WORD SetWindowWord(int nIndex, WORD wNewWord)
  124. {
  125. _ASSERTE(::IsWindow(m_hWnd));
  126. return ::SetWindowWord(m_hWnd, nIndex, wNewWord);
  127. }
  128. // Message Functions
  129. LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  130. {
  131. _ASSERTE(::IsWindow(m_hWnd));
  132. return ::SendMessage(m_hWnd,message,wParam,lParam);
  133. }
  134. BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  135. {
  136. _ASSERTE(::IsWindow(m_hWnd));
  137. return ::PostMessage(m_hWnd,message,wParam,lParam);
  138. }
  139. BOOL SendNotifyMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  140. {
  141. _ASSERTE(::IsWindow(m_hWnd));
  142. return ::SendNotifyMessage(m_hWnd, message, wParam, lParam);
  143. }
  144. // Window Text Functions
  145. BOOL SetWindowText(LPCTSTR lpszString)
  146. {
  147. _ASSERTE(::IsWindow(m_hWnd));
  148. return ::SetWindowText(m_hWnd, lpszString);
  149. }
  150. int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount) const
  151. {
  152. _ASSERTE(::IsWindow(m_hWnd));
  153. return ::GetWindowText(m_hWnd, lpszStringBuf, nMaxCount);
  154. }
  155. int GetWindowTextLength() const
  156. {
  157. _ASSERTE(::IsWindow(m_hWnd));
  158. return ::GetWindowTextLength(m_hWnd);
  159. }
  160. BOOL GetWindowText(BSTR& bstrText);
  161. // Font Functions
  162. void SetFont(HFONT hFont, BOOL bRedraw = TRUE)
  163. {
  164. _ASSERTE(::IsWindow(m_hWnd));
  165. ::SendMessage(m_hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(bRedraw, 0));
  166. }
  167. HFONT GetFont() const
  168. {
  169. _ASSERTE(::IsWindow(m_hWnd));
  170. return (HFONT)::SendMessage(m_hWnd, WM_GETFONT, 0, 0);
  171. }
  172. // Menu Functions (non-child windows only)
  173. #if defined(_WINUSER_) && !defined(NOMENUS)
  174. HMENU GetMenu() const
  175. {
  176. _ASSERTE(::IsWindow(m_hWnd));
  177. return ::GetMenu(m_hWnd);
  178. }
  179. BOOL SetMenu(HMENU hMenu)
  180. {
  181. _ASSERTE(::IsWindow(m_hWnd));
  182. return ::SetMenu(m_hWnd, hMenu);
  183. }
  184. BOOL DrawMenuBar()
  185. {
  186. _ASSERTE(::IsWindow(m_hWnd));
  187. return ::DrawMenuBar(m_hWnd);
  188. }
  189. HMENU GetSystemMenu(BOOL bRevert) const
  190. {
  191. _ASSERTE(::IsWindow(m_hWnd));
  192. return ::GetSystemMenu(m_hWnd, bRevert);
  193. }
  194. BOOL HiliteMenuItem(HMENU hMenu, UINT uItemHilite, UINT uHilite)
  195. {
  196. _ASSERTE(::IsWindow(m_hWnd));
  197. return ::HiliteMenuItem(m_hWnd, hMenu, uItemHilite, uHilite);
  198. }
  199. #endif
  200. // Window Size and Position Functions
  201. BOOL IsIconic() const
  202. {
  203. _ASSERTE(::IsWindow(m_hWnd));
  204. return ::IsIconic(m_hWnd);
  205. }
  206. BOOL IsZoomed() const
  207. {
  208. _ASSERTE(::IsWindow(m_hWnd));
  209. return ::IsZoomed(m_hWnd);
  210. }
  211. BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE)
  212. {
  213. _ASSERTE(::IsWindow(m_hWnd));
  214. return ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
  215. }
  216. BOOL MoveWindow(LPCRECT lpRect, BOOL bRepaint = TRUE)
  217. {
  218. _ASSERTE(::IsWindow(m_hWnd));
  219. return ::MoveWindow(m_hWnd, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, bRepaint);
  220. }
  221. BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags)
  222. {
  223. _ASSERTE(::IsWindow(m_hWnd));
  224. return ::SetWindowPos(m_hWnd, hWndInsertAfter, x, y, cx, cy, nFlags);
  225. }
  226. BOOL SetWindowPos(HWND hWndInsertAfter, LPCRECT lpRect, UINT nFlags)
  227. {
  228. _ASSERTE(::IsWindow(m_hWnd));
  229. return ::SetWindowPos(m_hWnd, hWndInsertAfter, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, nFlags);
  230. }
  231. #if defined(_WINUSER_) && !defined(NOMDI)
  232. UINT ArrangeIconicWindows()
  233. {
  234. _ASSERTE(::IsWindow(m_hWnd));
  235. return ::ArrangeIconicWindows(m_hWnd);
  236. }
  237. #endif
  238. BOOL BringWindowToTop()
  239. {
  240. _ASSERTE(::IsWindow(m_hWnd));
  241. return ::BringWindowToTop(m_hWnd);
  242. }
  243. BOOL GetWindowRect(LPRECT lpRect) const
  244. {
  245. _ASSERTE(::IsWindow(m_hWnd));
  246. return ::GetWindowRect(m_hWnd, lpRect);
  247. }
  248. BOOL GetClientRect(LPRECT lpRect) const
  249. {
  250. _ASSERTE(::IsWindow(m_hWnd));
  251. return ::GetClientRect(m_hWnd, lpRect);
  252. }
  253. BOOL GetWindowPlacement(WINDOWPLACEMENT FAR* lpwndpl) const
  254. {
  255. _ASSERTE(::IsWindow(m_hWnd));
  256. return ::GetWindowPlacement(m_hWnd, lpwndpl);
  257. }
  258. BOOL SetWindowPlacement(const WINDOWPLACEMENT FAR* lpwndpl)
  259. {
  260. _ASSERTE(::IsWindow(m_hWnd));
  261. return ::SetWindowPlacement(m_hWnd, lpwndpl);
  262. }
  263. // Coordinate Mapping Functions
  264. BOOL ClientToScreen(LPPOINT lpPoint) const
  265. {
  266. _ASSERTE(::IsWindow(m_hWnd));
  267. return ::ClientToScreen(m_hWnd, lpPoint);
  268. }
  269. BOOL ClientToScreen(LPRECT lpRect) const
  270. {
  271. _ASSERTE(::IsWindow(m_hWnd));
  272. if(!::ClientToScreen(m_hWnd, (LPPOINT)lpRect))
  273. return FALSE;
  274. if(!::ClientToScreen(m_hWnd, ((LPPOINT)lpRect)+1))
  275. return FALSE;
  276. if (GetExStyle() & WS_EX_LAYOUTRTL) {
  277. // Swap left and right
  278. LONG temp = lpRect->left;
  279. lpRect->left = lpRect->right;
  280. lpRect->right = temp;
  281. }
  282. return TRUE;
  283. }
  284. BOOL ScreenToClient(LPPOINT lpPoint) const
  285. {
  286. _ASSERTE(::IsWindow(m_hWnd));
  287. return ::ScreenToClient(m_hWnd, lpPoint);
  288. }
  289. BOOL ScreenToClient(LPRECT lpRect) const
  290. {
  291. _ASSERTE(::IsWindow(m_hWnd));
  292. if(!::ScreenToClient(m_hWnd, (LPPOINT)lpRect))
  293. return FALSE;
  294. if(!::ScreenToClient(m_hWnd, ((LPPOINT)lpRect)+1))
  295. return FALSE;
  296. if (GetExStyle() & WS_EX_LAYOUTRTL) {
  297. // Swap left and right
  298. LONG temp = lpRect->left;
  299. lpRect->left = lpRect->right;
  300. lpRect->right = temp;
  301. }
  302. return TRUE;
  303. }
  304. int MapWindowPoints(HWND hWndTo, LPPOINT lpPoint, UINT nCount) const
  305. {
  306. _ASSERTE(::IsWindow(m_hWnd));
  307. return ::MapWindowPoints(m_hWnd, hWndTo, lpPoint, nCount);
  308. }
  309. int MapWindowPoints(HWND hWndTo, LPRECT lpRect) const
  310. {
  311. _ASSERTE(::IsWindow(m_hWnd));
  312. return ::MapWindowPoints(m_hWnd, hWndTo, (LPPOINT)lpRect, 2);
  313. }
  314. // Update and Painting Functions
  315. HDC BeginPaint(LPPAINTSTRUCT lpPaint)
  316. {
  317. _ASSERTE(::IsWindow(m_hWnd));
  318. return ::BeginPaint(m_hWnd, lpPaint);
  319. }
  320. void EndPaint(LPPAINTSTRUCT lpPaint)
  321. {
  322. _ASSERTE(::IsWindow(m_hWnd));
  323. ::EndPaint(m_hWnd, lpPaint);
  324. }
  325. HDC GetDC()
  326. {
  327. _ASSERTE(::IsWindow(m_hWnd));
  328. return ::GetDC(m_hWnd);
  329. }
  330. HDC GetWindowDC()
  331. {
  332. _ASSERTE(::IsWindow(m_hWnd));
  333. return ::GetWindowDC(m_hWnd);
  334. }
  335. int ReleaseDC(HDC hDC)
  336. {
  337. _ASSERTE(::IsWindow(m_hWnd));
  338. return ::ReleaseDC(m_hWnd, hDC);
  339. }
  340. void Print(HDC hDC, DWORD dwFlags) const
  341. {
  342. _ASSERTE(::IsWindow(m_hWnd));
  343. ::SendMessage(m_hWnd, WM_PRINT, (WPARAM)hDC, dwFlags);
  344. }
  345. void PrintClient(HDC hDC, DWORD dwFlags) const
  346. {
  347. _ASSERTE(::IsWindow(m_hWnd));
  348. ::SendMessage(m_hWnd, WM_PRINTCLIENT, (WPARAM)hDC, dwFlags);
  349. }
  350. BOOL UpdateWindow()
  351. {
  352. _ASSERTE(::IsWindow(m_hWnd));
  353. return ::UpdateWindow(m_hWnd);
  354. }
  355. void SetRedraw(BOOL bRedraw = TRUE)
  356. {
  357. _ASSERTE(::IsWindow(m_hWnd));
  358. ::SendMessage(m_hWnd, WM_SETREDRAW, (WPARAM)bRedraw, 0);
  359. }
  360. BOOL GetUpdateRect(LPRECT lpRect, BOOL bErase = FALSE)
  361. {
  362. _ASSERTE(::IsWindow(m_hWnd));
  363. return ::GetUpdateRect(m_hWnd, lpRect, bErase);
  364. }
  365. int GetUpdateRgn(HRGN hRgn, BOOL bErase = FALSE)
  366. {
  367. _ASSERTE(::IsWindow(m_hWnd));
  368. return ::GetUpdateRgn(m_hWnd, hRgn, bErase);
  369. }
  370. BOOL Invalidate(BOOL bErase = TRUE)
  371. {
  372. _ASSERTE(::IsWindow(m_hWnd));
  373. return ::InvalidateRect(m_hWnd, NULL, bErase);
  374. }
  375. BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE)
  376. {
  377. _ASSERTE(::IsWindow(m_hWnd));
  378. return ::InvalidateRect(m_hWnd, lpRect, bErase);
  379. }
  380. void InvalidateRgn(HRGN hRgn, BOOL bErase = TRUE)
  381. {
  382. _ASSERTE(::IsWindow(m_hWnd));
  383. ::InvalidateRgn(m_hWnd, hRgn, bErase);
  384. }
  385. BOOL ValidateRect(LPCRECT lpRect)
  386. {
  387. _ASSERTE(::IsWindow(m_hWnd));
  388. return ::ValidateRect(m_hWnd, lpRect);
  389. }
  390. BOOL ValidateRgn(HRGN hRgn)
  391. {
  392. _ASSERTE(::IsWindow(m_hWnd));
  393. return ::ValidateRgn(m_hWnd, hRgn);
  394. }
  395. BOOL ShowWindow(int nCmdShow)
  396. {
  397. _ASSERTE(::IsWindow(m_hWnd));
  398. return ::ShowWindow(m_hWnd, nCmdShow);
  399. }
  400. BOOL IsWindowVisible() const
  401. {
  402. _ASSERTE(::IsWindow(m_hWnd));
  403. return ::IsWindowVisible(m_hWnd);
  404. }
  405. BOOL ShowOwnedPopups(BOOL bShow = TRUE)
  406. {
  407. _ASSERTE(::IsWindow(m_hWnd));
  408. return ::ShowOwnedPopups(m_hWnd, bShow);
  409. }
  410. HDC GetDCEx(HRGN hRgnClip, DWORD flags)
  411. {
  412. _ASSERTE(::IsWindow(m_hWnd));
  413. return ::GetDCEx(m_hWnd, hRgnClip, flags);
  414. }
  415. BOOL LockWindowUpdate(BOOL bLock = TRUE)
  416. {
  417. _ASSERTE(::IsWindow(m_hWnd));
  418. return ::LockWindowUpdate(bLock ? m_hWnd : NULL);
  419. }
  420. BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL, HRGN hRgnUpdate = NULL, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE)
  421. {
  422. _ASSERTE(::IsWindow(m_hWnd));
  423. return ::RedrawWindow(m_hWnd, lpRectUpdate, hRgnUpdate, flags);
  424. }
  425. // Timer Functions
  426. UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse, void (CALLBACK* lpfnTimer)(HWND, UINT, UINT_PTR, DWORD))
  427. {
  428. _ASSERTE(::IsWindow(m_hWnd));
  429. return ::SetTimer(m_hWnd, nIDEvent, nElapse, (TIMERPROC)lpfnTimer);
  430. }
  431. BOOL KillTimer(UINT_PTR nIDEvent)
  432. {
  433. _ASSERTE(::IsWindow(m_hWnd));
  434. return ::KillTimer(m_hWnd, nIDEvent);
  435. }
  436. // Window State Functions
  437. BOOL IsWindowEnabled() const
  438. {
  439. _ASSERTE(::IsWindow(m_hWnd));
  440. return ::IsWindowEnabled(m_hWnd);
  441. }
  442. BOOL EnableWindow(BOOL bEnable = TRUE)
  443. {
  444. _ASSERTE(::IsWindow(m_hWnd));
  445. return ::EnableWindow(m_hWnd, bEnable);
  446. }
  447. HWND SetActiveWindow()
  448. {
  449. _ASSERTE(::IsWindow(m_hWnd));
  450. return ::SetActiveWindow(m_hWnd);
  451. }
  452. HWND SetCapture()
  453. {
  454. _ASSERTE(::IsWindow(m_hWnd));
  455. return ::SetCapture(m_hWnd);
  456. }
  457. HWND SetFocus()
  458. {
  459. _ASSERTE(::IsWindow(m_hWnd));
  460. return ::SetFocus(m_hWnd);
  461. }
  462. // Dialog-Box Item Functions
  463. BOOL CheckDlgButton(int nIDButton, UINT nCheck)
  464. {
  465. _ASSERTE(::IsWindow(m_hWnd));
  466. return ::CheckDlgButton(m_hWnd, nIDButton, nCheck);
  467. }
  468. BOOL CheckRadioButton(int nIDFirstButton, int nIDLastButton, int nIDCheckButton)
  469. {
  470. _ASSERTE(::IsWindow(m_hWnd));
  471. return ::CheckRadioButton(m_hWnd, nIDFirstButton, nIDLastButton, nIDCheckButton);
  472. }
  473. int DlgDirList(LPTSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT nFileType)
  474. {
  475. _ASSERTE(::IsWindow(m_hWnd));
  476. return ::DlgDirList(m_hWnd, lpPathSpec, nIDListBox, nIDStaticPath, nFileType);
  477. }
  478. int DlgDirListComboBox(LPTSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT nFileType)
  479. {
  480. _ASSERTE(::IsWindow(m_hWnd));
  481. return ::DlgDirListComboBox(m_hWnd, lpPathSpec, nIDComboBox, nIDStaticPath, nFileType);
  482. }
  483. BOOL DlgDirSelect(LPTSTR lpString, int nCount, int nIDListBox)
  484. {
  485. _ASSERTE(::IsWindow(m_hWnd));
  486. return ::DlgDirSelectEx(m_hWnd, lpString, nCount, nIDListBox);
  487. }
  488. BOOL DlgDirSelectComboBox(LPTSTR lpString, int nCount, int nIDComboBox)
  489. {
  490. _ASSERTE(::IsWindow(m_hWnd));
  491. return ::DlgDirSelectComboBoxEx(m_hWnd, lpString, nCount, nIDComboBox);
  492. }
  493. UINT GetDlgItemInt(int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE) const
  494. {
  495. _ASSERTE(::IsWindow(m_hWnd));
  496. return ::GetDlgItemInt(m_hWnd, nID, lpTrans, bSigned);
  497. }
  498. UINT GetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount) const
  499. {
  500. _ASSERTE(::IsWindow(m_hWnd));
  501. return ::GetDlgItemText(m_hWnd, nID, lpStr, nMaxCount);
  502. }
  503. BOOL GetDlgItemText(int nID, BSTR& bstrText) const
  504. {
  505. _ASSERTE(::IsWindow(m_hWnd));
  506. HWND hWndCtl = GetDlgItem(nID);
  507. if(hWndCtl == NULL)
  508. return FALSE;
  509. return CWindow(hWndCtl).GetWindowText(bstrText);
  510. }
  511. HWND GetNextDlgGroupItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
  512. {
  513. _ASSERTE(::IsWindow(m_hWnd));
  514. return ::GetNextDlgGroupItem(m_hWnd, hWndCtl, bPrevious);
  515. }
  516. HWND GetNextDlgTabItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
  517. {
  518. _ASSERTE(::IsWindow(m_hWnd));
  519. return ::GetNextDlgTabItem(m_hWnd, hWndCtl, bPrevious);
  520. }
  521. UINT IsDlgButtonChecked(int nIDButton) const
  522. {
  523. _ASSERTE(::IsWindow(m_hWnd));
  524. return ::IsDlgButtonChecked(m_hWnd, nIDButton);
  525. }
  526. LRESULT SendDlgItemMessage(int nID, UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  527. {
  528. _ASSERTE(::IsWindow(m_hWnd));
  529. return ::SendDlgItemMessage(m_hWnd, nID, message, wParam, lParam);
  530. }
  531. BOOL SetDlgItemInt(int nID, UINT nValue, BOOL bSigned = TRUE)
  532. {
  533. _ASSERTE(::IsWindow(m_hWnd));
  534. return ::SetDlgItemInt(m_hWnd, nID, nValue, bSigned);
  535. }
  536. BOOL SetDlgItemText(int nID, LPCTSTR lpszString)
  537. {
  538. _ASSERTE(::IsWindow(m_hWnd));
  539. return ::SetDlgItemText(m_hWnd, nID, lpszString);
  540. }
  541. // Scrolling Functions
  542. int GetScrollPos(int nBar) const
  543. {
  544. _ASSERTE(::IsWindow(m_hWnd));
  545. return ::GetScrollPos(m_hWnd, nBar);
  546. }
  547. BOOL GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
  548. {
  549. _ASSERTE(::IsWindow(m_hWnd));
  550. return ::GetScrollRange(m_hWnd, nBar, lpMinPos, lpMaxPos);
  551. }
  552. BOOL ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect = NULL, LPCRECT lpClipRect = NULL)
  553. {
  554. _ASSERTE(::IsWindow(m_hWnd));
  555. return ::ScrollWindow(m_hWnd, xAmount, yAmount, lpRect, lpClipRect);
  556. }
  557. int ScrollWindowEx(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate, UINT flags)
  558. {
  559. _ASSERTE(::IsWindow(m_hWnd));
  560. return ::ScrollWindowEx(m_hWnd, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate, flags);
  561. }
  562. int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
  563. {
  564. _ASSERTE(::IsWindow(m_hWnd));
  565. return ::SetScrollPos(m_hWnd, nBar, nPos, bRedraw);
  566. }
  567. BOOL SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
  568. {
  569. _ASSERTE(::IsWindow(m_hWnd));
  570. return ::SetScrollRange(m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
  571. }
  572. BOOL ShowScrollBar(UINT nBar, BOOL bShow = TRUE)
  573. {
  574. _ASSERTE(::IsWindow(m_hWnd));
  575. return ::ShowScrollBar(m_hWnd, nBar, bShow);
  576. }
  577. BOOL EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH)
  578. {
  579. _ASSERTE(::IsWindow(m_hWnd));
  580. return ::EnableScrollBar(m_hWnd, uSBFlags, uArrowFlags);
  581. }
  582. // Window Access Functions
  583. HWND ChildWindowFromPoint(POINT point) const
  584. {
  585. _ASSERTE(::IsWindow(m_hWnd));
  586. return ::ChildWindowFromPoint(m_hWnd, point);
  587. }
  588. HWND ChildWindowFromPointEx(POINT point, UINT uFlags) const
  589. {
  590. _ASSERTE(::IsWindow(m_hWnd));
  591. return ::ChildWindowFromPointEx(m_hWnd, point, uFlags);
  592. }
  593. HWND GetTopWindow() const
  594. {
  595. _ASSERTE(::IsWindow(m_hWnd));
  596. return ::GetTopWindow(m_hWnd);
  597. }
  598. HWND GetWindow(UINT nCmd) const
  599. {
  600. _ASSERTE(::IsWindow(m_hWnd));
  601. return ::GetWindow(m_hWnd, nCmd);
  602. }
  603. HWND GetLastActivePopup() const
  604. {
  605. _ASSERTE(::IsWindow(m_hWnd));
  606. return ::GetLastActivePopup(m_hWnd);
  607. }
  608. BOOL IsChild(HWND hWnd) const
  609. {
  610. _ASSERTE(::IsWindow(m_hWnd));
  611. return ::IsChild(m_hWnd, hWnd);
  612. }
  613. HWND GetParent() const
  614. {
  615. _ASSERTE(::IsWindow(m_hWnd));
  616. return ::GetParent(m_hWnd);
  617. }
  618. HWND SetParent(HWND hWndNewParent)
  619. {
  620. _ASSERTE(::IsWindow(m_hWnd));
  621. return ::SetParent(m_hWnd, hWndNewParent);
  622. }
  623. // Window Tree Access
  624. int GetDlgCtrlID() const
  625. {
  626. _ASSERTE(::IsWindow(m_hWnd));
  627. return ::GetDlgCtrlID(m_hWnd);
  628. }
  629. int SetDlgCtrlID(int nID)
  630. {
  631. _ASSERTE(::IsWindow(m_hWnd));
  632. return (int)::SetWindowLong(m_hWnd, GWL_ID, nID);
  633. }
  634. HWND GetDlgItem(int nID) const
  635. {
  636. _ASSERTE(::IsWindow(m_hWnd));
  637. return ::GetDlgItem(m_hWnd, nID);
  638. }
  639. HWND GetDescendantWindow(int nID) const;
  640. void SendMessageToDescendants(UINT message, WPARAM wParam = 0, LPARAM lParam = 0, BOOL bDeep = TRUE);
  641. // Alert Functions
  642. BOOL FlashWindow(BOOL bInvert)
  643. {
  644. _ASSERTE(::IsWindow(m_hWnd));
  645. return ::FlashWindow(m_hWnd, bInvert);
  646. }
  647. int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK)
  648. {
  649. _ASSERTE(::IsWindow(m_hWnd));
  650. return ::MessageBox(m_hWnd, lpszText, lpszCaption, nType);
  651. }
  652. // Clipboard Functions
  653. BOOL ChangeClipboardChain(HWND hWndNewNext)
  654. {
  655. _ASSERTE(::IsWindow(m_hWnd));
  656. return ::ChangeClipboardChain(m_hWnd, hWndNewNext);
  657. }
  658. HWND SetClipboardViewer()
  659. {
  660. _ASSERTE(::IsWindow(m_hWnd));
  661. return ::SetClipboardViewer(m_hWnd);
  662. }
  663. BOOL OpenClipboard()
  664. {
  665. _ASSERTE(::IsWindow(m_hWnd));
  666. return ::OpenClipboard(m_hWnd);
  667. }
  668. // Caret Functions
  669. BOOL CreateCaret(HBITMAP hBitmap)
  670. {
  671. _ASSERTE(::IsWindow(m_hWnd));
  672. return ::CreateCaret(m_hWnd, hBitmap, 0, 0);
  673. }
  674. BOOL CreateSolidCaret(int nWidth, int nHeight)
  675. {
  676. _ASSERTE(::IsWindow(m_hWnd));
  677. return ::CreateCaret(m_hWnd, (HBITMAP)0, nWidth, nHeight);
  678. }
  679. BOOL CreateGrayCaret(int nWidth, int nHeight)
  680. {
  681. _ASSERTE(::IsWindow(m_hWnd));
  682. return ::CreateCaret(m_hWnd, (HBITMAP)1, nWidth, nHeight);
  683. }
  684. BOOL HideCaret()
  685. {
  686. _ASSERTE(::IsWindow(m_hWnd));
  687. return ::HideCaret(m_hWnd);
  688. }
  689. BOOL ShowCaret()
  690. {
  691. _ASSERTE(::IsWindow(m_hWnd));
  692. return ::ShowCaret(m_hWnd);
  693. }
  694. // Drag-Drop Functions
  695. #ifdef _INC_SHELLAPI
  696. void DragAcceptFiles(BOOL bAccept = TRUE)
  697. {
  698. _ASSERTE(::IsWindow(m_hWnd)); ::DragAcceptFiles(m_hWnd, bAccept);
  699. }
  700. #endif
  701. // Icon Functions
  702. HICON SetIcon(HICON hIcon, BOOL bBigIcon = TRUE)
  703. {
  704. _ASSERTE(::IsWindow(m_hWnd));
  705. return (HICON)::SendMessage(m_hWnd, WM_SETICON, bBigIcon, (LPARAM)hIcon);
  706. }
  707. HICON GetIcon(BOOL bBigIcon = TRUE) const
  708. {
  709. _ASSERTE(::IsWindow(m_hWnd));
  710. return (HICON)::SendMessage(m_hWnd, WM_GETICON, bBigIcon, 0);
  711. }
  712. // Help Functions
  713. #if defined(_WINUSER_) && !defined(NOHELP)
  714. BOOL WinHelp(LPCTSTR lpszHelp, UINT nCmd = HELP_CONTEXT, DWORD_PTR dwData = 0)
  715. {
  716. _ASSERTE(::IsWindow(m_hWnd));
  717. return ::WinHelp(m_hWnd, lpszHelp, nCmd, dwData);
  718. }
  719. BOOL SetWindowContextHelpId(DWORD dwContextHelpId)
  720. {
  721. _ASSERTE(::IsWindow(m_hWnd));
  722. return ::SetWindowContextHelpId(m_hWnd, dwContextHelpId);
  723. }
  724. DWORD GetWindowContextHelpId() const
  725. {
  726. _ASSERTE(::IsWindow(m_hWnd));
  727. return ::GetWindowContextHelpId(m_hWnd);
  728. }
  729. #endif
  730. // Hot Key Functions
  731. int SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
  732. {
  733. _ASSERTE(::IsWindow(m_hWnd));
  734. return (int)::SendMessage(m_hWnd, WM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0);
  735. }
  736. DWORD GetHotKey(WORD& /* wVirtualKeyCode */, WORD& /* wModifiers */) const
  737. {
  738. _ASSERTE(::IsWindow(m_hWnd));
  739. return (DWORD)::SendMessage(m_hWnd, WM_GETHOTKEY, 0, 0);
  740. }
  741. // Misc. Operations
  742. BOOL CenterWindow(HWND hWndCenter = NULL);
  743. HWND GetTopLevelParent() const;
  744. HWND GetTopLevelWindow() const;
  745. };
  746. /////////////////////////////////////////////////////////////////////////////
  747. // Thunks for __stdcall member functions
  748. #if defined(_M_IX86)
  749. #pragma pack(push,1)
  750. struct _stdcallthunk
  751. {
  752. DWORD m_mov; // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
  753. DWORD m_this; //
  754. BYTE m_jmp; // jmp WndProc
  755. DWORD m_relproc; // relative jmp
  756. void Init(DWORD_PTR proc, void* pThis)
  757. {
  758. m_mov = 0x042444C7; //C7 44 24 0C
  759. m_this = PtrToUlong(pThis);
  760. m_jmp = 0xe9;
  761. m_relproc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(_stdcallthunk)));
  762. // write block from data cache and
  763. // flush from instruction cache
  764. FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
  765. }
  766. };
  767. #pragma pack(pop)
  768. #elif defined (_M_AMD64)
  769. #pragma pack(push,2)
  770. struct _stdcallthunk
  771. {
  772. USHORT RcxMov; // mov rcx, pThis
  773. ULONG64 RcxImm; //
  774. USHORT RaxMov; // mov rax, target
  775. ULONG64 RaxImm; //
  776. USHORT RaxJmp; // jmp target
  777. void Init(DWORD_PTR proc, void *pThis)
  778. {
  779. RcxMov = 0xb948; // mov rcx, pThis
  780. RcxImm = (ULONG64)pThis; //
  781. RaxMov = 0xb848; // mov rax, target
  782. RaxImm = (ULONG64)proc; //
  783. RaxJmp = 0xe0ff; // jmp rax
  784. FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));
  785. }
  786. };
  787. #pragma pack(pop)
  788. #elif defined(_M_IA64)
  789. #pragma pack(push,8)
  790. extern "C" LRESULT CALLBACK _WndProcThunkProc( HWND, UINT, WPARAM, LPARAM );
  791. struct _FuncDesc
  792. {
  793. void* pfn;
  794. void* gp;
  795. };
  796. struct _stdcallthunk
  797. {
  798. _FuncDesc m_funcdesc;
  799. void* m_pFunc;
  800. void* m_pThis;
  801. void Init(DWORD_PTR proc, void* pThis)
  802. {
  803. const _FuncDesc* pThunkProc;
  804. pThunkProc = reinterpret_cast< const _FuncDesc* >( _WndProcThunkProc );
  805. m_funcdesc.pfn = pThunkProc->pfn;
  806. m_funcdesc.gp = &m_pFunc;
  807. m_pFunc = reinterpret_cast< void* >( proc );
  808. m_pThis = pThis;
  809. ::FlushInstructionCache( GetCurrentProcess(), this, sizeof( _stdcallthunk ) );
  810. }
  811. };
  812. #pragma pack(pop)
  813. #else
  814. #error Only AMD64, IA64, and X86 supported
  815. #endif
  816. class CDynamicStdCallThunk
  817. {
  818. public:
  819. _stdcallthunk *pThunk;
  820. CDynamicStdCallThunk()
  821. {
  822. pThunk = NULL;
  823. }
  824. ~CDynamicStdCallThunk()
  825. {
  826. if (pThunk)
  827. HeapFree(GetProcessHeap(), 0, pThunk);
  828. }
  829. void Init(DWORD_PTR proc, void *pThis)
  830. {
  831. if (!pThunk) {
  832. pThunk = static_cast<_stdcallthunk *>(HeapAlloc(GetProcessHeap(),
  833. HEAP_GENERATE_EXCEPTIONS, sizeof(_stdcallthunk)));
  834. }
  835. ATLASSERT(pThunk);
  836. pThunk->Init(proc, pThis);
  837. }
  838. };
  839. typedef CDynamicStdCallThunk CStdCallThunk;
  840. /////////////////////////////////////////////////////////////////////////////
  841. // WindowProc thunks
  842. class CWndProcThunk
  843. {
  844. public:
  845. _AtlCreateWndData cd;
  846. CStdCallThunk thunk;
  847. void Init(WNDPROC proc, void* pThis)
  848. {
  849. thunk.Init((DWORD_PTR)proc, pThis);
  850. }
  851. };
  852. /////////////////////////////////////////////////////////////////////////////
  853. // CMessageMap - abstract class that provides an interface for message maps
  854. class ATL_NO_VTABLE CMessageMap
  855. {
  856. public:
  857. virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
  858. LRESULT& lResult, DWORD dwMsgMapID) = 0;
  859. };
  860. /////////////////////////////////////////////////////////////////////////////
  861. // Message map
  862. #define BEGIN_MSG_MAP(theClass) \
  863. public: \
  864. BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \
  865. { \
  866. BOOL bHandled = TRUE; \
  867. hWnd; \
  868. switch(dwMsgMapID) \
  869. { \
  870. case 0:
  871. #define ALT_MSG_MAP(msgMapID) \
  872. break; \
  873. case msgMapID:
  874. #define MESSAGE_HANDLER(msg, func) \
  875. if(uMsg == msg) \
  876. { \
  877. bHandled = TRUE; \
  878. lResult = func(uMsg, wParam, lParam, bHandled); \
  879. if(bHandled) \
  880. return TRUE; \
  881. }
  882. #define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func) \
  883. if(uMsg >= msgFirst && uMsg <= msgLast) \
  884. { \
  885. bHandled = TRUE; \
  886. lResult = func(uMsg, wParam, lParam, bHandled); \
  887. if(bHandled) \
  888. return TRUE; \
  889. }
  890. #define COMMAND_HANDLER(id, code, func) \
  891. if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
  892. { \
  893. bHandled = TRUE; \
  894. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  895. if(bHandled) \
  896. return TRUE; \
  897. }
  898. #define COMMAND_ID_HANDLER(id, func) \
  899. if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
  900. { \
  901. bHandled = TRUE; \
  902. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  903. if(bHandled) \
  904. return TRUE; \
  905. }
  906. #define COMMAND_CODE_HANDLER(code, func) \
  907. if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \
  908. { \
  909. bHandled = TRUE; \
  910. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  911. if(bHandled) \
  912. return TRUE; \
  913. }
  914. #define COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
  915. if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
  916. { \
  917. bHandled = TRUE; \
  918. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  919. if(bHandled) \
  920. return TRUE; \
  921. }
  922. #define NOTIFY_HANDLER(id, cd, func) \
  923. if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
  924. { \
  925. bHandled = TRUE; \
  926. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  927. if(bHandled) \
  928. return TRUE; \
  929. }
  930. #define NOTIFY_ID_HANDLER(id, func) \
  931. if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
  932. { \
  933. bHandled = TRUE; \
  934. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  935. if(bHandled) \
  936. return TRUE; \
  937. }
  938. #define NOTIFY_CODE_HANDLER(cd, func) \
  939. if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
  940. { \
  941. bHandled = TRUE; \
  942. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  943. if(bHandled) \
  944. return TRUE; \
  945. }
  946. #define NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \
  947. if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
  948. { \
  949. bHandled = TRUE; \
  950. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  951. if(bHandled) \
  952. return TRUE; \
  953. }
  954. #define CHAIN_MSG_MAP(theChainClass) \
  955. { \
  956. if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
  957. return TRUE; \
  958. }
  959. #define CHAIN_MSG_MAP_MEMBER(theChainMember) \
  960. { \
  961. if(theChainMember.ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
  962. return TRUE; \
  963. }
  964. #define CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) \
  965. { \
  966. if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
  967. return TRUE; \
  968. }
  969. #define CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) \
  970. { \
  971. if(theChainMember.ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
  972. return TRUE; \
  973. }
  974. #define CHAIN_MSG_MAP_DYNAMIC(dynaChainID) \
  975. { \
  976. if(CDynamicChain::CallChain(dynaChainID, hWnd, uMsg, wParam, lParam, lResult)) \
  977. return TRUE; \
  978. }
  979. #define CHAIN_MSG_MAP_ALT_DYNAMIC(dynaChainID, msgMapID) \
  980. { \
  981. if(CDynamicChain::CallChain(dynaChainID, hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
  982. return TRUE; \
  983. }
  984. #define END_MSG_MAP() \
  985. break; \
  986. default: \
  987. ATLTRACE(_T("Invalid message map ID (%i)\n"), dwMsgMapID); \
  988. _ASSERTE(FALSE); \
  989. break; \
  990. } \
  991. return FALSE; \
  992. }
  993. // Handler prototypes:
  994. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  995. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  996. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  997. /////////////////////////////////////////////////////////////////////////////
  998. // CDynamicChain - provides support for dynamic chaining
  999. class CDynamicChain
  1000. {
  1001. public:
  1002. struct ATL_CHAIN_ENTRY
  1003. {
  1004. DWORD m_dwChainID;
  1005. CMessageMap* m_pObject;
  1006. DWORD m_dwMsgMapID;
  1007. };
  1008. int m_nEntries;
  1009. ATL_CHAIN_ENTRY** m_pChainEntry;
  1010. CDynamicChain() : m_nEntries(0), m_pChainEntry(NULL)
  1011. { }
  1012. ~CDynamicChain();
  1013. BOOL SetChainEntry(DWORD dwChainID, CMessageMap* pObject, DWORD dwMsgMapID = 0);
  1014. BOOL RemoveChainEntry(DWORD dwChainID);
  1015. BOOL CallChain(DWORD dwChainID, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult);
  1016. };
  1017. /////////////////////////////////////////////////////////////////////////////
  1018. // CWndClassInfo - Manages Windows class information
  1019. class CWndClassInfo
  1020. {
  1021. public:
  1022. WNDCLASSEX m_wc;
  1023. LPCTSTR m_lpszOrigName;
  1024. WNDPROC pWndProc;
  1025. LPCTSTR m_lpszCursorID;
  1026. BOOL m_bSystemCursor;
  1027. ATOM m_atom;
  1028. TCHAR m_szAutoName[sizeof("ATL:") + (sizeof(PVOID)*2)+1];
  1029. ATOM Register(WNDPROC*);
  1030. };
  1031. #define DECLARE_WND_CLASS(WndClassName) \
  1032. static CWndClassInfo& GetWndClassInfo() \
  1033. { \
  1034. static CWndClassInfo wc = \
  1035. { \
  1036. { sizeof(WNDCLASSEX), CS_HREDRAW|CS_VREDRAW, StartWindowProc, \
  1037. 0, 0, 0, 0, 0, (HBRUSH)(COLOR_WINDOW+1), 0, WndClassName, 0 }, \
  1038. NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
  1039. }; \
  1040. return wc; \
  1041. }
  1042. #define DECLARE_WND_SUPERCLASS(WndClassName, OrigWndClassName) \
  1043. static CWndClassInfo& GetWndClassInfo() \
  1044. { \
  1045. static CWndClassInfo wc = \
  1046. { \
  1047. { sizeof(WNDCLASSEX), NULL, StartWindowProc, \
  1048. 0, 0, 0, 0, 0, NULL, 0, WndClassName, 0 }, \
  1049. OrigWndClassName, NULL, NULL, TRUE, 0, _T("") \
  1050. }; \
  1051. return wc; \
  1052. }
  1053. /////////////////////////////////////////////////////////////////////////////
  1054. // CWindowImpl - Implements a window
  1055. class ATL_NO_VTABLE CWindowImplBase : public CWindow, public CMessageMap
  1056. {
  1057. public:
  1058. CWndProcThunk m_thunk;
  1059. WNDPROC m_pfnSuperWindowProc;
  1060. CWindowImplBase() : m_pfnSuperWindowProc(::DefWindowProc)
  1061. {}
  1062. static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1063. static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1064. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName,
  1065. DWORD dwStyle, DWORD dwExStyle, UINT_PTR nID, ATOM atom);
  1066. BOOL SubclassWindow(HWND hWnd);
  1067. HWND UnsubclassWindow();
  1068. LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1069. {
  1070. #ifdef STRICT
  1071. return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  1072. #else
  1073. return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  1074. #endif
  1075. }
  1076. };
  1077. template <class T>
  1078. class ATL_NO_VTABLE CWindowImpl : public CWindowImplBase
  1079. {
  1080. public:
  1081. DECLARE_WND_CLASS(NULL)
  1082. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  1083. DWORD dwStyle = WS_CHILD | WS_VISIBLE, DWORD dwExStyle = 0,
  1084. UINT_PTR nID = 0)
  1085. {
  1086. ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
  1087. return CWindowImplBase::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle,
  1088. nID, atom);
  1089. }
  1090. };
  1091. /////////////////////////////////////////////////////////////////////////////
  1092. // CDialog - Implements a dialog box
  1093. class ATL_NO_VTABLE CDialogImplBase : public CWindow, public CMessageMap
  1094. {
  1095. public:
  1096. CWndProcThunk m_thunk;
  1097. static INT_PTR CALLBACK StartDialogProc(HWND hWnd, UINT uMsg,
  1098. WPARAM wParam, LPARAM lParam);
  1099. static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1100. BOOL EndDialog(int nRetCode);
  1101. };
  1102. template <class T>
  1103. class ATL_NO_VTABLE CDialogImpl : public CDialogImplBase
  1104. {
  1105. public:
  1106. INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
  1107. {
  1108. _ASSERTE(m_hWnd == NULL);
  1109. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBase*)this);
  1110. INT_PTR nRet = ::DialogBoxParam(_Module.GetResourceInstance(),
  1111. MAKEINTRESOURCE(T::IDD),
  1112. hWndParent,
  1113. T::StartDialogProc,
  1114. NULL);
  1115. m_hWnd = NULL;
  1116. return nRet;
  1117. }
  1118. HWND Create(HWND hWndParent)
  1119. {
  1120. _ASSERTE(m_hWnd == NULL);
  1121. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBase*)this);
  1122. HWND hWnd = ::CreateDialogParam(_Module.GetResourceInstance(),
  1123. MAKEINTRESOURCE(T::IDD),
  1124. hWndParent,
  1125. T::StartDialogProc,
  1126. NULL);
  1127. _ASSERTE(m_hWnd == hWnd);
  1128. return hWnd;
  1129. }
  1130. };
  1131. /////////////////////////////////////////////////////////////////////////////
  1132. // CContainedWindow - Implements a contained window
  1133. class CContainedWindow : public CWindow
  1134. {
  1135. public:
  1136. CWndProcThunk m_thunk;
  1137. LPTSTR m_lpszClassName;
  1138. WNDPROC m_pfnSuperWindowProc;
  1139. CMessageMap* m_pObject;
  1140. DWORD m_dwMsgMapID;
  1141. CContainedWindow(LPTSTR lpszClassName, CMessageMap* pObject, DWORD dwMsgMapID = 0)
  1142. : m_lpszClassName(lpszClassName),
  1143. m_pfnSuperWindowProc(::DefWindowProc),
  1144. m_pObject(pObject), m_dwMsgMapID(dwMsgMapID)
  1145. { }
  1146. void SwitchMessageMap(DWORD dwMsgMapID)
  1147. {
  1148. m_dwMsgMapID = dwMsgMapID;
  1149. }
  1150. static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg,
  1151. WPARAM wParam, LPARAM lParam);
  1152. static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1153. ATOM RegisterWndSuperclass();
  1154. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  1155. DWORD dwStyle = WS_CHILD | WS_VISIBLE, DWORD dwExStyle = 0,
  1156. UINT nID = 0);
  1157. BOOL SubclassWindow(HWND hWnd);
  1158. HWND UnsubclassWindow();
  1159. LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1160. {
  1161. #ifdef STRICT
  1162. return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  1163. #else
  1164. return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  1165. #endif
  1166. }
  1167. };
  1168. #ifndef ATL_NO_NAMESPACE
  1169. }; //namespace ATL
  1170. #endif
  1171. #ifdef _ATL_REDEF_SUBCLASSWINDOW
  1172. #pragma pop_macro( "SubclassWindow" )
  1173. #undef _ATL_REDEF_SUBCLASSWINDOW
  1174. #endif
  1175. #endif // __ATLWIN_H__