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.

3122 lines
110 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1998 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. struct _ATL_WNDCLASSINFOA;
  19. struct _ATL_WNDCLASSINFOW;
  20. #ifndef _ATL_DLL_IMPL
  21. namespace ATL
  22. {
  23. #endif
  24. ATLAPI_(ATOM) AtlModuleRegisterWndClassInfoA(_ATL_MODULE* pM, _ATL_WNDCLASSINFOA* p, WNDPROC* pProc);
  25. ATLAPI_(ATOM) AtlModuleRegisterWndClassInfoW(_ATL_MODULE* pM, _ATL_WNDCLASSINFOW* p, WNDPROC* pProc);
  26. #ifdef UNICODE
  27. #define AtlModuleRegisterWndClassInfo AtlModuleRegisterWndClassInfoW
  28. #else
  29. #define AtlModuleRegisterWndClassInfo AtlModuleRegisterWndClassInfoA
  30. #endif
  31. #define HIMETRIC_PER_INCH 2540
  32. #define MAP_PIX_TO_LOGHIM(x,ppli) ( (HIMETRIC_PER_INCH*(x) + ((ppli)>>1)) / (ppli) )
  33. #define MAP_LOGHIM_TO_PIX(x,ppli) ( ((ppli)*(x) + HIMETRIC_PER_INCH/2) / HIMETRIC_PER_INCH )
  34. ATLAPI_(HDC) AtlCreateTargetDC(HDC hdc, DVTARGETDEVICE* ptd);
  35. ATLAPI_(void) AtlHiMetricToPixel(const SIZEL * lpSizeInHiMetric, LPSIZEL lpSizeInPix);
  36. ATLAPI_(void) AtlPixelToHiMetric(const SIZEL * lpSizeInPix, LPSIZEL lpSizeInHiMetric);
  37. #ifndef _ATL_DLL_IMPL
  38. }; //namespace ATL
  39. #endif
  40. struct _ATL_WNDCLASSINFOA
  41. {
  42. WNDCLASSEXA m_wc;
  43. LPCSTR m_lpszOrigName;
  44. WNDPROC pWndProc;
  45. LPCSTR m_lpszCursorID;
  46. BOOL m_bSystemCursor;
  47. ATOM m_atom;
  48. CHAR m_szAutoName[sizeof("ATL:") + (sizeof(PVOID)*2)+1];
  49. ATOM Register(WNDPROC* p)
  50. {
  51. return AtlModuleRegisterWndClassInfoA(&_Module, this, p);
  52. }
  53. };
  54. struct _ATL_WNDCLASSINFOW
  55. {
  56. WNDCLASSEXW m_wc;
  57. LPCWSTR m_lpszOrigName;
  58. WNDPROC pWndProc;
  59. LPCWSTR m_lpszCursorID;
  60. BOOL m_bSystemCursor;
  61. ATOM m_atom;
  62. WCHAR m_szAutoName[sizeof("ATL:") + (sizeof(PVOID)*2)+1];
  63. ATOM Register(WNDPROC* p)
  64. {
  65. return AtlModuleRegisterWndClassInfoW(&_Module, this, p);
  66. }
  67. };
  68. namespace ATL
  69. {
  70. /////////////////////////////////////////////////////////////////////////////
  71. // Forward declarations
  72. class CWindow;
  73. #ifndef _ATL_NO_HOSTING
  74. template <class TBase = CWindow> class CAxWindowT;
  75. #endif //!_ATL_NO_HOSTING
  76. class CMessageMap;
  77. class CDynamicChain;
  78. typedef _ATL_WNDCLASSINFOA CWndClassInfoA;
  79. typedef _ATL_WNDCLASSINFOW CWndClassInfoW;
  80. #ifdef UNICODE
  81. #define CWndClassInfo CWndClassInfoW
  82. #else
  83. #define CWndClassInfo CWndClassInfoA
  84. #endif
  85. template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits> class CWindowImpl;
  86. template <class T, class TBase = CWindow> class CDialogImpl;
  87. #ifndef _ATL_NO_HOSTING
  88. template <class T, class TBase = CWindow> class CAxDialogImpl;
  89. #endif //!_ATL_NO_HOSTING
  90. template <WORD t_wDlgTemplateID, BOOL t_bCenter = TRUE> class CSimpleDialog;
  91. template <class TBase = CWindow, class TWinTraits = CControlWinTraits> class CContainedWindowT;
  92. /////////////////////////////////////////////////////////////////////////////
  93. // CWindow - client side for a Windows window
  94. class CWindow
  95. {
  96. public:
  97. static RECT rcDefault;
  98. HWND m_hWnd;
  99. CWindow(HWND hWnd = NULL)
  100. {
  101. m_hWnd = hWnd;
  102. }
  103. CWindow& operator=(HWND hWnd)
  104. {
  105. m_hWnd = hWnd;
  106. return *this;
  107. }
  108. static LPCTSTR GetWndClassName()
  109. {
  110. return NULL;
  111. }
  112. void Attach(HWND hWndNew)
  113. {
  114. ATLASSERT(::IsWindow(hWndNew));
  115. m_hWnd = hWndNew;
  116. }
  117. HWND Detach()
  118. {
  119. HWND hWnd = m_hWnd;
  120. m_hWnd = NULL;
  121. return hWnd;
  122. }
  123. HWND Create(LPCTSTR lpstrWndClass, HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  124. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  125. UINT nID = 0, LPVOID lpCreateParam = NULL)
  126. {
  127. m_hWnd = ::CreateWindowEx(dwExStyle, lpstrWndClass, szWindowName,
  128. dwStyle, rcPos.left, rcPos.top, rcPos.right - rcPos.left,
  129. rcPos.bottom - rcPos.top, hWndParent, (HMENU)(DWORD_PTR)nID,
  130. _Module.GetModuleInstance(), lpCreateParam);
  131. return m_hWnd;
  132. }
  133. HWND Create(LPCTSTR lpstrWndClass, HWND hWndParent, LPRECT lpRect = NULL, LPCTSTR szWindowName = NULL,
  134. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  135. HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
  136. {
  137. if(lpRect == NULL)
  138. lpRect = &rcDefault;
  139. m_hWnd = ::CreateWindowEx(dwExStyle, lpstrWndClass, szWindowName,
  140. dwStyle, lpRect->left, lpRect->top, lpRect->right - lpRect->left,
  141. lpRect->bottom - lpRect->top, hWndParent, hMenu,
  142. _Module.GetModuleInstance(), lpCreateParam);
  143. return m_hWnd;
  144. }
  145. BOOL DestroyWindow()
  146. {
  147. ATLASSERT(::IsWindow(m_hWnd));
  148. if(!::DestroyWindow(m_hWnd))
  149. return FALSE;
  150. m_hWnd = NULL;
  151. return TRUE;
  152. }
  153. // Attributes
  154. operator HWND() const { return m_hWnd; }
  155. DWORD GetStyle() const
  156. {
  157. ATLASSERT(::IsWindow(m_hWnd));
  158. return (DWORD)::GetWindowLong(m_hWnd, GWL_STYLE);
  159. }
  160. DWORD GetExStyle() const
  161. {
  162. ATLASSERT(::IsWindow(m_hWnd));
  163. return (DWORD)::GetWindowLong(m_hWnd, GWL_EXSTYLE);
  164. }
  165. LONG GetWindowLong(int nIndex) const
  166. {
  167. ATLASSERT(::IsWindow(m_hWnd));
  168. return ::GetWindowLong(m_hWnd, nIndex);
  169. }
  170. LONG SetWindowLong(int nIndex, LONG dwNewLong)
  171. {
  172. ATLASSERT(::IsWindow(m_hWnd));
  173. return ::SetWindowLong(m_hWnd, nIndex, dwNewLong);
  174. }
  175. WORD GetWindowWord(int nIndex) const
  176. {
  177. ATLASSERT(::IsWindow(m_hWnd));
  178. return ::GetWindowWord(m_hWnd, nIndex);
  179. }
  180. WORD SetWindowWord(int nIndex, WORD wNewWord)
  181. {
  182. ATLASSERT(::IsWindow(m_hWnd));
  183. return ::SetWindowWord(m_hWnd, nIndex, wNewWord);
  184. }
  185. // Message Functions
  186. LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  187. {
  188. ATLASSERT(::IsWindow(m_hWnd));
  189. return ::SendMessage(m_hWnd,message,wParam,lParam);
  190. }
  191. BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  192. {
  193. ATLASSERT(::IsWindow(m_hWnd));
  194. return ::PostMessage(m_hWnd,message,wParam,lParam);
  195. }
  196. BOOL SendNotifyMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  197. {
  198. ATLASSERT(::IsWindow(m_hWnd));
  199. return ::SendNotifyMessage(m_hWnd, message, wParam, lParam);
  200. }
  201. // support for C style macros
  202. static LRESULT SendMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  203. {
  204. ATLASSERT(::IsWindow(hWnd));
  205. return ::SendMessage(hWnd, message, wParam, lParam);
  206. }
  207. // Window Text Functions
  208. BOOL SetWindowText(LPCTSTR lpszString)
  209. {
  210. ATLASSERT(::IsWindow(m_hWnd));
  211. return ::SetWindowText(m_hWnd, lpszString);
  212. }
  213. int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount) const
  214. {
  215. ATLASSERT(::IsWindow(m_hWnd));
  216. return ::GetWindowText(m_hWnd, lpszStringBuf, nMaxCount);
  217. }
  218. int GetWindowTextLength() const
  219. {
  220. ATLASSERT(::IsWindow(m_hWnd));
  221. return ::GetWindowTextLength(m_hWnd);
  222. }
  223. // Font Functions
  224. void SetFont(HFONT hFont, BOOL bRedraw = TRUE)
  225. {
  226. ATLASSERT(::IsWindow(m_hWnd));
  227. ::SendMessage(m_hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(bRedraw, 0));
  228. }
  229. HFONT GetFont() const
  230. {
  231. ATLASSERT(::IsWindow(m_hWnd));
  232. return (HFONT)::SendMessage(m_hWnd, WM_GETFONT, 0, 0);
  233. }
  234. // Menu Functions (non-child windows only)
  235. HMENU GetMenu() const
  236. {
  237. ATLASSERT(::IsWindow(m_hWnd));
  238. return ::GetMenu(m_hWnd);
  239. }
  240. BOOL SetMenu(HMENU hMenu)
  241. {
  242. ATLASSERT(::IsWindow(m_hWnd));
  243. return ::SetMenu(m_hWnd, hMenu);
  244. }
  245. BOOL DrawMenuBar()
  246. {
  247. ATLASSERT(::IsWindow(m_hWnd));
  248. return ::DrawMenuBar(m_hWnd);
  249. }
  250. HMENU GetSystemMenu(BOOL bRevert) const
  251. {
  252. ATLASSERT(::IsWindow(m_hWnd));
  253. return ::GetSystemMenu(m_hWnd, bRevert);
  254. }
  255. BOOL HiliteMenuItem(HMENU hMenu, UINT uItemHilite, UINT uHilite)
  256. {
  257. ATLASSERT(::IsWindow(m_hWnd));
  258. return ::HiliteMenuItem(m_hWnd, hMenu, uItemHilite, uHilite);
  259. }
  260. // Window Size and Position Functions
  261. BOOL IsIconic() const
  262. {
  263. ATLASSERT(::IsWindow(m_hWnd));
  264. return ::IsIconic(m_hWnd);
  265. }
  266. BOOL IsZoomed() const
  267. {
  268. ATLASSERT(::IsWindow(m_hWnd));
  269. return ::IsZoomed(m_hWnd);
  270. }
  271. BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE)
  272. {
  273. ATLASSERT(::IsWindow(m_hWnd));
  274. return ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
  275. }
  276. BOOL MoveWindow(LPCRECT lpRect, BOOL bRepaint = TRUE)
  277. {
  278. ATLASSERT(::IsWindow(m_hWnd));
  279. return ::MoveWindow(m_hWnd, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, bRepaint);
  280. }
  281. BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags)
  282. {
  283. ATLASSERT(::IsWindow(m_hWnd));
  284. return ::SetWindowPos(m_hWnd, hWndInsertAfter, x, y, cx, cy, nFlags);
  285. }
  286. BOOL SetWindowPos(HWND hWndInsertAfter, LPCRECT lpRect, UINT nFlags)
  287. {
  288. ATLASSERT(::IsWindow(m_hWnd));
  289. return ::SetWindowPos(m_hWnd, hWndInsertAfter, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, nFlags);
  290. }
  291. UINT ArrangeIconicWindows()
  292. {
  293. ATLASSERT(::IsWindow(m_hWnd));
  294. return ::ArrangeIconicWindows(m_hWnd);
  295. }
  296. BOOL BringWindowToTop()
  297. {
  298. ATLASSERT(::IsWindow(m_hWnd));
  299. return ::BringWindowToTop(m_hWnd);
  300. }
  301. BOOL GetWindowRect(LPRECT lpRect) const
  302. {
  303. ATLASSERT(::IsWindow(m_hWnd));
  304. return ::GetWindowRect(m_hWnd, lpRect);
  305. }
  306. BOOL GetClientRect(LPRECT lpRect) const
  307. {
  308. ATLASSERT(::IsWindow(m_hWnd));
  309. return ::GetClientRect(m_hWnd, lpRect);
  310. }
  311. BOOL GetWindowPlacement(WINDOWPLACEMENT FAR* lpwndpl) const
  312. {
  313. ATLASSERT(::IsWindow(m_hWnd));
  314. return ::GetWindowPlacement(m_hWnd, lpwndpl);
  315. }
  316. BOOL SetWindowPlacement(const WINDOWPLACEMENT FAR* lpwndpl)
  317. {
  318. ATLASSERT(::IsWindow(m_hWnd));
  319. return ::SetWindowPlacement(m_hWnd, lpwndpl);
  320. }
  321. // Coordinate Mapping Functions
  322. BOOL ClientToScreen(LPPOINT lpPoint) const
  323. {
  324. ATLASSERT(::IsWindow(m_hWnd));
  325. return ::ClientToScreen(m_hWnd, lpPoint);
  326. }
  327. BOOL ClientToScreen(LPRECT lpRect) const
  328. {
  329. ATLASSERT(::IsWindow(m_hWnd));
  330. if(!::ClientToScreen(m_hWnd, (LPPOINT)lpRect))
  331. return FALSE;
  332. return ::ClientToScreen(m_hWnd, ((LPPOINT)lpRect)+1);
  333. }
  334. BOOL ScreenToClient(LPPOINT lpPoint) const
  335. {
  336. ATLASSERT(::IsWindow(m_hWnd));
  337. return ::ScreenToClient(m_hWnd, lpPoint);
  338. }
  339. BOOL ScreenToClient(LPRECT lpRect) const
  340. {
  341. ATLASSERT(::IsWindow(m_hWnd));
  342. if(!::ScreenToClient(m_hWnd, (LPPOINT)lpRect))
  343. return FALSE;
  344. return ::ScreenToClient(m_hWnd, ((LPPOINT)lpRect)+1);
  345. }
  346. int MapWindowPoints(HWND hWndTo, LPPOINT lpPoint, UINT nCount) const
  347. {
  348. ATLASSERT(::IsWindow(m_hWnd));
  349. return ::MapWindowPoints(m_hWnd, hWndTo, lpPoint, nCount);
  350. }
  351. int MapWindowPoints(HWND hWndTo, LPRECT lpRect) const
  352. {
  353. ATLASSERT(::IsWindow(m_hWnd));
  354. return ::MapWindowPoints(m_hWnd, hWndTo, (LPPOINT)lpRect, 2);
  355. }
  356. // Update and Painting Functions
  357. HDC BeginPaint(LPPAINTSTRUCT lpPaint)
  358. {
  359. ATLASSERT(::IsWindow(m_hWnd));
  360. return ::BeginPaint(m_hWnd, lpPaint);
  361. }
  362. void EndPaint(LPPAINTSTRUCT lpPaint)
  363. {
  364. ATLASSERT(::IsWindow(m_hWnd));
  365. ::EndPaint(m_hWnd, lpPaint);
  366. }
  367. HDC GetDC()
  368. {
  369. ATLASSERT(::IsWindow(m_hWnd));
  370. return ::GetDC(m_hWnd);
  371. }
  372. HDC GetWindowDC()
  373. {
  374. ATLASSERT(::IsWindow(m_hWnd));
  375. return ::GetWindowDC(m_hWnd);
  376. }
  377. int ReleaseDC(HDC hDC)
  378. {
  379. ATLASSERT(::IsWindow(m_hWnd));
  380. return ::ReleaseDC(m_hWnd, hDC);
  381. }
  382. void Print(HDC hDC, DWORD dwFlags) const
  383. {
  384. ATLASSERT(::IsWindow(m_hWnd));
  385. ::SendMessage(m_hWnd, WM_PRINT, (WPARAM)hDC, dwFlags);
  386. }
  387. void PrintClient(HDC hDC, DWORD dwFlags) const
  388. {
  389. ATLASSERT(::IsWindow(m_hWnd));
  390. ::SendMessage(m_hWnd, WM_PRINTCLIENT, (WPARAM)hDC, dwFlags);
  391. }
  392. BOOL UpdateWindow()
  393. {
  394. ATLASSERT(::IsWindow(m_hWnd));
  395. return ::UpdateWindow(m_hWnd);
  396. }
  397. void SetRedraw(BOOL bRedraw = TRUE)
  398. {
  399. ATLASSERT(::IsWindow(m_hWnd));
  400. ::SendMessage(m_hWnd, WM_SETREDRAW, (WPARAM)bRedraw, 0);
  401. }
  402. BOOL GetUpdateRect(LPRECT lpRect, BOOL bErase = FALSE)
  403. {
  404. ATLASSERT(::IsWindow(m_hWnd));
  405. return ::GetUpdateRect(m_hWnd, lpRect, bErase);
  406. }
  407. int GetUpdateRgn(HRGN hRgn, BOOL bErase = FALSE)
  408. {
  409. ATLASSERT(::IsWindow(m_hWnd));
  410. return ::GetUpdateRgn(m_hWnd, hRgn, bErase);
  411. }
  412. BOOL Invalidate(BOOL bErase = TRUE)
  413. {
  414. ATLASSERT(::IsWindow(m_hWnd));
  415. return ::InvalidateRect(m_hWnd, NULL, bErase);
  416. }
  417. BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE)
  418. {
  419. ATLASSERT(::IsWindow(m_hWnd));
  420. return ::InvalidateRect(m_hWnd, lpRect, bErase);
  421. }
  422. BOOL ValidateRect(LPCRECT lpRect)
  423. {
  424. ATLASSERT(::IsWindow(m_hWnd));
  425. return ::ValidateRect(m_hWnd, lpRect);
  426. }
  427. void InvalidateRgn(HRGN hRgn, BOOL bErase = TRUE)
  428. {
  429. ATLASSERT(::IsWindow(m_hWnd));
  430. ::InvalidateRgn(m_hWnd, hRgn, bErase);
  431. }
  432. BOOL ValidateRgn(HRGN hRgn)
  433. {
  434. ATLASSERT(::IsWindow(m_hWnd));
  435. return ::ValidateRgn(m_hWnd, hRgn);
  436. }
  437. BOOL ShowWindow(int nCmdShow)
  438. {
  439. ATLASSERT(::IsWindow(m_hWnd));
  440. return ::ShowWindow(m_hWnd, nCmdShow);
  441. }
  442. BOOL IsWindowVisible() const
  443. {
  444. ATLASSERT(::IsWindow(m_hWnd));
  445. return ::IsWindowVisible(m_hWnd);
  446. }
  447. BOOL ShowOwnedPopups(BOOL bShow = TRUE)
  448. {
  449. ATLASSERT(::IsWindow(m_hWnd));
  450. return ::ShowOwnedPopups(m_hWnd, bShow);
  451. }
  452. HDC GetDCEx(HRGN hRgnClip, DWORD flags)
  453. {
  454. ATLASSERT(::IsWindow(m_hWnd));
  455. return ::GetDCEx(m_hWnd, hRgnClip, flags);
  456. }
  457. BOOL LockWindowUpdate(BOOL bLock = TRUE)
  458. {
  459. ATLASSERT(::IsWindow(m_hWnd));
  460. return ::LockWindowUpdate(bLock ? m_hWnd : NULL);
  461. }
  462. BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL, HRGN hRgnUpdate = NULL, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE)
  463. {
  464. ATLASSERT(::IsWindow(m_hWnd));
  465. return ::RedrawWindow(m_hWnd, lpRectUpdate, hRgnUpdate, flags);
  466. }
  467. // Timer Functions
  468. UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse)
  469. {
  470. ATLASSERT(::IsWindow(m_hWnd));
  471. return ::SetTimer(m_hWnd, nIDEvent, nElapse, NULL);
  472. }
  473. BOOL KillTimer(UINT_PTR nIDEvent)
  474. {
  475. ATLASSERT(::IsWindow(m_hWnd));
  476. return ::KillTimer(m_hWnd, nIDEvent);
  477. }
  478. // Window State Functions
  479. BOOL IsWindowEnabled() const
  480. {
  481. ATLASSERT(::IsWindow(m_hWnd));
  482. return ::IsWindowEnabled(m_hWnd);
  483. }
  484. BOOL EnableWindow(BOOL bEnable = TRUE)
  485. {
  486. ATLASSERT(::IsWindow(m_hWnd));
  487. return ::EnableWindow(m_hWnd, bEnable);
  488. }
  489. HWND SetActiveWindow()
  490. {
  491. ATLASSERT(::IsWindow(m_hWnd));
  492. return ::SetActiveWindow(m_hWnd);
  493. }
  494. HWND SetCapture()
  495. {
  496. ATLASSERT(::IsWindow(m_hWnd));
  497. return ::SetCapture(m_hWnd);
  498. }
  499. HWND SetFocus()
  500. {
  501. ATLASSERT(::IsWindow(m_hWnd));
  502. return ::SetFocus(m_hWnd);
  503. }
  504. // Dialog-Box Item Functions
  505. BOOL CheckDlgButton(int nIDButton, UINT nCheck)
  506. {
  507. ATLASSERT(::IsWindow(m_hWnd));
  508. return ::CheckDlgButton(m_hWnd, nIDButton, nCheck);
  509. }
  510. BOOL CheckRadioButton(int nIDFirstButton, int nIDLastButton, int nIDCheckButton)
  511. {
  512. ATLASSERT(::IsWindow(m_hWnd));
  513. return ::CheckRadioButton(m_hWnd, nIDFirstButton, nIDLastButton, nIDCheckButton);
  514. }
  515. int DlgDirList(LPTSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT nFileType)
  516. {
  517. ATLASSERT(::IsWindow(m_hWnd));
  518. return ::DlgDirList(m_hWnd, lpPathSpec, nIDListBox, nIDStaticPath, nFileType);
  519. }
  520. int DlgDirListComboBox(LPTSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT nFileType)
  521. {
  522. ATLASSERT(::IsWindow(m_hWnd));
  523. return ::DlgDirListComboBox(m_hWnd, lpPathSpec, nIDComboBox, nIDStaticPath, nFileType);
  524. }
  525. BOOL DlgDirSelect(LPTSTR lpString, int nCount, int nIDListBox)
  526. {
  527. ATLASSERT(::IsWindow(m_hWnd));
  528. return ::DlgDirSelectEx(m_hWnd, lpString, nCount, nIDListBox);
  529. }
  530. BOOL DlgDirSelectComboBox(LPTSTR lpString, int nCount, int nIDComboBox)
  531. {
  532. ATLASSERT(::IsWindow(m_hWnd));
  533. return ::DlgDirSelectComboBoxEx(m_hWnd, lpString, nCount, nIDComboBox);
  534. }
  535. UINT GetDlgItemInt(int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE) const
  536. {
  537. ATLASSERT(::IsWindow(m_hWnd));
  538. return ::GetDlgItemInt(m_hWnd, nID, lpTrans, bSigned);
  539. }
  540. UINT GetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount) const
  541. {
  542. ATLASSERT(::IsWindow(m_hWnd));
  543. return ::GetDlgItemText(m_hWnd, nID, lpStr, nMaxCount);
  544. }
  545. BOOL GetDlgItemText(int nID, BSTR& bstrText) const
  546. {
  547. ATLASSERT(::IsWindow(m_hWnd));
  548. HWND hWndCtl = GetDlgItem(nID);
  549. if(hWndCtl == NULL)
  550. return FALSE;
  551. return CWindow(hWndCtl).GetWindowText(bstrText);
  552. }
  553. HWND GetNextDlgGroupItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
  554. {
  555. ATLASSERT(::IsWindow(m_hWnd));
  556. return ::GetNextDlgGroupItem(m_hWnd, hWndCtl, bPrevious);
  557. }
  558. HWND GetNextDlgTabItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
  559. {
  560. ATLASSERT(::IsWindow(m_hWnd));
  561. return ::GetNextDlgTabItem(m_hWnd, hWndCtl, bPrevious);
  562. }
  563. UINT IsDlgButtonChecked(int nIDButton) const
  564. {
  565. ATLASSERT(::IsWindow(m_hWnd));
  566. return ::IsDlgButtonChecked(m_hWnd, nIDButton);
  567. }
  568. LRESULT SendDlgItemMessage(int nID, UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  569. {
  570. ATLASSERT(::IsWindow(m_hWnd));
  571. return ::SendDlgItemMessage(m_hWnd, nID, message, wParam, lParam);
  572. }
  573. BOOL SetDlgItemInt(int nID, UINT nValue, BOOL bSigned = TRUE)
  574. {
  575. ATLASSERT(::IsWindow(m_hWnd));
  576. return ::SetDlgItemInt(m_hWnd, nID, nValue, bSigned);
  577. }
  578. BOOL SetDlgItemText(int nID, LPCTSTR lpszString)
  579. {
  580. ATLASSERT(::IsWindow(m_hWnd));
  581. return ::SetDlgItemText(m_hWnd, nID, lpszString);
  582. }
  583. #ifndef _ATL_NO_HOSTING
  584. HRESULT GetDlgControl(int nID, REFIID iid, void** ppUnk)
  585. {
  586. ATLASSERT(::IsWindow(m_hWnd));
  587. ATLASSERT(ppUnk != NULL);
  588. HRESULT hr = E_FAIL;
  589. HWND hWndCtrl = GetDlgItem(nID);
  590. if (hWndCtrl != NULL)
  591. {
  592. if (ppUnk == NULL)
  593. {
  594. return E_POINTER;
  595. }
  596. *ppUnk = NULL;
  597. CComPtr<IUnknown> spUnk;
  598. hr = AtlAxGetControl(hWndCtrl, &spUnk);
  599. if (SUCCEEDED(hr))
  600. hr = spUnk->QueryInterface(iid, ppUnk);
  601. }
  602. return hr;
  603. }
  604. #endif //!_ATL_NO_HOSTING
  605. // Scrolling Functions
  606. int GetScrollPos(int nBar) const
  607. {
  608. ATLASSERT(::IsWindow(m_hWnd));
  609. return ::GetScrollPos(m_hWnd, nBar);
  610. }
  611. BOOL GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
  612. {
  613. ATLASSERT(::IsWindow(m_hWnd));
  614. return ::GetScrollRange(m_hWnd, nBar, lpMinPos, lpMaxPos);
  615. }
  616. BOOL ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect = NULL, LPCRECT lpClipRect = NULL)
  617. {
  618. ATLASSERT(::IsWindow(m_hWnd));
  619. return ::ScrollWindow(m_hWnd, xAmount, yAmount, lpRect, lpClipRect);
  620. }
  621. int ScrollWindowEx(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate, UINT uFlags)
  622. {
  623. ATLASSERT(::IsWindow(m_hWnd));
  624. return ::ScrollWindowEx(m_hWnd, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate, uFlags);
  625. }
  626. int ScrollWindowEx(int dx, int dy, UINT uFlags, LPCRECT lpRectScroll = NULL, LPCRECT lpRectClip = NULL, HRGN hRgnUpdate = NULL, LPRECT lpRectUpdate = NULL)
  627. {
  628. ATLASSERT(::IsWindow(m_hWnd));
  629. return ::ScrollWindowEx(m_hWnd, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate, uFlags);
  630. }
  631. int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
  632. {
  633. ATLASSERT(::IsWindow(m_hWnd));
  634. return ::SetScrollPos(m_hWnd, nBar, nPos, bRedraw);
  635. }
  636. BOOL SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
  637. {
  638. ATLASSERT(::IsWindow(m_hWnd));
  639. return ::SetScrollRange(m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
  640. }
  641. BOOL ShowScrollBar(UINT nBar, BOOL bShow = TRUE)
  642. {
  643. ATLASSERT(::IsWindow(m_hWnd));
  644. return ::ShowScrollBar(m_hWnd, nBar, bShow);
  645. }
  646. BOOL EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH)
  647. {
  648. ATLASSERT(::IsWindow(m_hWnd));
  649. return ::EnableScrollBar(m_hWnd, uSBFlags, uArrowFlags);
  650. }
  651. // Window Access Functions
  652. HWND ChildWindowFromPoint(POINT point) const
  653. {
  654. ATLASSERT(::IsWindow(m_hWnd));
  655. return ::ChildWindowFromPoint(m_hWnd, point);
  656. }
  657. HWND ChildWindowFromPointEx(POINT point, UINT uFlags) const
  658. {
  659. ATLASSERT(::IsWindow(m_hWnd));
  660. return ::ChildWindowFromPointEx(m_hWnd, point, uFlags);
  661. }
  662. HWND GetTopWindow() const
  663. {
  664. ATLASSERT(::IsWindow(m_hWnd));
  665. return ::GetTopWindow(m_hWnd);
  666. }
  667. HWND GetWindow(UINT nCmd) const
  668. {
  669. ATLASSERT(::IsWindow(m_hWnd));
  670. return ::GetWindow(m_hWnd, nCmd);
  671. }
  672. HWND GetLastActivePopup() const
  673. {
  674. ATLASSERT(::IsWindow(m_hWnd));
  675. return ::GetLastActivePopup(m_hWnd);
  676. }
  677. BOOL IsChild(HWND hWnd) const
  678. {
  679. ATLASSERT(::IsWindow(m_hWnd));
  680. return ::IsChild(m_hWnd, hWnd);
  681. }
  682. HWND GetParent() const
  683. {
  684. ATLASSERT(::IsWindow(m_hWnd));
  685. return ::GetParent(m_hWnd);
  686. }
  687. HWND SetParent(HWND hWndNewParent)
  688. {
  689. ATLASSERT(::IsWindow(m_hWnd));
  690. return ::SetParent(m_hWnd, hWndNewParent);
  691. }
  692. // Window Tree Access
  693. int GetDlgCtrlID() const
  694. {
  695. ATLASSERT(::IsWindow(m_hWnd));
  696. return ::GetDlgCtrlID(m_hWnd);
  697. }
  698. int SetDlgCtrlID(int nID)
  699. {
  700. ATLASSERT(::IsWindow(m_hWnd));
  701. return (int)::SetWindowLong(m_hWnd, GWL_ID, nID);
  702. }
  703. HWND GetDlgItem(int nID) const
  704. {
  705. ATLASSERT(::IsWindow(m_hWnd));
  706. return ::GetDlgItem(m_hWnd, nID);
  707. }
  708. // Alert Functions
  709. BOOL FlashWindow(BOOL bInvert)
  710. {
  711. ATLASSERT(::IsWindow(m_hWnd));
  712. return ::FlashWindow(m_hWnd, bInvert);
  713. }
  714. int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = _T(""), UINT nType = MB_OK)
  715. {
  716. ATLASSERT(::IsWindow(m_hWnd));
  717. return ::MessageBox(m_hWnd, lpszText, lpszCaption, nType);
  718. }
  719. // Clipboard Functions
  720. BOOL ChangeClipboardChain(HWND hWndNewNext)
  721. {
  722. ATLASSERT(::IsWindow(m_hWnd));
  723. return ::ChangeClipboardChain(m_hWnd, hWndNewNext);
  724. }
  725. HWND SetClipboardViewer()
  726. {
  727. ATLASSERT(::IsWindow(m_hWnd));
  728. return ::SetClipboardViewer(m_hWnd);
  729. }
  730. BOOL OpenClipboard()
  731. {
  732. ATLASSERT(::IsWindow(m_hWnd));
  733. return ::OpenClipboard(m_hWnd);
  734. }
  735. // Caret Functions
  736. BOOL CreateCaret(HBITMAP hBitmap)
  737. {
  738. ATLASSERT(::IsWindow(m_hWnd));
  739. return ::CreateCaret(m_hWnd, hBitmap, 0, 0);
  740. }
  741. BOOL CreateSolidCaret(int nWidth, int nHeight)
  742. {
  743. ATLASSERT(::IsWindow(m_hWnd));
  744. return ::CreateCaret(m_hWnd, (HBITMAP)0, nWidth, nHeight);
  745. }
  746. BOOL CreateGrayCaret(int nWidth, int nHeight)
  747. {
  748. ATLASSERT(::IsWindow(m_hWnd));
  749. return ::CreateCaret(m_hWnd, (HBITMAP)1, nWidth, nHeight);
  750. }
  751. BOOL HideCaret()
  752. {
  753. ATLASSERT(::IsWindow(m_hWnd));
  754. return ::HideCaret(m_hWnd);
  755. }
  756. BOOL ShowCaret()
  757. {
  758. ATLASSERT(::IsWindow(m_hWnd));
  759. return ::ShowCaret(m_hWnd);
  760. }
  761. #ifdef _INC_SHELLAPI
  762. // Drag-Drop Functions
  763. void DragAcceptFiles(BOOL bAccept = TRUE)
  764. {
  765. ATLASSERT(::IsWindow(m_hWnd)); ::DragAcceptFiles(m_hWnd, bAccept);
  766. }
  767. #endif
  768. // Icon Functions
  769. HICON SetIcon(HICON hIcon, BOOL bBigIcon = TRUE)
  770. {
  771. ATLASSERT(::IsWindow(m_hWnd));
  772. return (HICON)::SendMessage(m_hWnd, WM_SETICON, bBigIcon, (LPARAM)hIcon);
  773. }
  774. HICON GetIcon(BOOL bBigIcon = TRUE) const
  775. {
  776. ATLASSERT(::IsWindow(m_hWnd));
  777. return (HICON)::SendMessage(m_hWnd, WM_GETICON, bBigIcon, 0);
  778. }
  779. // Help Functions
  780. BOOL WinHelp(LPCTSTR lpszHelp, UINT nCmd = HELP_CONTEXT, DWORD dwData = 0)
  781. {
  782. ATLASSERT(::IsWindow(m_hWnd));
  783. return ::WinHelp(m_hWnd, lpszHelp, nCmd, dwData);
  784. }
  785. BOOL SetWindowContextHelpId(DWORD dwContextHelpId)
  786. {
  787. ATLASSERT(::IsWindow(m_hWnd));
  788. return ::SetWindowContextHelpId(m_hWnd, dwContextHelpId);
  789. }
  790. DWORD GetWindowContextHelpId() const
  791. {
  792. ATLASSERT(::IsWindow(m_hWnd));
  793. return ::GetWindowContextHelpId(m_hWnd);
  794. }
  795. // Hot Key Functions
  796. int SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
  797. {
  798. ATLASSERT(::IsWindow(m_hWnd));
  799. return (int)::SendMessage(m_hWnd, WM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0);
  800. }
  801. DWORD GetHotKey() const
  802. {
  803. ATLASSERT(::IsWindow(m_hWnd));
  804. return (DWORD)::SendMessage(m_hWnd, WM_GETHOTKEY, 0, 0);
  805. }
  806. // Misc. Operations
  807. //N new
  808. BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo)
  809. {
  810. ATLASSERT(::IsWindow(m_hWnd));
  811. return ::GetScrollInfo(m_hWnd, nBar, lpScrollInfo);
  812. }
  813. BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
  814. {
  815. ATLASSERT(::IsWindow(m_hWnd));
  816. return ::SetScrollInfo(m_hWnd, nBar, lpScrollInfo, bRedraw);
  817. }
  818. BOOL IsDialogMessage(LPMSG lpMsg)
  819. {
  820. ATLASSERT(::IsWindow(m_hWnd));
  821. return ::IsDialogMessage(m_hWnd, lpMsg);
  822. }
  823. void NextDlgCtrl() const
  824. {
  825. ATLASSERT(::IsWindow(m_hWnd));
  826. ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0L);
  827. }
  828. void PrevDlgCtrl() const
  829. {
  830. ATLASSERT(::IsWindow(m_hWnd));
  831. ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 1, 0L);
  832. }
  833. void GotoDlgCtrl(HWND hWndCtrl) const
  834. {
  835. ATLASSERT(::IsWindow(m_hWnd));
  836. ::SendMessage(m_hWnd, WM_NEXTDLGCTL, (WPARAM)hWndCtrl, 1L);
  837. }
  838. BOOL ResizeClient(int nWidth, int nHeight, BOOL bRedraw = TRUE)
  839. {
  840. ATLASSERT(::IsWindow(m_hWnd));
  841. RECT rcWnd;
  842. if(!GetClientRect(&rcWnd))
  843. return FALSE;
  844. if(nWidth != -1)
  845. rcWnd.right = nWidth;
  846. if(nHeight != -1)
  847. rcWnd.bottom = nHeight;
  848. if(!::AdjustWindowRectEx(&rcWnd, GetStyle(), (!(GetStyle() & WS_CHILD) && (GetMenu() != NULL)), GetExStyle()))
  849. return FALSE;
  850. UINT uFlags = SWP_NOZORDER | SWP_NOMOVE;
  851. if(!bRedraw)
  852. uFlags |= SWP_NOREDRAW;
  853. return SetWindowPos(NULL, 0, 0, rcWnd.right - rcWnd.left, rcWnd.bottom - rcWnd.top, uFlags);
  854. }
  855. int GetWindowRgn(HRGN hRgn)
  856. {
  857. ATLASSERT(::IsWindow(m_hWnd));
  858. return ::GetWindowRgn(m_hWnd, hRgn);
  859. }
  860. int SetWindowRgn(HRGN hRgn, BOOL bRedraw = FALSE)
  861. {
  862. ATLASSERT(::IsWindow(m_hWnd));
  863. return ::SetWindowRgn(m_hWnd, hRgn, bRedraw);
  864. }
  865. HDWP DeferWindowPos(HDWP hWinPosInfo, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags)
  866. {
  867. ATLASSERT(::IsWindow(m_hWnd));
  868. return ::DeferWindowPos(hWinPosInfo, m_hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
  869. }
  870. DWORD GetWindowThreadID()
  871. {
  872. ATLASSERT(::IsWindow(m_hWnd));
  873. return ::GetWindowThreadProcessId(m_hWnd, NULL);
  874. }
  875. DWORD GetWindowProcessID()
  876. {
  877. ATLASSERT(::IsWindow(m_hWnd));
  878. DWORD dwProcessID;
  879. ::GetWindowThreadProcessId(m_hWnd, &dwProcessID);
  880. return dwProcessID;
  881. }
  882. BOOL IsWindow()
  883. {
  884. return ::IsWindow(m_hWnd);
  885. }
  886. BOOL IsWindowUnicode()
  887. {
  888. ATLASSERT(::IsWindow(m_hWnd));
  889. return ::IsWindowUnicode(m_hWnd);
  890. }
  891. BOOL IsParentDialog()
  892. {
  893. ATLASSERT(::IsWindow(m_hWnd));
  894. TCHAR szBuf[8]; // "#32770" + NUL character
  895. GetClassName(GetParent(), szBuf, sizeof(szBuf)/sizeof(TCHAR));
  896. return lstrcmp(szBuf, _T("#32770")) == 0;
  897. }
  898. BOOL ShowWindowAsync(int nCmdShow)
  899. {
  900. ATLASSERT(::IsWindow(m_hWnd));
  901. return ::ShowWindowAsync(m_hWnd, nCmdShow);
  902. }
  903. HWND GetDescendantWindow(int nID) const
  904. {
  905. ATLASSERT(::IsWindow(m_hWnd));
  906. // GetDlgItem recursive (return first found)
  907. // breadth-first for 1 level, then depth-first for next level
  908. // use GetDlgItem since it is a fast USER function
  909. HWND hWndChild, hWndTmp;
  910. CWindow wnd;
  911. if((hWndChild = ::GetDlgItem(m_hWnd, nID)) != NULL)
  912. {
  913. if(::GetTopWindow(hWndChild) != NULL)
  914. {
  915. // children with the same ID as their parent have priority
  916. wnd.Attach(hWndChild);
  917. hWndTmp = wnd.GetDescendantWindow(nID);
  918. if(hWndTmp != NULL)
  919. return hWndTmp;
  920. }
  921. return hWndChild;
  922. }
  923. // walk each child
  924. for(hWndChild = ::GetTopWindow(m_hWnd); hWndChild != NULL;
  925. hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
  926. {
  927. wnd.Attach(hWndChild);
  928. hWndTmp = wnd.GetDescendantWindow(nID);
  929. if(hWndTmp != NULL)
  930. return hWndTmp;
  931. }
  932. return NULL; // not found
  933. }
  934. void SendMessageToDescendants(UINT message, WPARAM wParam = 0, LPARAM lParam = 0, BOOL bDeep = TRUE)
  935. {
  936. CWindow wnd;
  937. for(HWND hWndChild = ::GetTopWindow(m_hWnd); hWndChild != NULL;
  938. hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
  939. {
  940. ::SendMessage(hWndChild, message, wParam, lParam);
  941. if(bDeep && ::GetTopWindow(hWndChild) != NULL)
  942. {
  943. // send to child windows after parent
  944. wnd.Attach(hWndChild);
  945. wnd.SendMessageToDescendants(message, wParam, lParam, bDeep);
  946. }
  947. }
  948. }
  949. BOOL CenterWindow(HWND hWndCenter = NULL)
  950. {
  951. ATLASSERT(::IsWindow(m_hWnd));
  952. // determine owner window to center against
  953. DWORD dwStyle = GetStyle();
  954. if(hWndCenter == NULL)
  955. {
  956. if(dwStyle & WS_CHILD)
  957. hWndCenter = ::GetParent(m_hWnd);
  958. else
  959. hWndCenter = ::GetWindow(m_hWnd, GW_OWNER);
  960. }
  961. // get coordinates of the window relative to its parent
  962. RECT rcDlg;
  963. ::GetWindowRect(m_hWnd, &rcDlg);
  964. RECT rcArea;
  965. RECT rcCenter;
  966. HWND hWndParent;
  967. if(!(dwStyle & WS_CHILD))
  968. {
  969. // don't center against invisible or minimized windows
  970. if(hWndCenter != NULL)
  971. {
  972. DWORD L_dwStyle = ::GetWindowLong(hWndCenter, GWL_STYLE);
  973. if(!(L_dwStyle & WS_VISIBLE) || (L_dwStyle & WS_MINIMIZE))
  974. hWndCenter = NULL;
  975. }
  976. // center within screen coordinates
  977. ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
  978. if(hWndCenter == NULL)
  979. rcCenter = rcArea;
  980. else
  981. ::GetWindowRect(hWndCenter, &rcCenter);
  982. }
  983. else
  984. {
  985. // center within parent client coordinates
  986. hWndParent = ::GetParent(m_hWnd);
  987. ATLASSERT(::IsWindow(hWndParent));
  988. ::GetClientRect(hWndParent, &rcArea);
  989. ATLASSERT(::IsWindow(hWndCenter));
  990. ::GetClientRect(hWndCenter, &rcCenter);
  991. ::MapWindowPoints(hWndCenter, hWndParent, (POINT*)&rcCenter, 2);
  992. }
  993. int DlgWidth = rcDlg.right - rcDlg.left;
  994. int DlgHeight = rcDlg.bottom - rcDlg.top;
  995. // find dialog's upper left based on rcCenter
  996. int xLeft = (rcCenter.left + rcCenter.right) / 2 - DlgWidth / 2;
  997. int yTop = (rcCenter.top + rcCenter.bottom) / 2 - DlgHeight / 2;
  998. // if the dialog is outside the screen, move it inside
  999. if(xLeft < rcArea.left)
  1000. xLeft = rcArea.left;
  1001. else if(xLeft + DlgWidth > rcArea.right)
  1002. xLeft = rcArea.right - DlgWidth;
  1003. if(yTop < rcArea.top)
  1004. yTop = rcArea.top;
  1005. else if(yTop + DlgHeight > rcArea.bottom)
  1006. yTop = rcArea.bottom - DlgHeight;
  1007. // map screen coordinates to child coordinates
  1008. return ::SetWindowPos(m_hWnd, NULL, xLeft, yTop, -1, -1,
  1009. SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  1010. }
  1011. BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0)
  1012. {
  1013. ATLASSERT(::IsWindow(m_hWnd));
  1014. DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
  1015. DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
  1016. if(dwStyle == dwNewStyle)
  1017. return FALSE;
  1018. ::SetWindowLong(m_hWnd, GWL_STYLE, dwNewStyle);
  1019. if(nFlags != 0)
  1020. {
  1021. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0,
  1022. SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
  1023. }
  1024. return TRUE;
  1025. }
  1026. BOOL ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0)
  1027. {
  1028. ATLASSERT(::IsWindow(m_hWnd));
  1029. DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
  1030. DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
  1031. if(dwStyle == dwNewStyle)
  1032. return FALSE;
  1033. ::SetWindowLong(m_hWnd, GWL_EXSTYLE, dwNewStyle);
  1034. if(nFlags != 0)
  1035. {
  1036. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0,
  1037. SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
  1038. }
  1039. return TRUE;
  1040. }
  1041. BOOL GetWindowText(BSTR* pbstrText)
  1042. {
  1043. return GetWindowText(*pbstrText);
  1044. }
  1045. BOOL GetWindowText(BSTR& bstrText)
  1046. {
  1047. USES_CONVERSION;
  1048. ATLASSERT(::IsWindow(m_hWnd));
  1049. if (bstrText != NULL)
  1050. {
  1051. SysFreeString(bstrText);
  1052. bstrText = NULL;
  1053. }
  1054. int nLen = ::GetWindowTextLength(m_hWnd);
  1055. if(nLen == 0)
  1056. {
  1057. bstrText = ::SysAllocString(OLESTR(""));
  1058. return (bstrText != NULL) ? TRUE : FALSE;
  1059. }
  1060. LPTSTR lpszText = (LPTSTR)_alloca((nLen+1)*sizeof(TCHAR));
  1061. if(!::GetWindowText(m_hWnd, lpszText, nLen+1))
  1062. return FALSE;
  1063. bstrText = ::SysAllocString(T2OLE(lpszText));
  1064. return (bstrText != NULL) ? TRUE : FALSE;
  1065. }
  1066. HWND GetTopLevelParent() const
  1067. {
  1068. ATLASSERT(::IsWindow(m_hWnd));
  1069. HWND hWndParent = m_hWnd;
  1070. HWND hWndTmp;
  1071. while((hWndTmp = ::GetParent(hWndParent)) != NULL)
  1072. hWndParent = hWndTmp;
  1073. return hWndParent;
  1074. }
  1075. HWND GetTopLevelWindow() const
  1076. {
  1077. ATLASSERT(::IsWindow(m_hWnd));
  1078. HWND hWndParent;
  1079. HWND hWndTmp = m_hWnd;
  1080. do
  1081. {
  1082. hWndParent = hWndTmp;
  1083. hWndTmp = (::GetWindowLong(hWndParent, GWL_STYLE) & WS_CHILD) ? ::GetParent(hWndParent) : ::GetWindow(hWndParent, GW_OWNER);
  1084. }
  1085. while(hWndTmp != NULL);
  1086. return hWndParent;
  1087. }
  1088. };
  1089. _declspec(selectany) RECT CWindow::rcDefault = { CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 };
  1090. /////////////////////////////////////////////////////////////////////////////
  1091. // CAxWindow - client side for an ActiveX host window
  1092. #ifndef _ATL_NO_HOSTING
  1093. template <class TBase /* = CWindow */>
  1094. class CAxWindowT : public TBase
  1095. {
  1096. public:
  1097. // Constructors
  1098. CAxWindowT(HWND hWnd = NULL) : TBase(hWnd)
  1099. { }
  1100. CAxWindowT< TBase >& operator=(HWND hWnd)
  1101. {
  1102. m_hWnd = hWnd;
  1103. return *this;
  1104. }
  1105. // Attributes
  1106. static LPCTSTR GetWndClassName()
  1107. {
  1108. return _T("AtlAxWin");
  1109. }
  1110. // Operations
  1111. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  1112. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  1113. UINT nID = 0, LPVOID lpCreateParam = NULL)
  1114. {
  1115. return CWindow::Create(GetWndClassName(), hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  1116. }
  1117. HWND Create(HWND hWndParent, LPRECT lpRect = NULL, LPCTSTR szWindowName = NULL,
  1118. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  1119. HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
  1120. {
  1121. return CWindow::Create(GetWndClassName(), hWndParent, lpRect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
  1122. }
  1123. HRESULT CreateControl(LPCOLESTR lpszName, IStream* pStream = NULL, IUnknown** ppUnkContainer = NULL)
  1124. {
  1125. ATLASSERT(::IsWindow(m_hWnd));
  1126. return AtlAxCreateControl(lpszName, m_hWnd, pStream, ppUnkContainer);
  1127. }
  1128. HRESULT CreateControl(DWORD dwResID, IStream* pStream = NULL, IUnknown** ppUnkContainer = NULL)
  1129. {
  1130. TCHAR szModule[_MAX_PATH];
  1131. DWORD len = GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
  1132. if (0 == len || (sizeof szModule / sizeof szModule[0]) == len)
  1133. { // GetModuleFileName failed
  1134. return HRESULT_FROM_WIN32(::GetLastError());
  1135. }
  1136. CComBSTR bstrURL(OLESTR("res://"));
  1137. bstrURL.Append(szModule);
  1138. bstrURL.Append(OLESTR("/"));
  1139. TCHAR szResID[11];
  1140. wsprintf(szResID, _T("%0d"), dwResID);
  1141. bstrURL.Append(szResID);
  1142. ATLASSERT(::IsWindow(m_hWnd));
  1143. return AtlAxCreateControl(bstrURL, m_hWnd, pStream, ppUnkContainer);
  1144. }
  1145. HRESULT CreateControlEx(LPCOLESTR lpszName, IStream* pStream = NULL,
  1146. IUnknown** ppUnkContainer = NULL, IUnknown** ppUnkControl = NULL,
  1147. REFIID iidSink = IID_NULL, IUnknown* punkSink = NULL)
  1148. {
  1149. ATLASSERT(::IsWindow(m_hWnd));
  1150. return AtlAxCreateControlEx(lpszName, m_hWnd, pStream, ppUnkContainer, ppUnkControl, iidSink, punkSink);
  1151. }
  1152. HRESULT CreateControlEx(DWORD dwResID, IStream* pStream = NULL,
  1153. IUnknown** ppUnkContainer = NULL, IUnknown** ppUnkControl = NULL,
  1154. REFIID iidSink = IID_NULL, IUnknown* punkSink = NULL)
  1155. {
  1156. TCHAR szModule[_MAX_PATH];
  1157. DWORD len = GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
  1158. if (0 == len || (sizeof szModule / sizeof szModule[0]) == len)
  1159. { // GetModuleFileName failed
  1160. return HRESULT_FROM_WIN32(::GetLastError());
  1161. }
  1162. CComBSTR bstrURL(OLESTR("res://"));
  1163. bstrURL.Append(szModule);
  1164. bstrURL.Append(OLESTR("/"));
  1165. TCHAR szResID[11];
  1166. wsprintf(szResID, _T("%0d"), dwResID);
  1167. bstrURL.Append(szResID);
  1168. ATLASSERT(::IsWindow(m_hWnd));
  1169. return AtlAxCreateControlEx(bstrURL, m_hWnd, pStream, ppUnkContainer, ppUnkControl, iidSink, punkSink);
  1170. }
  1171. HRESULT AttachControl(IUnknown* pControl, IUnknown** ppUnkContainer)
  1172. {
  1173. ATLASSERT(::IsWindow(m_hWnd));
  1174. return AtlAxAttachControl(pControl, m_hWnd, ppUnkContainer);
  1175. }
  1176. HRESULT QueryHost(REFIID iid, void** ppUnk)
  1177. {
  1178. ATLASSERT(ppUnk != NULL);
  1179. HRESULT hr;
  1180. if (NULL == ppUnk)
  1181. {
  1182. return E_POINTER;
  1183. }
  1184. *ppUnk = NULL;
  1185. CComPtr<IUnknown> spUnk;
  1186. hr = AtlAxGetHost(m_hWnd, &spUnk);
  1187. if (SUCCEEDED(hr))
  1188. hr = spUnk->QueryInterface(iid, ppUnk);
  1189. return hr;
  1190. }
  1191. template <class Q>
  1192. HRESULT QueryHost(Q** ppUnk)
  1193. {
  1194. return QueryHost(__uuidof(Q), (void**)ppUnk);
  1195. }
  1196. HRESULT QueryControl(REFIID iid, void** ppUnk)
  1197. {
  1198. ATLASSERT(ppUnk != NULL);
  1199. HRESULT hr;
  1200. if (NULL == ppUnk)
  1201. {
  1202. return E_POINTER;
  1203. }
  1204. *ppUnk = NULL;
  1205. CComPtr<IUnknown> spUnk;
  1206. hr = AtlAxGetControl(m_hWnd, &spUnk);
  1207. if (SUCCEEDED(hr))
  1208. hr = spUnk->QueryInterface(iid, ppUnk);
  1209. return hr;
  1210. }
  1211. template <class Q>
  1212. HRESULT QueryControl(Q** ppUnk)
  1213. {
  1214. return QueryControl(__uuidof(Q), (void**)ppUnk);
  1215. }
  1216. HRESULT SetExternalDispatch(IDispatch* pDisp)
  1217. {
  1218. HRESULT hr;
  1219. CComPtr<IAxWinHostWindow> spHost;
  1220. hr = QueryHost(IID_IAxWinHostWindow, (void**)&spHost);
  1221. if (SUCCEEDED(hr))
  1222. hr = spHost->SetExternalDispatch(pDisp);
  1223. return hr;
  1224. }
  1225. HRESULT SetExternalUIHandler(IDocHostUIHandlerDispatch* pUIHandler)
  1226. {
  1227. HRESULT hr;
  1228. CComPtr<IAxWinHostWindow> spHost;
  1229. hr = QueryHost(IID_IAxWinHostWindow, (void**)&spHost);
  1230. if (SUCCEEDED(hr))
  1231. hr = spHost->SetExternalUIHandler(pUIHandler);
  1232. return hr;
  1233. }
  1234. };
  1235. typedef CAxWindowT<CWindow> CAxWindow;
  1236. #endif //_ATL_NO_HOSTING
  1237. /////////////////////////////////////////////////////////////////////////////
  1238. // WindowProc thunks
  1239. class CWndProcThunk
  1240. {
  1241. public:
  1242. _AtlCreateWndData cd;
  1243. CStdCallThunk thunk;
  1244. void Init(WNDPROC proc, void* pThis)
  1245. {
  1246. thunk.Init((DWORD_PTR)proc, pThis);
  1247. }
  1248. };
  1249. /////////////////////////////////////////////////////////////////////////////
  1250. // CMessageMap - abstract class that provides an interface for message maps
  1251. class ATL_NO_VTABLE CMessageMap
  1252. {
  1253. public:
  1254. virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
  1255. LRESULT& lResult, DWORD dwMsgMapID) = 0;
  1256. };
  1257. /////////////////////////////////////////////////////////////////////////////
  1258. // Message map
  1259. #define BEGIN_MSG_MAP(theClass) \
  1260. public: \
  1261. BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \
  1262. { \
  1263. BOOL bHandled = TRUE; \
  1264. hWnd; \
  1265. uMsg; \
  1266. wParam; \
  1267. lParam; \
  1268. lResult; \
  1269. bHandled; \
  1270. switch(dwMsgMapID) \
  1271. { \
  1272. case 0:
  1273. #define ALT_MSG_MAP(msgMapID) \
  1274. break; \
  1275. case msgMapID:
  1276. #define MESSAGE_HANDLER(msg, func) \
  1277. if(uMsg == msg) \
  1278. { \
  1279. bHandled = TRUE; \
  1280. lResult = func(uMsg, wParam, lParam, bHandled); \
  1281. if(bHandled) \
  1282. return TRUE; \
  1283. }
  1284. #define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func) \
  1285. if(uMsg >= msgFirst && uMsg <= msgLast) \
  1286. { \
  1287. bHandled = TRUE; \
  1288. lResult = func(uMsg, wParam, lParam, bHandled); \
  1289. if(bHandled) \
  1290. return TRUE; \
  1291. }
  1292. #define COMMAND_HANDLER(id, code, func) \
  1293. if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
  1294. { \
  1295. bHandled = TRUE; \
  1296. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  1297. if(bHandled) \
  1298. return TRUE; \
  1299. }
  1300. #define COMMAND_ID_HANDLER(id, func) \
  1301. if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
  1302. { \
  1303. bHandled = TRUE; \
  1304. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  1305. if(bHandled) \
  1306. return TRUE; \
  1307. }
  1308. #define COMMAND_CODE_HANDLER(code, func) \
  1309. if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \
  1310. { \
  1311. bHandled = TRUE; \
  1312. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  1313. if(bHandled) \
  1314. return TRUE; \
  1315. }
  1316. #define COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
  1317. if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
  1318. { \
  1319. bHandled = TRUE; \
  1320. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  1321. if(bHandled) \
  1322. return TRUE; \
  1323. }
  1324. #define NOTIFY_HANDLER(id, cd, func) \
  1325. if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
  1326. { \
  1327. bHandled = TRUE; \
  1328. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  1329. if(bHandled) \
  1330. return TRUE; \
  1331. }
  1332. #define NOTIFY_ID_HANDLER(id, func) \
  1333. if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
  1334. { \
  1335. bHandled = TRUE; \
  1336. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  1337. if(bHandled) \
  1338. return TRUE; \
  1339. }
  1340. #define NOTIFY_CODE_HANDLER(cd, func) \
  1341. if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
  1342. { \
  1343. bHandled = TRUE; \
  1344. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  1345. if(bHandled) \
  1346. return TRUE; \
  1347. }
  1348. #define NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \
  1349. if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
  1350. { \
  1351. bHandled = TRUE; \
  1352. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  1353. if(bHandled) \
  1354. return TRUE; \
  1355. }
  1356. #define CHAIN_MSG_MAP(theChainClass) \
  1357. { \
  1358. if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
  1359. return TRUE; \
  1360. }
  1361. #define CHAIN_MSG_MAP_MEMBER(theChainMember) \
  1362. { \
  1363. if(theChainMember.ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
  1364. return TRUE; \
  1365. }
  1366. #define CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) \
  1367. { \
  1368. if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
  1369. return TRUE; \
  1370. }
  1371. #define CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) \
  1372. { \
  1373. if(theChainMember.ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
  1374. return TRUE; \
  1375. }
  1376. #define CHAIN_MSG_MAP_DYNAMIC(dynaChainID) \
  1377. { \
  1378. if(CDynamicChain::CallChain(dynaChainID, hWnd, uMsg, wParam, lParam, lResult)) \
  1379. return TRUE; \
  1380. }
  1381. #define END_MSG_MAP() \
  1382. break; \
  1383. default: \
  1384. ATLTRACE2(atlTraceWindowing, 0, _T("Invalid message map ID (%i)\n"), dwMsgMapID); \
  1385. ATLASSERT(FALSE); \
  1386. break; \
  1387. } \
  1388. return FALSE; \
  1389. }
  1390. // Handler prototypes:
  1391. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  1392. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  1393. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  1394. // Empty message map macro
  1395. #define DECLARE_EMPTY_MSG_MAP() \
  1396. public: \
  1397. BOOL ProcessWindowMessage(HWND, UINT, WPARAM, LPARAM, LRESULT&, DWORD) \
  1398. { \
  1399. return FALSE; \
  1400. }
  1401. // Message reflection macros
  1402. #define REFLECT_NOTIFICATIONS() \
  1403. { \
  1404. bHandled = TRUE; \
  1405. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  1406. if(bHandled) \
  1407. return TRUE; \
  1408. }
  1409. #define DEFAULT_REFLECTION_HANDLER() \
  1410. if(DefaultReflectionHandler(hWnd, uMsg, wParam, lParam, lResult)) \
  1411. return TRUE;
  1412. /////////////////////////////////////////////////////////////////////////////
  1413. // CDynamicChain - provides support for dynamic chaining
  1414. class CDynamicChain
  1415. {
  1416. public:
  1417. struct ATL_CHAIN_ENTRY
  1418. {
  1419. DWORD m_dwChainID;
  1420. CMessageMap* m_pObject;
  1421. DWORD m_dwMsgMapID;
  1422. };
  1423. CSimpleArray<ATL_CHAIN_ENTRY*> m_aChainEntry;
  1424. CDynamicChain()
  1425. { }
  1426. ~CDynamicChain()
  1427. {
  1428. for(int i = 0; i < m_aChainEntry.GetSize(); i++)
  1429. {
  1430. if(m_aChainEntry[i] != NULL)
  1431. delete m_aChainEntry[i];
  1432. }
  1433. }
  1434. BOOL SetChainEntry(DWORD dwChainID, CMessageMap* pObject, DWORD dwMsgMapID = 0)
  1435. {
  1436. // first search for an existing entry
  1437. for(int i = 0; i < m_aChainEntry.GetSize(); i++)
  1438. {
  1439. if(m_aChainEntry[i] != NULL && m_aChainEntry[i]->m_dwChainID == dwChainID)
  1440. {
  1441. m_aChainEntry[i]->m_pObject = pObject;
  1442. m_aChainEntry[i]->m_dwMsgMapID = dwMsgMapID;
  1443. return TRUE;
  1444. }
  1445. }
  1446. // create a new one
  1447. ATL_CHAIN_ENTRY* pEntry = NULL;
  1448. ATLTRY(pEntry = new ATL_CHAIN_ENTRY);
  1449. if(pEntry == NULL)
  1450. return FALSE;
  1451. pEntry->m_dwChainID = dwChainID;
  1452. pEntry->m_pObject = pObject;
  1453. pEntry->m_dwMsgMapID = dwMsgMapID;
  1454. // search for an empty one
  1455. for(i = 0; i < m_aChainEntry.GetSize(); i++)
  1456. {
  1457. if(m_aChainEntry[i] == NULL)
  1458. {
  1459. m_aChainEntry[i] = pEntry;
  1460. return TRUE;
  1461. }
  1462. }
  1463. // add a new one
  1464. BOOL bRet = m_aChainEntry.Add(pEntry);
  1465. if(!bRet)
  1466. {
  1467. delete pEntry;
  1468. return FALSE;
  1469. }
  1470. return TRUE;
  1471. }
  1472. BOOL RemoveChainEntry(DWORD dwChainID)
  1473. {
  1474. for(int i = 0; i < m_aChainEntry.GetSize(); i++)
  1475. {
  1476. if(m_aChainEntry[i] != NULL && m_aChainEntry[i]->m_dwChainID == dwChainID)
  1477. {
  1478. delete m_aChainEntry[i];
  1479. m_aChainEntry[i] = NULL;
  1480. return TRUE;
  1481. }
  1482. }
  1483. return FALSE;
  1484. }
  1485. BOOL CallChain(DWORD dwChainID, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult)
  1486. {
  1487. for(int i = 0; i < m_aChainEntry.GetSize(); i++)
  1488. {
  1489. if(m_aChainEntry[i] != NULL && m_aChainEntry[i]->m_dwChainID == dwChainID)
  1490. return (m_aChainEntry[i]->m_pObject)->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, m_aChainEntry[i]->m_dwMsgMapID);
  1491. }
  1492. return FALSE;
  1493. }
  1494. };
  1495. /////////////////////////////////////////////////////////////////////////////
  1496. // CWndClassInfo - Manages Windows class information
  1497. #define DECLARE_WND_CLASS(WndClassName) \
  1498. static CWndClassInfo& GetWndClassInfo() \
  1499. { \
  1500. static CWndClassInfo wc = \
  1501. { \
  1502. { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, StartWindowProc, \
  1503. 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName, NULL }, \
  1504. NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
  1505. }; \
  1506. return wc; \
  1507. }
  1508. #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \
  1509. static CWndClassInfo& GetWndClassInfo() \
  1510. { \
  1511. static CWndClassInfo wc = \
  1512. { \
  1513. { sizeof(WNDCLASSEX), style, StartWindowProc, \
  1514. 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
  1515. NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
  1516. }; \
  1517. return wc; \
  1518. }
  1519. #define DECLARE_WND_SUPERCLASS(WndClassName, OrigWndClassName) \
  1520. static CWndClassInfo& GetWndClassInfo() \
  1521. { \
  1522. static CWndClassInfo wc = \
  1523. { \
  1524. { sizeof(WNDCLASSEX), 0, StartWindowProc, \
  1525. 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \
  1526. OrigWndClassName, NULL, NULL, TRUE, 0, _T("") \
  1527. }; \
  1528. return wc; \
  1529. }
  1530. /////////////////////////////////////////////////////////////////////////////
  1531. // CWinTraits - Defines various default values for a window
  1532. template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0>
  1533. class CWinTraits
  1534. {
  1535. public:
  1536. static DWORD GetWndStyle(DWORD dwStyle)
  1537. {
  1538. return dwStyle == 0 ? t_dwStyle : dwStyle;
  1539. }
  1540. static DWORD GetWndExStyle(DWORD dwExStyle)
  1541. {
  1542. return dwExStyle == 0 ? t_dwExStyle : dwExStyle;
  1543. }
  1544. };
  1545. typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0> CControlWinTraits;
  1546. typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> CFrameWinTraits;
  1547. typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_MDICHILD> CMDIChildWinTraits;
  1548. typedef CWinTraits<0, 0> CNullTraits;
  1549. template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0, class TWinTraits = CControlWinTraits>
  1550. class CWinTraitsOR
  1551. {
  1552. public:
  1553. static DWORD GetWndStyle(DWORD dwStyle)
  1554. {
  1555. return dwStyle | t_dwStyle | TWinTraits::GetWndStyle(dwStyle);
  1556. }
  1557. static DWORD GetWndExStyle(DWORD dwExStyle)
  1558. {
  1559. return dwExStyle | t_dwExStyle | TWinTraits::GetWndExStyle(dwExStyle);
  1560. }
  1561. };
  1562. /////////////////////////////////////////////////////////////////////////////
  1563. // CWindowImpl - Implements a window
  1564. template <class TBase = CWindow>
  1565. class ATL_NO_VTABLE CWindowImplRoot : public TBase, public CMessageMap
  1566. {
  1567. public:
  1568. CWndProcThunk m_thunk;
  1569. const MSG* m_pCurrentMsg;
  1570. // Constructor/destructor
  1571. CWindowImplRoot() : m_pCurrentMsg(NULL)
  1572. { }
  1573. ~CWindowImplRoot()
  1574. {
  1575. #ifdef _DEBUG
  1576. if(m_hWnd != NULL) // should be cleared in WindowProc
  1577. {
  1578. ATLTRACE2(atlTraceWindowing, 0, _T("ERROR - Object deleted before window was destroyed\n"));
  1579. ATLASSERT(FALSE);
  1580. }
  1581. #endif //_DEBUG
  1582. }
  1583. // Current message
  1584. const MSG* GetCurrentMessage() const
  1585. {
  1586. return m_pCurrentMsg;
  1587. }
  1588. // Message reflection support
  1589. LRESULT ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  1590. static BOOL DefaultReflectionHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult);
  1591. };
  1592. template <class TBase>
  1593. LRESULT CWindowImplRoot< TBase >::ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1594. {
  1595. HWND hWndChild = NULL;
  1596. switch(uMsg)
  1597. {
  1598. case WM_COMMAND:
  1599. if(lParam != NULL) // not from a menu
  1600. hWndChild = (HWND)lParam;
  1601. break;
  1602. case WM_NOTIFY:
  1603. hWndChild = ((LPNMHDR)lParam)->hwndFrom;
  1604. break;
  1605. case WM_PARENTNOTIFY:
  1606. switch(LOWORD(wParam))
  1607. {
  1608. case WM_CREATE:
  1609. case WM_DESTROY:
  1610. hWndChild = (HWND)lParam;
  1611. break;
  1612. default:
  1613. hWndChild = GetDlgItem(HIWORD(wParam));
  1614. break;
  1615. }
  1616. break;
  1617. case WM_DRAWITEM:
  1618. if(wParam) // not from a menu
  1619. hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
  1620. break;
  1621. case WM_MEASUREITEM:
  1622. if(wParam) // not from a menu
  1623. hWndChild = GetDlgItem(((LPMEASUREITEMSTRUCT)lParam)->CtlID);
  1624. break;
  1625. case WM_COMPAREITEM:
  1626. if(wParam) // not from a menu
  1627. hWndChild = GetDlgItem(((LPCOMPAREITEMSTRUCT)lParam)->CtlID);
  1628. break;
  1629. case WM_DELETEITEM:
  1630. if(wParam) // not from a menu
  1631. hWndChild = GetDlgItem(((LPDELETEITEMSTRUCT)lParam)->CtlID);
  1632. break;
  1633. case WM_VKEYTOITEM:
  1634. case WM_CHARTOITEM:
  1635. case WM_HSCROLL:
  1636. case WM_VSCROLL:
  1637. hWndChild = (HWND)lParam;
  1638. break;
  1639. case WM_CTLCOLORBTN:
  1640. case WM_CTLCOLORDLG:
  1641. case WM_CTLCOLOREDIT:
  1642. case WM_CTLCOLORLISTBOX:
  1643. case WM_CTLCOLORMSGBOX:
  1644. case WM_CTLCOLORSCROLLBAR:
  1645. case WM_CTLCOLORSTATIC:
  1646. hWndChild = (HWND)lParam;
  1647. break;
  1648. default:
  1649. break;
  1650. }
  1651. if(hWndChild == NULL)
  1652. {
  1653. bHandled = FALSE;
  1654. return 1;
  1655. }
  1656. ATLASSERT(::IsWindow(hWndChild));
  1657. return ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
  1658. }
  1659. template <class TBase>
  1660. BOOL CWindowImplRoot< TBase >::DefaultReflectionHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult)
  1661. {
  1662. switch(uMsg)
  1663. {
  1664. case OCM_COMMAND:
  1665. case OCM_NOTIFY:
  1666. case OCM_PARENTNOTIFY:
  1667. case OCM_DRAWITEM:
  1668. case OCM_MEASUREITEM:
  1669. case OCM_COMPAREITEM:
  1670. case OCM_DELETEITEM:
  1671. case OCM_VKEYTOITEM:
  1672. case OCM_CHARTOITEM:
  1673. case OCM_HSCROLL:
  1674. case OCM_VSCROLL:
  1675. case OCM_CTLCOLORBTN:
  1676. case OCM_CTLCOLORDLG:
  1677. case OCM_CTLCOLOREDIT:
  1678. case OCM_CTLCOLORLISTBOX:
  1679. case OCM_CTLCOLORMSGBOX:
  1680. case OCM_CTLCOLORSCROLLBAR:
  1681. case OCM_CTLCOLORSTATIC:
  1682. lResult = ::DefWindowProc(hWnd, uMsg - OCM__BASE, wParam, lParam);
  1683. return TRUE;
  1684. default:
  1685. break;
  1686. }
  1687. return FALSE;
  1688. }
  1689. template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
  1690. class ATL_NO_VTABLE CWindowImplBaseT : public CWindowImplRoot< TBase >
  1691. {
  1692. public:
  1693. WNDPROC m_pfnSuperWindowProc;
  1694. CWindowImplBaseT() : m_pfnSuperWindowProc(::DefWindowProc)
  1695. {}
  1696. static DWORD GetWndStyle(DWORD dwStyle)
  1697. {
  1698. return TWinTraits::GetWndStyle(dwStyle);
  1699. }
  1700. static DWORD GetWndExStyle(DWORD dwExStyle)
  1701. {
  1702. return TWinTraits::GetWndExStyle(dwExStyle);
  1703. }
  1704. virtual WNDPROC GetWindowProc()
  1705. {
  1706. return WindowProc;
  1707. }
  1708. static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1709. static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1710. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName,
  1711. DWORD dwStyle, DWORD dwExStyle, UINT nID, ATOM atom, LPVOID lpCreateParam = NULL);
  1712. BOOL DestroyWindow()
  1713. {
  1714. ATLASSERT(::IsWindow(m_hWnd));
  1715. return ::DestroyWindow(m_hWnd);
  1716. }
  1717. BOOL SubclassWindow(HWND hWnd);
  1718. HWND UnsubclassWindow(BOOL bForce = FALSE);
  1719. LRESULT DefWindowProc()
  1720. {
  1721. const MSG* pMsg = m_pCurrentMsg;
  1722. LRESULT lRes = 0;
  1723. if (pMsg != NULL)
  1724. lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
  1725. return lRes;
  1726. }
  1727. LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1728. {
  1729. #ifdef STRICT
  1730. return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  1731. #else
  1732. return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  1733. #endif
  1734. }
  1735. virtual void OnFinalMessage(HWND /*hWnd*/)
  1736. {
  1737. // override to do something, if needed
  1738. }
  1739. };
  1740. typedef CWindowImplBaseT<CWindow> CWindowImplBase;
  1741. template <class TBase, class TWinTraits>
  1742. LRESULT CALLBACK CWindowImplBaseT< TBase, TWinTraits >::StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1743. {
  1744. CWindowImplBaseT< TBase, TWinTraits >* pThis = (CWindowImplBaseT< TBase, TWinTraits >*)_Module.ExtractCreateWndData();
  1745. ATLASSERT(pThis != NULL);
  1746. pThis->m_hWnd = hWnd;
  1747. pThis->m_thunk.Init(pThis->GetWindowProc(), pThis);
  1748. WNDPROC pProc = (WNDPROC)(pThis->m_thunk.thunk.pThunk);
  1749. WNDPROC pOldProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LPARAM)pProc);
  1750. #ifdef _DEBUG
  1751. // check if somebody has subclassed us already since we discard it
  1752. if(pOldProc != StartWindowProc)
  1753. ATLTRACE2(atlTraceWindowing, 0, _T("Subclassing through a hook discarded.\n"));
  1754. #else
  1755. pOldProc; // avoid unused warning
  1756. #endif
  1757. return pProc(hWnd, uMsg, wParam, lParam);
  1758. }
  1759. template <class TBase, class TWinTraits>
  1760. LRESULT CALLBACK CWindowImplBaseT< TBase, TWinTraits >::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1761. {
  1762. CWindowImplBaseT< TBase, TWinTraits >* pThis = (CWindowImplBaseT< TBase, TWinTraits >*)hWnd;
  1763. // set a ptr to this message and save the old value
  1764. MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
  1765. const MSG* pOldMsg = pThis->m_pCurrentMsg;
  1766. pThis->m_pCurrentMsg = &msg;
  1767. // pass to the message map to process
  1768. LRESULT lRes;
  1769. BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
  1770. // restore saved value for the current message
  1771. ATLASSERT(pThis->m_pCurrentMsg == &msg);
  1772. pThis->m_pCurrentMsg = pOldMsg;
  1773. // do the default processing if message was not handled
  1774. if(!bRet)
  1775. {
  1776. if(uMsg != WM_NCDESTROY)
  1777. lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  1778. else
  1779. {
  1780. // unsubclass, if needed
  1781. LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
  1782. lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  1783. if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
  1784. ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
  1785. // clear out window handle
  1786. HWND L_hWnd = pThis->m_hWnd;
  1787. pThis->m_hWnd = NULL;
  1788. // clean up after window is destroyed
  1789. pThis->OnFinalMessage(L_hWnd);
  1790. }
  1791. }
  1792. return lRes;
  1793. }
  1794. template <class TBase, class TWinTraits>
  1795. HWND CWindowImplBaseT< TBase, TWinTraits >::Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName,
  1796. DWORD dwStyle, DWORD dwExStyle, UINT nID, ATOM atom, LPVOID lpCreateParam)
  1797. {
  1798. ATLASSERT(m_hWnd == NULL);
  1799. if(atom == 0)
  1800. return NULL;
  1801. _Module.AddCreateWndData(&m_thunk.cd, this);
  1802. if(nID == 0 && (dwStyle & WS_CHILD))
  1803. #if _ATL_VER > 0x0300
  1804. nID = _Module.GetNextWindowID();
  1805. #else
  1806. nID = (UINT)this;
  1807. #endif
  1808. HWND hWnd = ::CreateWindowEx(dwExStyle, (LPCTSTR)(LONG_PTR)MAKELONG(atom, 0), szWindowName,
  1809. dwStyle, rcPos.left, rcPos.top, rcPos.right - rcPos.left,
  1810. rcPos.bottom - rcPos.top, hWndParent, (HMENU)(DWORD_PTR)nID,
  1811. _Module.GetModuleInstance(), lpCreateParam);
  1812. ATLASSERT(m_hWnd == hWnd);
  1813. return hWnd;
  1814. }
  1815. template <class TBase, class TWinTraits>
  1816. BOOL CWindowImplBaseT< TBase, TWinTraits >::SubclassWindow(HWND hWnd)
  1817. {
  1818. ATLASSERT(m_hWnd == NULL);
  1819. ATLASSERT(::IsWindow(hWnd));
  1820. m_thunk.Init(GetWindowProc(), this);
  1821. WNDPROC pProc = (WNDPROC)(m_thunk.thunk.pThunk);
  1822. WNDPROC pfnWndProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LPARAM)pProc);
  1823. if(pfnWndProc == NULL)
  1824. return FALSE;
  1825. m_pfnSuperWindowProc = pfnWndProc;
  1826. m_hWnd = hWnd;
  1827. return TRUE;
  1828. }
  1829. // Use only if you want to subclass before window is destroyed,
  1830. // WindowProc will automatically subclass when window goes away
  1831. template <class TBase, class TWinTraits>
  1832. HWND CWindowImplBaseT< TBase, TWinTraits >::UnsubclassWindow(BOOL bForce /*= FALSE*/)
  1833. {
  1834. ATLASSERT(m_hWnd != NULL);
  1835. WNDPROC pOurProc = (WNDPROC)(m_thunk.thunk.pThunk);
  1836. WNDPROC pActiveProc = (WNDPROC)::GetWindowLongPtr(m_hWnd, GWLP_WNDPROC);
  1837. HWND hWnd = NULL;
  1838. if (bForce || pOurProc == pActiveProc)
  1839. {
  1840. if(!::SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pfnSuperWindowProc))
  1841. return NULL;
  1842. m_pfnSuperWindowProc = ::DefWindowProc;
  1843. hWnd = m_hWnd;
  1844. m_hWnd = NULL;
  1845. }
  1846. return hWnd;
  1847. }
  1848. template <class T, class TBase /* = CWindow */, class TWinTraits /* = CControlWinTraits */>
  1849. class ATL_NO_VTABLE CWindowImpl : public CWindowImplBaseT< TBase, TWinTraits >
  1850. {
  1851. public:
  1852. DECLARE_WND_CLASS(NULL)
  1853. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  1854. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  1855. UINT nID = 0, LPVOID lpCreateParam = NULL)
  1856. {
  1857. if (T::GetWndClassInfo().m_lpszOrigName == NULL)
  1858. T::GetWndClassInfo().m_lpszOrigName = GetWndClassName();
  1859. ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
  1860. dwStyle = T::GetWndStyle(dwStyle);
  1861. dwExStyle = T::GetWndExStyle(dwExStyle);
  1862. return CWindowImplBaseT< TBase, TWinTraits >::Create(hWndParent, rcPos, szWindowName,
  1863. dwStyle, dwExStyle, nID, atom, lpCreateParam);
  1864. }
  1865. };
  1866. /////////////////////////////////////////////////////////////////////////////
  1867. // CDialogImpl - Implements a dialog box
  1868. template <class TBase = CWindow>
  1869. class ATL_NO_VTABLE CDialogImplBaseT : public CWindowImplRoot< TBase >
  1870. {
  1871. public:
  1872. virtual DLGPROC GetDialogProc()
  1873. {
  1874. return DialogProc;
  1875. }
  1876. static INT_PTR CALLBACK StartDialogProc(HWND hWnd, UINT uMsg,
  1877. WPARAM wParam, LPARAM lParam);
  1878. static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1879. BOOL MapDialogRect(LPRECT lpRect)
  1880. {
  1881. ATLASSERT(::IsWindow(m_hWnd));
  1882. return ::MapDialogRect(m_hWnd, lpRect);
  1883. }
  1884. virtual void OnFinalMessage(HWND /*hWnd*/)
  1885. {
  1886. // override to do something, if needed
  1887. }
  1888. // has no meaning for a dialog, but needed for handlers that use it
  1889. LRESULT DefWindowProc()
  1890. {
  1891. return 0;
  1892. }
  1893. };
  1894. template <class TBase>
  1895. INT_PTR CALLBACK CDialogImplBaseT< TBase >::StartDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1896. {
  1897. CDialogImplBaseT< TBase >* pThis = (CDialogImplBaseT< TBase >*)_Module.ExtractCreateWndData();
  1898. ATLASSERT(pThis != NULL);
  1899. pThis->m_hWnd = hWnd;
  1900. pThis->m_thunk.Init((WNDPROC)pThis->GetDialogProc(), pThis);
  1901. DLGPROC pProc = (DLGPROC)(pThis->m_thunk.thunk.pThunk);
  1902. DLGPROC pOldProc = (DLGPROC)::SetWindowLongPtr(hWnd, DWLP_DLGPROC, (LPARAM)pProc);
  1903. #ifdef _DEBUG
  1904. // check if somebody has subclassed us already since we discard it
  1905. if(pOldProc != StartDialogProc)
  1906. ATLTRACE2(atlTraceWindowing, 0, _T("Subclassing through a hook discarded.\n"));
  1907. #else
  1908. pOldProc; // avoid unused warning
  1909. #endif
  1910. return pProc(hWnd, uMsg, wParam, lParam);
  1911. }
  1912. template <class TBase>
  1913. INT_PTR CALLBACK CDialogImplBaseT< TBase >::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1914. {
  1915. CDialogImplBaseT< TBase >* pThis = (CDialogImplBaseT< TBase >*)hWnd;
  1916. // set a ptr to this message and save the old value
  1917. MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
  1918. const MSG* pOldMsg = pThis->m_pCurrentMsg;
  1919. pThis->m_pCurrentMsg = &msg;
  1920. // pass to the message map to process
  1921. LRESULT lRes;
  1922. BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
  1923. // restore saved value for the current message
  1924. ATLASSERT(pThis->m_pCurrentMsg == &msg);
  1925. pThis->m_pCurrentMsg = pOldMsg;
  1926. // set result if message was handled
  1927. if(bRet)
  1928. {
  1929. switch (uMsg)
  1930. {
  1931. case WM_COMPAREITEM:
  1932. case WM_VKEYTOITEM:
  1933. case WM_CHARTOITEM:
  1934. case WM_INITDIALOG:
  1935. case WM_QUERYDRAGICON:
  1936. case WM_CTLCOLORMSGBOX:
  1937. case WM_CTLCOLOREDIT:
  1938. case WM_CTLCOLORLISTBOX:
  1939. case WM_CTLCOLORBTN:
  1940. case WM_CTLCOLORDLG:
  1941. case WM_CTLCOLORSCROLLBAR:
  1942. case WM_CTLCOLORSTATIC:
  1943. return lRes;
  1944. break;
  1945. }
  1946. ::SetWindowLongPtr(pThis->m_hWnd, DWLP_MSGRESULT, lRes);
  1947. return TRUE;
  1948. }
  1949. if(uMsg == WM_NCDESTROY)
  1950. {
  1951. // clear out window handle
  1952. HWND hWnd = pThis->m_hWnd;
  1953. pThis->m_hWnd = NULL;
  1954. // clean up after dialog is destroyed
  1955. pThis->OnFinalMessage(hWnd);
  1956. }
  1957. return FALSE;
  1958. }
  1959. typedef CDialogImplBaseT<CWindow> CDialogImplBase;
  1960. template <class T, class TBase /* = CWindow */>
  1961. class ATL_NO_VTABLE CDialogImpl : public CDialogImplBaseT< TBase >
  1962. {
  1963. public:
  1964. #ifdef _DEBUG
  1965. bool m_bModal;
  1966. CDialogImpl() : m_bModal(false) { }
  1967. #endif //_DEBUG
  1968. // modal dialogs
  1969. INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
  1970. {
  1971. ATLASSERT(m_hWnd == NULL);
  1972. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT< TBase >*)this);
  1973. #ifdef _DEBUG
  1974. m_bModal = true;
  1975. #endif //_DEBUG
  1976. return ::DialogBoxParam(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
  1977. hWndParent, T::StartDialogProc, dwInitParam);
  1978. }
  1979. BOOL EndDialog(INT_PTR nRetCode)
  1980. {
  1981. ATLASSERT(::IsWindow(m_hWnd));
  1982. ATLASSERT(m_bModal); // must be a modal dialog
  1983. return ::EndDialog(m_hWnd, nRetCode);
  1984. }
  1985. // modeless dialogs
  1986. HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
  1987. {
  1988. ATLASSERT(m_hWnd == NULL);
  1989. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT< TBase >*)this);
  1990. #ifdef _DEBUG
  1991. m_bModal = false;
  1992. #endif //_DEBUG
  1993. HWND hWnd = ::CreateDialogParam(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
  1994. hWndParent, T::StartDialogProc, dwInitParam);
  1995. ATLASSERT(m_hWnd == hWnd);
  1996. return hWnd;
  1997. }
  1998. // for CComControl
  1999. HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL)
  2000. {
  2001. return Create(hWndParent, dwInitParam);
  2002. }
  2003. BOOL DestroyWindow()
  2004. {
  2005. ATLASSERT(::IsWindow(m_hWnd));
  2006. ATLASSERT(!m_bModal); // must not be a modal dialog
  2007. return ::DestroyWindow(m_hWnd);
  2008. }
  2009. };
  2010. /////////////////////////////////////////////////////////////////////////////
  2011. // CAxDialogImpl - Implements a dialog box that hosts ActiveX controls
  2012. #ifndef _ATL_NO_HOSTING
  2013. template <class T, class TBase /* = CWindow */>
  2014. class ATL_NO_VTABLE CAxDialogImpl : public CDialogImplBaseT< TBase >
  2015. {
  2016. public:
  2017. #ifdef _DEBUG
  2018. bool m_bModal;
  2019. CAxDialogImpl() : m_bModal(false) { }
  2020. #endif //_DEBUG
  2021. // modal dialogs
  2022. INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
  2023. {
  2024. ATLASSERT(m_hWnd == NULL);
  2025. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT< TBase >*)this);
  2026. #ifdef _DEBUG
  2027. m_bModal = true;
  2028. #endif //_DEBUG
  2029. return AtlAxDialogBox(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
  2030. hWndParent, T::StartDialogProc, dwInitParam);
  2031. }
  2032. BOOL EndDialog(int nRetCode)
  2033. {
  2034. ATLASSERT(::IsWindow(m_hWnd));
  2035. ATLASSERT(m_bModal); // must be a modal dialog
  2036. return ::EndDialog(m_hWnd, nRetCode);
  2037. }
  2038. // modeless dialogs
  2039. HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
  2040. {
  2041. ATLASSERT(m_hWnd == NULL);
  2042. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT< TBase >*)this);
  2043. #ifdef _DEBUG
  2044. m_bModal = false;
  2045. #endif //_DEBUG
  2046. HWND hWnd = AtlAxCreateDialog(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
  2047. hWndParent, T::StartDialogProc, dwInitParam);
  2048. ATLASSERT(m_hWnd == hWnd);
  2049. return hWnd;
  2050. }
  2051. // for CComControl
  2052. HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL)
  2053. {
  2054. return Create(hWndParent, dwInitParam);
  2055. }
  2056. BOOL DestroyWindow()
  2057. {
  2058. ATLASSERT(::IsWindow(m_hWnd));
  2059. ATLASSERT(!m_bModal); // must not be a modal dialog
  2060. return ::DestroyWindow(m_hWnd);
  2061. }
  2062. };
  2063. #endif //_ATL_NO_HOSTING
  2064. /////////////////////////////////////////////////////////////////////////////
  2065. // CSimpleDialog - Prebuilt modal dialog that uses standard buttons
  2066. template <WORD t_wDlgTemplateID, BOOL t_bCenter /* = TRUE */>
  2067. class CSimpleDialog : public CDialogImplBase
  2068. {
  2069. public:
  2070. INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
  2071. {
  2072. ATLASSERT(m_hWnd == NULL);
  2073. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBase*)this);
  2074. INT_PTR nRet = ::DialogBox(_Module.GetResourceInstance(),
  2075. MAKEINTRESOURCE(t_wDlgTemplateID), hWndParent, StartDialogProc);
  2076. m_hWnd = NULL;
  2077. return nRet;
  2078. }
  2079. typedef CSimpleDialog<t_wDlgTemplateID, t_bCenter> thisClass;
  2080. BEGIN_MSG_MAP(thisClass)
  2081. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  2082. COMMAND_RANGE_HANDLER(IDOK, IDNO, OnCloseCmd)
  2083. END_MSG_MAP()
  2084. LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  2085. {
  2086. if(t_bCenter)
  2087. CenterWindow(GetParent());
  2088. return TRUE;
  2089. }
  2090. LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  2091. {
  2092. ::EndDialog(m_hWnd, wID);
  2093. return 0;
  2094. }
  2095. };
  2096. /////////////////////////////////////////////////////////////////////////////
  2097. // CContainedWindow - Implements a contained window
  2098. template <class TBase /* = CWindow */, class TWinTraits /* = CControlWinTraits */>
  2099. class CContainedWindowT : public TBase
  2100. {
  2101. public:
  2102. CWndProcThunk m_thunk;
  2103. LPCTSTR m_lpszClassName;
  2104. WNDPROC m_pfnSuperWindowProc;
  2105. CMessageMap* m_pObject;
  2106. DWORD m_dwMsgMapID;
  2107. const MSG* m_pCurrentMsg;
  2108. // If you use this constructor you must supply
  2109. // the Window Class Name, Object* and Message Map ID
  2110. // Later to the Create call
  2111. CContainedWindowT() : m_pCurrentMsg(NULL)
  2112. { }
  2113. CContainedWindowT(LPTSTR lpszClassName, CMessageMap* pObject, DWORD dwMsgMapID = 0)
  2114. : m_lpszClassName(lpszClassName),
  2115. m_pfnSuperWindowProc(::DefWindowProc),
  2116. m_pObject(pObject), m_dwMsgMapID(dwMsgMapID),
  2117. m_pCurrentMsg(NULL)
  2118. { }
  2119. CContainedWindowT(CMessageMap* pObject, DWORD dwMsgMapID = 0)
  2120. : m_lpszClassName(TBase::GetWndClassName()),
  2121. m_pfnSuperWindowProc(::DefWindowProc),
  2122. m_pObject(pObject), m_dwMsgMapID(dwMsgMapID),
  2123. m_pCurrentMsg(NULL)
  2124. { }
  2125. void SwitchMessageMap(DWORD dwMsgMapID)
  2126. {
  2127. m_dwMsgMapID = dwMsgMapID;
  2128. }
  2129. const MSG* GetCurrentMessage() const
  2130. {
  2131. return m_pCurrentMsg;
  2132. }
  2133. LRESULT DefWindowProc()
  2134. {
  2135. const MSG* pMsg = m_pCurrentMsg;
  2136. LRESULT lRes = 0;
  2137. if (pMsg != NULL)
  2138. lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
  2139. return lRes;
  2140. }
  2141. LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  2142. {
  2143. #ifdef STRICT
  2144. return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  2145. #else
  2146. return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  2147. #endif
  2148. }
  2149. static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg,
  2150. WPARAM wParam, LPARAM lParam)
  2151. {
  2152. CContainedWindowT< TBase >* pThis = (CContainedWindowT< TBase >*)_Module.ExtractCreateWndData();
  2153. ATLASSERT(pThis != NULL);
  2154. pThis->m_hWnd = hWnd;
  2155. pThis->m_thunk.Init(WindowProc, pThis);
  2156. WNDPROC pProc = (WNDPROC)(pThis->m_thunk.thunk.pThunk);
  2157. WNDPROC pOldProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pProc);
  2158. #ifdef _DEBUG
  2159. // check if somebody has subclassed us already since we discard it
  2160. if(pOldProc != StartWindowProc)
  2161. ATLTRACE2(atlTraceWindowing, 0, _T("Subclassing through a hook discarded.\n"));
  2162. #else
  2163. pOldProc; // avoid unused warning
  2164. #endif
  2165. return pProc(hWnd, uMsg, wParam, lParam);
  2166. }
  2167. static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2168. {
  2169. CContainedWindowT< TBase >* pThis = (CContainedWindowT< TBase >*)hWnd;
  2170. ATLASSERT(pThis->m_hWnd != NULL);
  2171. ATLASSERT(pThis->m_pObject != NULL);
  2172. // set a ptr to this message and save the old value
  2173. MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
  2174. const MSG* pOldMsg = pThis->m_pCurrentMsg;
  2175. pThis->m_pCurrentMsg = &msg;
  2176. // pass to the message map to process
  2177. LRESULT lRes;
  2178. BOOL bRet = pThis->m_pObject->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, pThis->m_dwMsgMapID);
  2179. // restore saved value for the current message
  2180. ATLASSERT(pThis->m_pCurrentMsg == &msg);
  2181. pThis->m_pCurrentMsg = pOldMsg;
  2182. // do the default processing if message was not handled
  2183. if(!bRet)
  2184. {
  2185. if(uMsg != WM_NCDESTROY)
  2186. lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  2187. else
  2188. {
  2189. // unsubclass, if needed
  2190. LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
  2191. lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  2192. if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
  2193. ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
  2194. // clear out window handle
  2195. pThis->m_hWnd = NULL;
  2196. }
  2197. }
  2198. return lRes;
  2199. }
  2200. ATOM RegisterWndSuperclass()
  2201. {
  2202. ATOM atom = 0;
  2203. LPTSTR szBuff = (LPTSTR)_alloca((lstrlen(m_lpszClassName) + 14) * sizeof(TCHAR));
  2204. WNDCLASSEX wc;
  2205. wc.cbSize = sizeof(WNDCLASSEX);
  2206. // Try global class
  2207. if(!::GetClassInfoEx(NULL, m_lpszClassName, &wc))
  2208. {
  2209. // try local class
  2210. if(!::GetClassInfoEx(_Module.GetModuleInstance(), m_lpszClassName, &wc))
  2211. return atom;
  2212. }
  2213. m_pfnSuperWindowProc = wc.lpfnWndProc;
  2214. lstrcpy(szBuff, _T("ATL:"));
  2215. lstrcat(szBuff, m_lpszClassName);
  2216. WNDCLASSEX wc1;
  2217. wc1.cbSize = sizeof(WNDCLASSEX);
  2218. atom = (ATOM)::GetClassInfoEx(_Module.GetModuleInstance(), szBuff, &wc1);
  2219. if(atom == 0) // register class
  2220. {
  2221. wc.lpszClassName = szBuff;
  2222. wc.lpfnWndProc = StartWindowProc;
  2223. wc.hInstance = _Module.GetModuleInstance();
  2224. wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
  2225. atom = ::RegisterClassEx(&wc);
  2226. }
  2227. return atom;
  2228. }
  2229. HWND Create(CMessageMap* pObject, DWORD dwMsgMapID, HWND hWndParent, RECT* prcPos,
  2230. LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0,
  2231. UINT nID = 0, LPVOID lpCreateParam = NULL)
  2232. {
  2233. m_lpszClassName = TBase::GetWndClassName();
  2234. m_pfnSuperWindowProc = ::DefWindowProc;
  2235. m_pObject = pObject;
  2236. m_dwMsgMapID = dwMsgMapID;
  2237. return Create(hWndParent, prcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  2238. }
  2239. HWND Create(LPCTSTR lpszClassName, CMessageMap* pObject, DWORD dwMsgMapID, HWND hWndParent, RECT* prcPos, LPCTSTR szWindowName = NULL,
  2240. DWORD dwStyle = 0, DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL)
  2241. {
  2242. m_lpszClassName = lpszClassName;
  2243. m_pfnSuperWindowProc = ::DefWindowProc;
  2244. m_pObject = pObject;
  2245. m_dwMsgMapID = dwMsgMapID;
  2246. return Create(hWndParent, prcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  2247. }
  2248. // This function is Deprecated, use the version
  2249. // which takes a RECT* instead
  2250. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  2251. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  2252. UINT nID = 0, LPVOID lpCreateParam = NULL)
  2253. {
  2254. return Create(hWndParent, &rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  2255. }
  2256. HWND Create(HWND hWndParent, RECT* prcPos, LPCTSTR szWindowName = NULL,
  2257. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  2258. UINT nID = 0, LPVOID lpCreateParam = NULL)
  2259. {
  2260. ATLASSERT(m_hWnd == NULL);
  2261. ATOM atom = RegisterWndSuperclass();
  2262. if(atom == 0)
  2263. return NULL;
  2264. _Module.AddCreateWndData(&m_thunk.cd, this);
  2265. dwStyle = TWinTraits::GetWndStyle(dwStyle);
  2266. dwExStyle = TWinTraits::GetWndExStyle(dwExStyle);
  2267. HWND hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWindowName,
  2268. dwStyle,
  2269. prcPos->left, prcPos->top,
  2270. prcPos->right - prcPos->left,
  2271. prcPos->bottom - prcPos->top,
  2272. hWndParent,
  2273. (nID == 0 && (dwStyle & WS_CHILD)) ? (HMENU)this : (HMENU)(DWORD_PTR)nID,
  2274. _Module.GetModuleInstance(), lpCreateParam);
  2275. ATLASSERT(m_hWnd == hWnd);
  2276. return hWnd;
  2277. }
  2278. BOOL SubclassWindow(HWND hWnd)
  2279. {
  2280. ATLASSERT(m_hWnd == NULL);
  2281. ATLASSERT(::IsWindow(hWnd));
  2282. m_thunk.Init(WindowProc, this);
  2283. WNDPROC pProc = (WNDPROC)m_thunk.thunk.pThunk;
  2284. WNDPROC pfnWndProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pProc);
  2285. if(pfnWndProc == NULL)
  2286. return FALSE;
  2287. m_pfnSuperWindowProc = pfnWndProc;
  2288. m_hWnd = hWnd;
  2289. return TRUE;
  2290. }
  2291. // Use only if you want to subclass before window is destroyed,
  2292. // WindowProc will automatically subclass when window goes away
  2293. HWND UnsubclassWindow(BOOL bForce = FALSE)
  2294. {
  2295. ATLASSERT(m_hWnd != NULL);
  2296. WNDPROC pOurProc = (WNDPROC)(m_thunk.thunk.pThunk);
  2297. WNDPROC pActiveProc = (WNDPROC)::GetWindowLongPtr(m_hWnd, GWLP_WNDPROC);
  2298. HWND hWnd = NULL;
  2299. if (bForce || pOurProc == pActiveProc)
  2300. {
  2301. if(!::SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pfnSuperWindowProc))
  2302. return NULL;
  2303. m_pfnSuperWindowProc = ::DefWindowProc;
  2304. hWnd = m_hWnd;
  2305. m_hWnd = NULL;
  2306. }
  2307. return hWnd;
  2308. }
  2309. };
  2310. typedef CContainedWindowT<CWindow> CContainedWindow;
  2311. /////////////////////////////////////////////////////////////////////////////
  2312. // _DialogSizeHelper - helpers for calculating the size of a dialog template
  2313. class _DialogSizeHelper
  2314. {
  2315. public:
  2316. //local struct used for implementation
  2317. #pragma pack(push, 1)
  2318. struct _ATL_DLGTEMPLATEEX
  2319. {
  2320. WORD dlgVer;
  2321. WORD signature;
  2322. DWORD helpID;
  2323. DWORD exStyle;
  2324. DWORD style;
  2325. WORD cDlgItems;
  2326. short x;
  2327. short y;
  2328. short cx;
  2329. short cy;
  2330. };
  2331. #pragma pack(pop)
  2332. static void GetDialogSize(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  2333. {
  2334. // If the dialog has a font we use it otherwise we default
  2335. // to the system font.
  2336. if (HasFont(pTemplate))
  2337. {
  2338. TCHAR szFace[LF_FACESIZE];
  2339. WORD wFontSize = 0;
  2340. GetFont(pTemplate, szFace, &wFontSize);
  2341. GetSizeInDialogUnits(pTemplate, pSize);
  2342. ConvertDialogUnitsToPixels(szFace, wFontSize, pSize);
  2343. }
  2344. else
  2345. {
  2346. GetSizeInDialogUnits(pTemplate, pSize);
  2347. LONG nDlgBaseUnits = GetDialogBaseUnits();
  2348. pSize->cx = MulDiv(pSize->cx, LOWORD(nDlgBaseUnits), 4);
  2349. pSize->cy = MulDiv(pSize->cy, HIWORD(nDlgBaseUnits), 8);
  2350. }
  2351. }
  2352. static void ConvertDialogUnitsToPixels(LPCTSTR pszFontFace, WORD wFontSize, SIZE* pSizePixel)
  2353. {
  2354. // Attempt to create the font to be used in the dialog box
  2355. UINT cxSysChar, cySysChar;
  2356. LOGFONT lf;
  2357. HDC hDC = ::GetDC(NULL);
  2358. int cxDlg = pSizePixel->cx;
  2359. int cyDlg = pSizePixel->cy;
  2360. ZeroMemory(&lf, sizeof(LOGFONT));
  2361. lf.lfHeight = -MulDiv(wFontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  2362. lf.lfWeight = FW_NORMAL;
  2363. lf.lfCharSet = DEFAULT_CHARSET;
  2364. lstrcpyn(lf.lfFaceName, pszFontFace, sizeof lf.lfFaceName / sizeof lf.lfFaceName[0]);
  2365. HFONT hNewFont = CreateFontIndirect(&lf);
  2366. if (hNewFont != NULL)
  2367. {
  2368. TEXTMETRIC tm;
  2369. SIZE size;
  2370. HFONT hFontOld = (HFONT)SelectObject(hDC, hNewFont);
  2371. GetTextMetrics(hDC, &tm);
  2372. cySysChar = tm.tmHeight + tm.tmExternalLeading;
  2373. ::GetTextExtentPoint(hDC,
  2374. _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52,
  2375. &size);
  2376. cxSysChar = (size.cx + 26) / 52;
  2377. SelectObject(hDC, hFontOld);
  2378. DeleteObject(hNewFont);
  2379. }
  2380. else
  2381. {
  2382. // Could not create the font so just use the system's values
  2383. cxSysChar = LOWORD(GetDialogBaseUnits());
  2384. cySysChar = HIWORD(GetDialogBaseUnits());
  2385. }
  2386. ::ReleaseDC(NULL, hDC);
  2387. // Translate dialog units to pixels
  2388. pSizePixel->cx = MulDiv(cxDlg, cxSysChar, 4);
  2389. pSizePixel->cy = MulDiv(cyDlg, cySysChar, 8);
  2390. }
  2391. static BOOL IsDialogEx(const DLGTEMPLATE* pTemplate)
  2392. {
  2393. return ((_ATL_DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
  2394. }
  2395. static BOOL HasFont(const DLGTEMPLATE* pTemplate)
  2396. {
  2397. return (DS_SETFONT &
  2398. (IsDialogEx(pTemplate) ?
  2399. ((_ATL_DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style));
  2400. }
  2401. static BYTE* GetFontSizeField(const DLGTEMPLATE* pTemplate)
  2402. {
  2403. BOOL bDialogEx = IsDialogEx(pTemplate);
  2404. WORD* pw;
  2405. if (bDialogEx)
  2406. pw = (WORD*)((_ATL_DLGTEMPLATEEX*)pTemplate + 1);
  2407. else
  2408. pw = (WORD*)(pTemplate + 1);
  2409. if (*pw == (WORD)-1) // Skip menu name string or ordinal
  2410. pw += 2; // WORDs
  2411. else
  2412. while(*pw++);
  2413. if (*pw == (WORD)-1) // Skip class name string or ordinal
  2414. pw += 2; // WORDs
  2415. else
  2416. while(*pw++);
  2417. while (*pw++); // Skip caption string
  2418. return (BYTE*)pw;
  2419. }
  2420. static BOOL GetFont(const DLGTEMPLATE* pTemplate, TCHAR* pszFace, WORD* pFontSize)
  2421. {
  2422. USES_CONVERSION;
  2423. if (!HasFont(pTemplate))
  2424. return FALSE;
  2425. BYTE* pb = GetFontSizeField(pTemplate);
  2426. *pFontSize = *(WORD*)pb;
  2427. // Skip over font attributes to get to the font name
  2428. pb += sizeof(WORD) * (IsDialogEx(pTemplate) ? 3 : 1);
  2429. _tcsncpy(pszFace, W2T((WCHAR*)pb), LF_FACESIZE);
  2430. if (_tcslen(pszFace) >= LF_FACESIZE)
  2431. { // NUL not appended
  2432. pszFace[LF_FACESIZE-1] = _T('\0');
  2433. }
  2434. return TRUE;
  2435. }
  2436. static void GetSizeInDialogUnits(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  2437. {
  2438. if (IsDialogEx(pTemplate))
  2439. {
  2440. pSize->cx = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cx;
  2441. pSize->cy = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cy;
  2442. }
  2443. else
  2444. {
  2445. pSize->cx = pTemplate->cx;
  2446. pSize->cy = pTemplate->cy;
  2447. }
  2448. }
  2449. };
  2450. inline void AtlGetDialogSize(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  2451. {
  2452. _DialogSizeHelper::GetDialogSize(pTemplate, pSize);
  2453. }
  2454. }; //namespace ATL
  2455. #ifndef _ATL_DLL_IMPL
  2456. #ifndef _ATL_DLL
  2457. #define _ATLWIN_IMPL
  2458. #endif
  2459. #endif
  2460. #endif // __ATLWIN_H__
  2461. //All exports go here
  2462. #ifdef _ATLWIN_IMPL
  2463. #ifndef _ATL_DLL_IMPL
  2464. namespace ATL
  2465. {
  2466. #endif
  2467. ATLINLINE ATLAPI_(ATOM) AtlModuleRegisterWndClassInfoA(_ATL_MODULE* pM, _ATL_WNDCLASSINFOA* p, WNDPROC* pProc)
  2468. {
  2469. BOOL fFail = FALSE;
  2470. if (p->m_atom == 0)
  2471. {
  2472. ::EnterCriticalSection(&pM->m_csWindowCreate);
  2473. __try
  2474. {
  2475. if(p->m_atom == 0)
  2476. {
  2477. HINSTANCE hInst = pM->m_hInst;
  2478. if (p->m_lpszOrigName != NULL)
  2479. {
  2480. ATLASSERT(pProc != NULL);
  2481. LPCSTR lpsz = p->m_wc.lpszClassName;
  2482. WNDPROC proc = p->m_wc.lpfnWndProc;
  2483. WNDCLASSEXA wc;
  2484. wc.cbSize = sizeof(WNDCLASSEX);
  2485. // Try global class
  2486. if(!::GetClassInfoExA(NULL, p->m_lpszOrigName, &wc))
  2487. {
  2488. // try process local
  2489. if(!::GetClassInfoExA(_Module.GetModuleInstance(), p->m_lpszOrigName, &wc))
  2490. {
  2491. fFail = TRUE;
  2492. __leave;
  2493. }
  2494. }
  2495. memcpy(&p->m_wc, &wc, sizeof(WNDCLASSEX));
  2496. p->pWndProc = p->m_wc.lpfnWndProc;
  2497. p->m_wc.lpszClassName = lpsz;
  2498. p->m_wc.lpfnWndProc = proc;
  2499. }
  2500. else
  2501. {
  2502. p->m_wc.hCursor = ::LoadCursorA(p->m_bSystemCursor ? NULL : hInst,
  2503. p->m_lpszCursorID);
  2504. }
  2505. p->m_wc.hInstance = hInst;
  2506. p->m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
  2507. if (p->m_wc.lpszClassName == NULL)
  2508. {
  2509. #ifdef _WIN64 // %p isn't available on Win2k/Win9x
  2510. wsprintfA(p->m_szAutoName, "ATL:%p", &p->m_wc);
  2511. #else
  2512. wsprintfA(p->m_szAutoName, "ATL:%8.8X", PtrToUlong(&p->m_wc));
  2513. #endif
  2514. p->m_wc.lpszClassName = p->m_szAutoName;
  2515. }
  2516. WNDCLASSEXA wcTemp;
  2517. memcpy(&wcTemp, &p->m_wc, sizeof(WNDCLASSEXW));
  2518. p->m_atom = (ATOM)::GetClassInfoExA(p->m_wc.hInstance, p->m_wc.lpszClassName, &wcTemp);
  2519. if (p->m_atom == 0)
  2520. p->m_atom = ::RegisterClassExA(&p->m_wc);
  2521. }
  2522. }
  2523. __finally
  2524. {
  2525. ::LeaveCriticalSection(&pM->m_csWindowCreate);
  2526. }
  2527. }
  2528. if (fFail)
  2529. {
  2530. return 0;
  2531. }
  2532. if (p->m_lpszOrigName != NULL)
  2533. {
  2534. ATLASSERT(pProc != NULL);
  2535. ATLASSERT(p->pWndProc != NULL);
  2536. *pProc = p->pWndProc;
  2537. }
  2538. return p->m_atom;
  2539. }
  2540. ATLINLINE ATLAPI_(ATOM) AtlModuleRegisterWndClassInfoW(_ATL_MODULE* pM, _ATL_WNDCLASSINFOW* p, WNDPROC* pProc)
  2541. {
  2542. BOOL fFail = FALSE;
  2543. if (p->m_atom == 0)
  2544. {
  2545. ::EnterCriticalSection(&pM->m_csWindowCreate);
  2546. __try
  2547. {
  2548. if(p->m_atom == 0)
  2549. {
  2550. HINSTANCE hInst = pM->m_hInst;
  2551. if (p->m_lpszOrigName != NULL)
  2552. {
  2553. ATLASSERT(pProc != NULL);
  2554. LPCWSTR lpsz = p->m_wc.lpszClassName;
  2555. WNDPROC proc = p->m_wc.lpfnWndProc;
  2556. WNDCLASSEXW wc;
  2557. wc.cbSize = sizeof(WNDCLASSEX);
  2558. // Try global class
  2559. if(!::GetClassInfoExW(NULL, p->m_lpszOrigName, &wc))
  2560. {
  2561. // try process local
  2562. if(!::GetClassInfoExW(_Module.GetModuleInstance(), p->m_lpszOrigName, &wc))
  2563. {
  2564. fFail = TRUE;
  2565. __leave;
  2566. }
  2567. }
  2568. memcpy(&p->m_wc, &wc, sizeof(WNDCLASSEX));
  2569. p->pWndProc = p->m_wc.lpfnWndProc;
  2570. p->m_wc.lpszClassName = lpsz;
  2571. p->m_wc.lpfnWndProc = proc;
  2572. }
  2573. else
  2574. {
  2575. p->m_wc.hCursor = ::LoadCursorW(p->m_bSystemCursor ? NULL : hInst,
  2576. p->m_lpszCursorID);
  2577. }
  2578. p->m_wc.hInstance = hInst;
  2579. p->m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
  2580. if (p->m_wc.lpszClassName == NULL)
  2581. {
  2582. #ifdef _WIN64 // %p isn't available on Win2k/Win9x
  2583. wsprintfW(p->m_szAutoName, L"ATL:%p", &p->m_wc);
  2584. #else
  2585. wsprintfW(p->m_szAutoName, L"ATL:%8.8X", PtrToUlong(&p->m_wc));
  2586. #endif
  2587. p->m_wc.lpszClassName = p->m_szAutoName;
  2588. }
  2589. WNDCLASSEXW wcTemp;
  2590. memcpy(&wcTemp, &p->m_wc, sizeof(WNDCLASSEXW));
  2591. p->m_atom = (ATOM)::GetClassInfoExW(p->m_wc.hInstance, p->m_wc.lpszClassName, &wcTemp);
  2592. if (p->m_atom == 0)
  2593. p->m_atom = ::RegisterClassExW(&p->m_wc);
  2594. }
  2595. }
  2596. __finally
  2597. {
  2598. ::LeaveCriticalSection(&pM->m_csWindowCreate);
  2599. }
  2600. }
  2601. if (fFail)
  2602. {
  2603. return 0;
  2604. }
  2605. if (p->m_lpszOrigName != NULL)
  2606. {
  2607. ATLASSERT(pProc != NULL);
  2608. ATLASSERT(p->pWndProc != NULL);
  2609. *pProc = p->pWndProc;
  2610. }
  2611. return p->m_atom;
  2612. }
  2613. ATLINLINE ATLAPI_(HDC) AtlCreateTargetDC(HDC hdc, DVTARGETDEVICE* ptd)
  2614. {
  2615. USES_CONVERSION;
  2616. // cases hdc, ptd, hdc is metafile, hic
  2617. // NULL, NULL, n/a, Display
  2618. // NULL, !NULL, n/a, ptd
  2619. // !NULL, NULL, FALSE, hdc
  2620. // !NULL, NULL, TRUE, display
  2621. // !NULL, !NULL, FALSE, ptd
  2622. // !NULL, !NULL, TRUE, ptd
  2623. if (ptd != NULL)
  2624. {
  2625. LPDEVMODEOLE lpDevMode;
  2626. LPOLESTR lpszDriverName;
  2627. LPOLESTR lpszDeviceName;
  2628. LPOLESTR lpszPortName;
  2629. if (ptd->tdExtDevmodeOffset == 0)
  2630. lpDevMode = NULL;
  2631. else
  2632. lpDevMode = (LPDEVMODEOLE) ((LPSTR)ptd + ptd->tdExtDevmodeOffset);
  2633. lpszDriverName = (LPOLESTR)((BYTE*)ptd + ptd->tdDriverNameOffset);
  2634. lpszDeviceName = (LPOLESTR)((BYTE*)ptd + ptd->tdDeviceNameOffset);
  2635. lpszPortName = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  2636. return ::CreateDC(OLE2CT(lpszDriverName), OLE2CT(lpszDeviceName),
  2637. OLE2CT(lpszPortName), DEVMODEOLE2T(lpDevMode));
  2638. }
  2639. else if (hdc == NULL || GetDeviceCaps(hdc, TECHNOLOGY) == DT_METAFILE)
  2640. return ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
  2641. else
  2642. return hdc;
  2643. }
  2644. ATLINLINE ATLAPI_(void) AtlHiMetricToPixel(const SIZEL * lpSizeInHiMetric, LPSIZEL lpSizeInPix)
  2645. {
  2646. int nPixelsPerInchX; // Pixels per logical inch along width
  2647. int nPixelsPerInchY; // Pixels per logical inch along height
  2648. HDC hDCScreen = GetDC(NULL);
  2649. ATLASSERT(hDCScreen != NULL);
  2650. if (hDCScreen != NULL)
  2651. {
  2652. nPixelsPerInchX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
  2653. nPixelsPerInchY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
  2654. ReleaseDC(NULL, hDCScreen);
  2655. }
  2656. else
  2657. {
  2658. nPixelsPerInchX = 1;
  2659. nPixelsPerInchY = 1;
  2660. }
  2661. lpSizeInPix->cx = MAP_LOGHIM_TO_PIX(lpSizeInHiMetric->cx, nPixelsPerInchX);
  2662. lpSizeInPix->cy = MAP_LOGHIM_TO_PIX(lpSizeInHiMetric->cy, nPixelsPerInchY);
  2663. }
  2664. ATLINLINE ATLAPI_(void) AtlPixelToHiMetric(const SIZEL * lpSizeInPix, LPSIZEL lpSizeInHiMetric)
  2665. {
  2666. int nPixelsPerInchX; // Pixels per logical inch along width
  2667. int nPixelsPerInchY; // Pixels per logical inch along height
  2668. HDC hDCScreen = GetDC(NULL);
  2669. if (hDCScreen) {
  2670. nPixelsPerInchX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
  2671. nPixelsPerInchY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
  2672. ReleaseDC(NULL, hDCScreen);
  2673. } else {
  2674. nPixelsPerInchX = nPixelsPerInchY = 1;
  2675. }
  2676. lpSizeInHiMetric->cx = MAP_PIX_TO_LOGHIM(lpSizeInPix->cx, nPixelsPerInchX);
  2677. lpSizeInHiMetric->cy = MAP_PIX_TO_LOGHIM(lpSizeInPix->cy, nPixelsPerInchY);
  2678. }
  2679. #ifndef _ATL_DLL_IMPL
  2680. }; //namespace ATL
  2681. #endif
  2682. //Prevent pulling in second time
  2683. #undef _ATLWIN_IMPL
  2684. #endif // _ATLWIN_IMPL