Source code of Windows XP (NT5)
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.

3064 lines
78 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 nIDEvent, UINT nElapse)
  469. {
  470. ATLASSERT(::IsWindow(m_hWnd));
  471. return ::SetTimer(m_hWnd, nIDEvent, nElapse, NULL);
  472. }
  473. BOOL KillTimer(UINT 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. *ppUnk = NULL;
  593. CComPtr<IUnknown> spUnk;
  594. hr = AtlAxGetControl(hWndCtrl, &spUnk);
  595. if (SUCCEEDED(hr))
  596. hr = spUnk->QueryInterface(iid, ppUnk);
  597. }
  598. return hr;
  599. }
  600. #endif //!_ATL_NO_HOSTING
  601. // Scrolling Functions
  602. int GetScrollPos(int nBar) const
  603. {
  604. ATLASSERT(::IsWindow(m_hWnd));
  605. return ::GetScrollPos(m_hWnd, nBar);
  606. }
  607. BOOL GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
  608. {
  609. ATLASSERT(::IsWindow(m_hWnd));
  610. return ::GetScrollRange(m_hWnd, nBar, lpMinPos, lpMaxPos);
  611. }
  612. BOOL ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect = NULL, LPCRECT lpClipRect = NULL)
  613. {
  614. ATLASSERT(::IsWindow(m_hWnd));
  615. return ::ScrollWindow(m_hWnd, xAmount, yAmount, lpRect, lpClipRect);
  616. }
  617. int ScrollWindowEx(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate, UINT uFlags)
  618. {
  619. ATLASSERT(::IsWindow(m_hWnd));
  620. return ::ScrollWindowEx(m_hWnd, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate, uFlags);
  621. }
  622. int ScrollWindowEx(int dx, int dy, UINT uFlags, LPCRECT lpRectScroll = NULL, LPCRECT lpRectClip = NULL, HRGN hRgnUpdate = NULL, LPRECT lpRectUpdate = NULL)
  623. {
  624. ATLASSERT(::IsWindow(m_hWnd));
  625. return ::ScrollWindowEx(m_hWnd, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate, uFlags);
  626. }
  627. int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
  628. {
  629. ATLASSERT(::IsWindow(m_hWnd));
  630. return ::SetScrollPos(m_hWnd, nBar, nPos, bRedraw);
  631. }
  632. BOOL SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
  633. {
  634. ATLASSERT(::IsWindow(m_hWnd));
  635. return ::SetScrollRange(m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
  636. }
  637. BOOL ShowScrollBar(UINT nBar, BOOL bShow = TRUE)
  638. {
  639. ATLASSERT(::IsWindow(m_hWnd));
  640. return ::ShowScrollBar(m_hWnd, nBar, bShow);
  641. }
  642. BOOL EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH)
  643. {
  644. ATLASSERT(::IsWindow(m_hWnd));
  645. return ::EnableScrollBar(m_hWnd, uSBFlags, uArrowFlags);
  646. }
  647. // Window Access Functions
  648. HWND ChildWindowFromPoint(POINT point) const
  649. {
  650. ATLASSERT(::IsWindow(m_hWnd));
  651. return ::ChildWindowFromPoint(m_hWnd, point);
  652. }
  653. HWND ChildWindowFromPointEx(POINT point, UINT uFlags) const
  654. {
  655. ATLASSERT(::IsWindow(m_hWnd));
  656. return ::ChildWindowFromPointEx(m_hWnd, point, uFlags);
  657. }
  658. HWND GetTopWindow() const
  659. {
  660. ATLASSERT(::IsWindow(m_hWnd));
  661. return ::GetTopWindow(m_hWnd);
  662. }
  663. HWND GetWindow(UINT nCmd) const
  664. {
  665. ATLASSERT(::IsWindow(m_hWnd));
  666. return ::GetWindow(m_hWnd, nCmd);
  667. }
  668. HWND GetLastActivePopup() const
  669. {
  670. ATLASSERT(::IsWindow(m_hWnd));
  671. return ::GetLastActivePopup(m_hWnd);
  672. }
  673. BOOL IsChild(HWND hWnd) const
  674. {
  675. ATLASSERT(::IsWindow(m_hWnd));
  676. return ::IsChild(m_hWnd, hWnd);
  677. }
  678. HWND GetParent() const
  679. {
  680. ATLASSERT(::IsWindow(m_hWnd));
  681. return ::GetParent(m_hWnd);
  682. }
  683. HWND SetParent(HWND hWndNewParent)
  684. {
  685. ATLASSERT(::IsWindow(m_hWnd));
  686. return ::SetParent(m_hWnd, hWndNewParent);
  687. }
  688. // Window Tree Access
  689. int GetDlgCtrlID() const
  690. {
  691. ATLASSERT(::IsWindow(m_hWnd));
  692. return ::GetDlgCtrlID(m_hWnd);
  693. }
  694. int SetDlgCtrlID(int nID)
  695. {
  696. ATLASSERT(::IsWindow(m_hWnd));
  697. return (int)::SetWindowLong(m_hWnd, GWL_ID, nID);
  698. }
  699. HWND GetDlgItem(int nID) const
  700. {
  701. ATLASSERT(::IsWindow(m_hWnd));
  702. return ::GetDlgItem(m_hWnd, nID);
  703. }
  704. // Alert Functions
  705. BOOL FlashWindow(BOOL bInvert)
  706. {
  707. ATLASSERT(::IsWindow(m_hWnd));
  708. return ::FlashWindow(m_hWnd, bInvert);
  709. }
  710. int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = _T(""), UINT nType = MB_OK)
  711. {
  712. ATLASSERT(::IsWindow(m_hWnd));
  713. return ::MessageBox(m_hWnd, lpszText, lpszCaption, nType);
  714. }
  715. // Clipboard Functions
  716. BOOL ChangeClipboardChain(HWND hWndNewNext)
  717. {
  718. ATLASSERT(::IsWindow(m_hWnd));
  719. return ::ChangeClipboardChain(m_hWnd, hWndNewNext);
  720. }
  721. HWND SetClipboardViewer()
  722. {
  723. ATLASSERT(::IsWindow(m_hWnd));
  724. return ::SetClipboardViewer(m_hWnd);
  725. }
  726. BOOL OpenClipboard()
  727. {
  728. ATLASSERT(::IsWindow(m_hWnd));
  729. return ::OpenClipboard(m_hWnd);
  730. }
  731. // Caret Functions
  732. BOOL CreateCaret(HBITMAP hBitmap)
  733. {
  734. ATLASSERT(::IsWindow(m_hWnd));
  735. return ::CreateCaret(m_hWnd, hBitmap, 0, 0);
  736. }
  737. BOOL CreateSolidCaret(int nWidth, int nHeight)
  738. {
  739. ATLASSERT(::IsWindow(m_hWnd));
  740. return ::CreateCaret(m_hWnd, (HBITMAP)0, nWidth, nHeight);
  741. }
  742. BOOL CreateGrayCaret(int nWidth, int nHeight)
  743. {
  744. ATLASSERT(::IsWindow(m_hWnd));
  745. return ::CreateCaret(m_hWnd, (HBITMAP)1, nWidth, nHeight);
  746. }
  747. BOOL HideCaret()
  748. {
  749. ATLASSERT(::IsWindow(m_hWnd));
  750. return ::HideCaret(m_hWnd);
  751. }
  752. BOOL ShowCaret()
  753. {
  754. ATLASSERT(::IsWindow(m_hWnd));
  755. return ::ShowCaret(m_hWnd);
  756. }
  757. #ifdef _INC_SHELLAPI
  758. // Drag-Drop Functions
  759. void DragAcceptFiles(BOOL bAccept = TRUE)
  760. {
  761. ATLASSERT(::IsWindow(m_hWnd)); ::DragAcceptFiles(m_hWnd, bAccept);
  762. }
  763. #endif
  764. // Icon Functions
  765. HICON SetIcon(HICON hIcon, BOOL bBigIcon = TRUE)
  766. {
  767. ATLASSERT(::IsWindow(m_hWnd));
  768. return (HICON)::SendMessage(m_hWnd, WM_SETICON, bBigIcon, (LPARAM)hIcon);
  769. }
  770. HICON GetIcon(BOOL bBigIcon = TRUE) const
  771. {
  772. ATLASSERT(::IsWindow(m_hWnd));
  773. return (HICON)::SendMessage(m_hWnd, WM_GETICON, bBigIcon, 0);
  774. }
  775. // Help Functions
  776. BOOL WinHelp(LPCTSTR lpszHelp, UINT nCmd = HELP_CONTEXT, DWORD dwData = 0)
  777. {
  778. ATLASSERT(::IsWindow(m_hWnd));
  779. return ::WinHelp(m_hWnd, lpszHelp, nCmd, dwData);
  780. }
  781. BOOL SetWindowContextHelpId(DWORD dwContextHelpId)
  782. {
  783. ATLASSERT(::IsWindow(m_hWnd));
  784. return ::SetWindowContextHelpId(m_hWnd, dwContextHelpId);
  785. }
  786. DWORD GetWindowContextHelpId() const
  787. {
  788. ATLASSERT(::IsWindow(m_hWnd));
  789. return ::GetWindowContextHelpId(m_hWnd);
  790. }
  791. // Hot Key Functions
  792. int SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
  793. {
  794. ATLASSERT(::IsWindow(m_hWnd));
  795. return (int)::SendMessage(m_hWnd, WM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0);
  796. }
  797. DWORD GetHotKey() const
  798. {
  799. ATLASSERT(::IsWindow(m_hWnd));
  800. return (DWORD)::SendMessage(m_hWnd, WM_GETHOTKEY, 0, 0);
  801. }
  802. // Misc. Operations
  803. //N new
  804. BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo)
  805. {
  806. ATLASSERT(::IsWindow(m_hWnd));
  807. return ::GetScrollInfo(m_hWnd, nBar, lpScrollInfo);
  808. }
  809. BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
  810. {
  811. ATLASSERT(::IsWindow(m_hWnd));
  812. return ::SetScrollInfo(m_hWnd, nBar, lpScrollInfo, bRedraw);
  813. }
  814. BOOL IsDialogMessage(LPMSG lpMsg)
  815. {
  816. ATLASSERT(::IsWindow(m_hWnd));
  817. return ::IsDialogMessage(m_hWnd, lpMsg);
  818. }
  819. void NextDlgCtrl() const
  820. {
  821. ATLASSERT(::IsWindow(m_hWnd));
  822. ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0L);
  823. }
  824. void PrevDlgCtrl() const
  825. {
  826. ATLASSERT(::IsWindow(m_hWnd));
  827. ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 1, 0L);
  828. }
  829. void GotoDlgCtrl(HWND hWndCtrl) const
  830. {
  831. ATLASSERT(::IsWindow(m_hWnd));
  832. ::SendMessage(m_hWnd, WM_NEXTDLGCTL, (WPARAM)hWndCtrl, 1L);
  833. }
  834. BOOL ResizeClient(int nWidth, int nHeight, BOOL bRedraw = TRUE)
  835. {
  836. ATLASSERT(::IsWindow(m_hWnd));
  837. RECT rcWnd;
  838. if(!GetClientRect(&rcWnd))
  839. return FALSE;
  840. if(nWidth != -1)
  841. rcWnd.right = nWidth;
  842. if(nHeight != -1)
  843. rcWnd.bottom = nHeight;
  844. if(!::AdjustWindowRectEx(&rcWnd, GetStyle(), (!(GetStyle() & WS_CHILD) && (GetMenu() != NULL)), GetExStyle()))
  845. return FALSE;
  846. UINT uFlags = SWP_NOZORDER | SWP_NOMOVE;
  847. if(!bRedraw)
  848. uFlags |= SWP_NOREDRAW;
  849. return SetWindowPos(NULL, 0, 0, rcWnd.right - rcWnd.left, rcWnd.bottom - rcWnd.top, uFlags);
  850. }
  851. int GetWindowRgn(HRGN hRgn)
  852. {
  853. ATLASSERT(::IsWindow(m_hWnd));
  854. return ::GetWindowRgn(m_hWnd, hRgn);
  855. }
  856. int SetWindowRgn(HRGN hRgn, BOOL bRedraw = FALSE)
  857. {
  858. ATLASSERT(::IsWindow(m_hWnd));
  859. return ::SetWindowRgn(m_hWnd, hRgn, bRedraw);
  860. }
  861. HDWP DeferWindowPos(HDWP hWinPosInfo, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags)
  862. {
  863. ATLASSERT(::IsWindow(m_hWnd));
  864. return ::DeferWindowPos(hWinPosInfo, m_hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
  865. }
  866. DWORD GetWindowThreadID()
  867. {
  868. ATLASSERT(::IsWindow(m_hWnd));
  869. return ::GetWindowThreadProcessId(m_hWnd, NULL);
  870. }
  871. DWORD GetWindowProcessID()
  872. {
  873. ATLASSERT(::IsWindow(m_hWnd));
  874. DWORD dwProcessID;
  875. ::GetWindowThreadProcessId(m_hWnd, &dwProcessID);
  876. return dwProcessID;
  877. }
  878. BOOL IsWindow()
  879. {
  880. return ::IsWindow(m_hWnd);
  881. }
  882. BOOL IsWindowUnicode()
  883. {
  884. ATLASSERT(::IsWindow(m_hWnd));
  885. return ::IsWindowUnicode(m_hWnd);
  886. }
  887. BOOL IsParentDialog()
  888. {
  889. ATLASSERT(::IsWindow(m_hWnd));
  890. TCHAR szBuf[8]; // "#32770" + NUL character
  891. GetClassName(GetParent(), szBuf, sizeof(szBuf)/sizeof(TCHAR));
  892. return lstrcmp(szBuf, _T("#32770")) == 0;
  893. }
  894. BOOL ShowWindowAsync(int nCmdShow)
  895. {
  896. ATLASSERT(::IsWindow(m_hWnd));
  897. return ::ShowWindowAsync(m_hWnd, nCmdShow);
  898. }
  899. HWND GetDescendantWindow(int nID) const
  900. {
  901. ATLASSERT(::IsWindow(m_hWnd));
  902. // GetDlgItem recursive (return first found)
  903. // breadth-first for 1 level, then depth-first for next level
  904. // use GetDlgItem since it is a fast USER function
  905. HWND hWndChild, hWndTmp;
  906. CWindow wnd;
  907. if((hWndChild = ::GetDlgItem(m_hWnd, nID)) != NULL)
  908. {
  909. if(::GetTopWindow(hWndChild) != NULL)
  910. {
  911. // children with the same ID as their parent have priority
  912. wnd.Attach(hWndChild);
  913. hWndTmp = wnd.GetDescendantWindow(nID);
  914. if(hWndTmp != NULL)
  915. return hWndTmp;
  916. }
  917. return hWndChild;
  918. }
  919. // walk each child
  920. for(hWndChild = ::GetTopWindow(m_hWnd); hWndChild != NULL;
  921. hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
  922. {
  923. wnd.Attach(hWndChild);
  924. hWndTmp = wnd.GetDescendantWindow(nID);
  925. if(hWndTmp != NULL)
  926. return hWndTmp;
  927. }
  928. return NULL; // not found
  929. }
  930. void SendMessageToDescendants(UINT message, WPARAM wParam = 0, LPARAM lParam = 0, BOOL bDeep = TRUE)
  931. {
  932. CWindow wnd;
  933. for(HWND hWndChild = ::GetTopWindow(m_hWnd); hWndChild != NULL;
  934. hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
  935. {
  936. ::SendMessage(hWndChild, message, wParam, lParam);
  937. if(bDeep && ::GetTopWindow(hWndChild) != NULL)
  938. {
  939. // send to child windows after parent
  940. wnd.Attach(hWndChild);
  941. wnd.SendMessageToDescendants(message, wParam, lParam, bDeep);
  942. }
  943. }
  944. }
  945. BOOL CenterWindow(HWND hWndCenter = NULL)
  946. {
  947. ATLASSERT(::IsWindow(m_hWnd));
  948. // determine owner window to center against
  949. DWORD dwStyle = GetStyle();
  950. if(hWndCenter == NULL)
  951. {
  952. if(dwStyle & WS_CHILD)
  953. hWndCenter = ::GetParent(m_hWnd);
  954. else
  955. hWndCenter = ::GetWindow(m_hWnd, GW_OWNER);
  956. }
  957. // get coordinates of the window relative to its parent
  958. RECT rcDlg;
  959. ::GetWindowRect(m_hWnd, &rcDlg);
  960. RECT rcArea;
  961. RECT rcCenter;
  962. HWND hWndParent;
  963. if(!(dwStyle & WS_CHILD))
  964. {
  965. // don't center against invisible or minimized windows
  966. if(hWndCenter != NULL)
  967. {
  968. DWORD dwStyle = ::GetWindowLong(hWndCenter, GWL_STYLE);
  969. if(!(dwStyle & WS_VISIBLE) || (dwStyle & WS_MINIMIZE))
  970. hWndCenter = NULL;
  971. }
  972. // center within screen coordinates
  973. ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
  974. if(hWndCenter == NULL)
  975. rcCenter = rcArea;
  976. else
  977. ::GetWindowRect(hWndCenter, &rcCenter);
  978. }
  979. else
  980. {
  981. // center within parent client coordinates
  982. hWndParent = ::GetParent(m_hWnd);
  983. ATLASSERT(::IsWindow(hWndParent));
  984. ::GetClientRect(hWndParent, &rcArea);
  985. ATLASSERT(::IsWindow(hWndCenter));
  986. ::GetClientRect(hWndCenter, &rcCenter);
  987. ::MapWindowPoints(hWndCenter, hWndParent, (POINT*)&rcCenter, 2);
  988. }
  989. int DlgWidth = rcDlg.right - rcDlg.left;
  990. int DlgHeight = rcDlg.bottom - rcDlg.top;
  991. // find dialog's upper left based on rcCenter
  992. int xLeft = (rcCenter.left + rcCenter.right) / 2 - DlgWidth / 2;
  993. int yTop = (rcCenter.top + rcCenter.bottom) / 2 - DlgHeight / 2;
  994. // if the dialog is outside the screen, move it inside
  995. if(xLeft < rcArea.left)
  996. xLeft = rcArea.left;
  997. else if(xLeft + DlgWidth > rcArea.right)
  998. xLeft = rcArea.right - DlgWidth;
  999. if(yTop < rcArea.top)
  1000. yTop = rcArea.top;
  1001. else if(yTop + DlgHeight > rcArea.bottom)
  1002. yTop = rcArea.bottom - DlgHeight;
  1003. // map screen coordinates to child coordinates
  1004. return ::SetWindowPos(m_hWnd, NULL, xLeft, yTop, -1, -1,
  1005. SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  1006. }
  1007. BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0)
  1008. {
  1009. ATLASSERT(::IsWindow(m_hWnd));
  1010. DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
  1011. DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
  1012. if(dwStyle == dwNewStyle)
  1013. return FALSE;
  1014. ::SetWindowLong(m_hWnd, GWL_STYLE, dwNewStyle);
  1015. if(nFlags != 0)
  1016. {
  1017. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0,
  1018. SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
  1019. }
  1020. return TRUE;
  1021. }
  1022. BOOL ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0)
  1023. {
  1024. ATLASSERT(::IsWindow(m_hWnd));
  1025. DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
  1026. DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
  1027. if(dwStyle == dwNewStyle)
  1028. return FALSE;
  1029. ::SetWindowLong(m_hWnd, GWL_EXSTYLE, dwNewStyle);
  1030. if(nFlags != 0)
  1031. {
  1032. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0,
  1033. SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
  1034. }
  1035. return TRUE;
  1036. }
  1037. BOOL GetWindowText(BSTR* pbstrText)
  1038. {
  1039. return GetWindowText(*pbstrText);
  1040. }
  1041. BOOL GetWindowText(BSTR& bstrText)
  1042. {
  1043. USES_CONVERSION;
  1044. ATLASSERT(::IsWindow(m_hWnd));
  1045. if (bstrText != NULL)
  1046. {
  1047. SysFreeString(bstrText);
  1048. bstrText = NULL;
  1049. }
  1050. int nLen = ::GetWindowTextLength(m_hWnd);
  1051. if(nLen == 0)
  1052. {
  1053. bstrText = ::SysAllocString(OLESTR(""));
  1054. return (bstrText != NULL) ? TRUE : FALSE;
  1055. }
  1056. LPTSTR lpszText = (LPTSTR)_alloca((nLen+1)*sizeof(TCHAR));
  1057. if(!::GetWindowText(m_hWnd, lpszText, nLen+1))
  1058. return FALSE;
  1059. bstrText = ::SysAllocString(T2OLE(lpszText));
  1060. return (bstrText != NULL) ? TRUE : FALSE;
  1061. }
  1062. HWND GetTopLevelParent() const
  1063. {
  1064. ATLASSERT(::IsWindow(m_hWnd));
  1065. HWND hWndParent = m_hWnd;
  1066. HWND hWndTmp;
  1067. while((hWndTmp = ::GetParent(hWndParent)) != NULL)
  1068. hWndParent = hWndTmp;
  1069. return hWndParent;
  1070. }
  1071. HWND GetTopLevelWindow() const
  1072. {
  1073. ATLASSERT(::IsWindow(m_hWnd));
  1074. HWND hWndParent;
  1075. HWND hWndTmp = m_hWnd;
  1076. do
  1077. {
  1078. hWndParent = hWndTmp;
  1079. hWndTmp = (::GetWindowLong(hWndParent, GWL_STYLE) & WS_CHILD) ? ::GetParent(hWndParent) : ::GetWindow(hWndParent, GW_OWNER);
  1080. }
  1081. while(hWndTmp != NULL);
  1082. return hWndParent;
  1083. }
  1084. };
  1085. _declspec(selectany) RECT CWindow::rcDefault = { CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 };
  1086. /////////////////////////////////////////////////////////////////////////////
  1087. // CAxWindow - client side for an ActiveX host window
  1088. #ifndef _ATL_NO_HOSTING
  1089. template <class TBase = CWindow>
  1090. class CAxWindowT : public TBase
  1091. {
  1092. public:
  1093. // Constructors
  1094. CAxWindowT(HWND hWnd = NULL) : TBase(hWnd)
  1095. { }
  1096. CAxWindowT< TBase >& operator=(HWND hWnd)
  1097. {
  1098. m_hWnd = hWnd;
  1099. return *this;
  1100. }
  1101. // Attributes
  1102. static LPCTSTR GetWndClassName()
  1103. {
  1104. return _T("AtlAxWin");
  1105. }
  1106. // Operations
  1107. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  1108. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  1109. UINT nID = 0, LPVOID lpCreateParam = NULL)
  1110. {
  1111. return CWindow::Create(GetWndClassName(), hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  1112. }
  1113. HWND Create(HWND hWndParent, LPRECT lpRect = NULL, LPCTSTR szWindowName = NULL,
  1114. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  1115. HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
  1116. {
  1117. return CWindow::Create(GetWndClassName(), hWndParent, lpRect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
  1118. }
  1119. HRESULT CreateControl(LPCOLESTR lpszName, IStream* pStream = NULL, IUnknown** ppUnkContainer = NULL)
  1120. {
  1121. ATLASSERT(::IsWindow(m_hWnd));
  1122. return AtlAxCreateControl(lpszName, m_hWnd, pStream, ppUnkContainer);
  1123. }
  1124. HRESULT CreateControl(DWORD dwResID, IStream* pStream = NULL, IUnknown** ppUnkContainer = NULL)
  1125. {
  1126. TCHAR szModule[_MAX_PATH];
  1127. GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
  1128. CComBSTR bstrURL(OLESTR("res://"));
  1129. bstrURL.Append(szModule);
  1130. bstrURL.Append(OLESTR("/"));
  1131. TCHAR szResID[11];
  1132. wsprintf(szResID, _T("%0d"), dwResID);
  1133. bstrURL.Append(szResID);
  1134. ATLASSERT(::IsWindow(m_hWnd));
  1135. return AtlAxCreateControl(bstrURL, m_hWnd, pStream, ppUnkContainer);
  1136. }
  1137. HRESULT CreateControlEx(LPCOLESTR lpszName, IStream* pStream = NULL,
  1138. IUnknown** ppUnkContainer = NULL, IUnknown** ppUnkControl = NULL,
  1139. REFIID iidSink = IID_NULL, IUnknown* punkSink = NULL)
  1140. {
  1141. ATLASSERT(::IsWindow(m_hWnd));
  1142. return AtlAxCreateControlEx(lpszName, m_hWnd, pStream, ppUnkContainer, ppUnkControl, iidSink, punkSink);
  1143. }
  1144. HRESULT CreateControlEx(DWORD dwResID, IStream* pStream = NULL,
  1145. IUnknown** ppUnkContainer = NULL, IUnknown** ppUnkControl = NULL,
  1146. REFIID iidSink = IID_NULL, IUnknown* punkSink = NULL)
  1147. {
  1148. TCHAR szModule[_MAX_PATH];
  1149. GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
  1150. CComBSTR bstrURL(OLESTR("res://"));
  1151. bstrURL.Append(szModule);
  1152. bstrURL.Append(OLESTR("/"));
  1153. TCHAR szResID[11];
  1154. wsprintf(szResID, _T("%0d"), dwResID);
  1155. bstrURL.Append(szResID);
  1156. ATLASSERT(::IsWindow(m_hWnd));
  1157. return AtlAxCreateControlEx(bstrURL, m_hWnd, pStream, ppUnkContainer, ppUnkControl, iidSink, punkSink);
  1158. }
  1159. HRESULT AttachControl(IUnknown* pControl, IUnknown** ppUnkContainer)
  1160. {
  1161. ATLASSERT(::IsWindow(m_hWnd));
  1162. return AtlAxAttachControl(pControl, m_hWnd, ppUnkContainer);
  1163. }
  1164. HRESULT QueryHost(REFIID iid, void** ppUnk)
  1165. {
  1166. ATLASSERT(ppUnk != NULL);
  1167. HRESULT hr;
  1168. *ppUnk = NULL;
  1169. CComPtr<IUnknown> spUnk;
  1170. hr = AtlAxGetHost(m_hWnd, &spUnk);
  1171. if (SUCCEEDED(hr))
  1172. hr = spUnk->QueryInterface(iid, ppUnk);
  1173. return hr;
  1174. }
  1175. template <class Q>
  1176. HRESULT QueryHost(Q** ppUnk)
  1177. {
  1178. return QueryHost(__uuidof(Q), (void**)ppUnk);
  1179. }
  1180. HRESULT QueryControl(REFIID iid, void** ppUnk)
  1181. {
  1182. ATLASSERT(ppUnk != NULL);
  1183. HRESULT hr;
  1184. *ppUnk = NULL;
  1185. CComPtr<IUnknown> spUnk;
  1186. hr = AtlAxGetControl(m_hWnd, &spUnk);
  1187. if (SUCCEEDED(hr))
  1188. hr = spUnk->QueryInterface(iid, ppUnk);
  1189. return hr;
  1190. }
  1191. template <class Q>
  1192. HRESULT QueryControl(Q** ppUnk)
  1193. {
  1194. return QueryControl(__uuidof(Q), (void**)ppUnk);
  1195. }
  1196. HRESULT SetExternalDispatch(IDispatch* pDisp)
  1197. {
  1198. HRESULT hr;
  1199. CComPtr<IAxWinHostWindow> spHost;
  1200. hr = QueryHost(IID_IAxWinHostWindow, (void**)&spHost);
  1201. if (SUCCEEDED(hr))
  1202. hr = spHost->SetExternalDispatch(pDisp);
  1203. return hr;
  1204. }
  1205. HRESULT SetExternalUIHandler(IDocHostUIHandlerDispatch* pUIHandler)
  1206. {
  1207. HRESULT hr;
  1208. CComPtr<IAxWinHostWindow> spHost;
  1209. hr = QueryHost(IID_IAxWinHostWindow, (void**)&spHost);
  1210. if (SUCCEEDED(hr))
  1211. hr = spHost->SetExternalUIHandler(pUIHandler);
  1212. return hr;
  1213. }
  1214. };
  1215. typedef CAxWindowT<CWindow> CAxWindow;
  1216. #endif //_ATL_NO_HOSTING
  1217. /////////////////////////////////////////////////////////////////////////////
  1218. // WindowProc thunks
  1219. class CWndProcThunk
  1220. {
  1221. public:
  1222. _AtlCreateWndData cd;
  1223. CStdCallThunk thunk;
  1224. void Init(WNDPROC proc, void* pThis)
  1225. {
  1226. thunk.Init((DWORD_PTR)proc, pThis);
  1227. }
  1228. };
  1229. /////////////////////////////////////////////////////////////////////////////
  1230. // CMessageMap - abstract class that provides an interface for message maps
  1231. class ATL_NO_VTABLE CMessageMap
  1232. {
  1233. public:
  1234. virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
  1235. LRESULT& lResult, DWORD dwMsgMapID) = 0;
  1236. };
  1237. /////////////////////////////////////////////////////////////////////////////
  1238. // Message map
  1239. #define BEGIN_MSG_MAP(theClass) \
  1240. public: \
  1241. BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \
  1242. { \
  1243. BOOL bHandled = TRUE; \
  1244. hWnd; \
  1245. uMsg; \
  1246. wParam; \
  1247. lParam; \
  1248. lResult; \
  1249. bHandled; \
  1250. switch(dwMsgMapID) \
  1251. { \
  1252. case 0:
  1253. #define ALT_MSG_MAP(msgMapID) \
  1254. break; \
  1255. case msgMapID:
  1256. #define MESSAGE_HANDLER(msg, func) \
  1257. if(uMsg == msg) \
  1258. { \
  1259. bHandled = TRUE; \
  1260. lResult = func(uMsg, wParam, lParam, bHandled); \
  1261. if(bHandled) \
  1262. return TRUE; \
  1263. }
  1264. #define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func) \
  1265. if(uMsg >= msgFirst && uMsg <= msgLast) \
  1266. { \
  1267. bHandled = TRUE; \
  1268. lResult = func(uMsg, wParam, lParam, bHandled); \
  1269. if(bHandled) \
  1270. return TRUE; \
  1271. }
  1272. #define COMMAND_HANDLER(id, code, func) \
  1273. if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
  1274. { \
  1275. bHandled = TRUE; \
  1276. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  1277. if(bHandled) \
  1278. return TRUE; \
  1279. }
  1280. #define COMMAND_ID_HANDLER(id, func) \
  1281. if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
  1282. { \
  1283. bHandled = TRUE; \
  1284. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  1285. if(bHandled) \
  1286. return TRUE; \
  1287. }
  1288. #define COMMAND_CODE_HANDLER(code, func) \
  1289. if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \
  1290. { \
  1291. bHandled = TRUE; \
  1292. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  1293. if(bHandled) \
  1294. return TRUE; \
  1295. }
  1296. #define COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
  1297. if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
  1298. { \
  1299. bHandled = TRUE; \
  1300. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  1301. if(bHandled) \
  1302. return TRUE; \
  1303. }
  1304. #define NOTIFY_HANDLER(id, cd, func) \
  1305. if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
  1306. { \
  1307. bHandled = TRUE; \
  1308. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  1309. if(bHandled) \
  1310. return TRUE; \
  1311. }
  1312. #define NOTIFY_ID_HANDLER(id, func) \
  1313. if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
  1314. { \
  1315. bHandled = TRUE; \
  1316. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  1317. if(bHandled) \
  1318. return TRUE; \
  1319. }
  1320. #define NOTIFY_CODE_HANDLER(cd, func) \
  1321. if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
  1322. { \
  1323. bHandled = TRUE; \
  1324. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  1325. if(bHandled) \
  1326. return TRUE; \
  1327. }
  1328. #define NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \
  1329. if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
  1330. { \
  1331. bHandled = TRUE; \
  1332. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  1333. if(bHandled) \
  1334. return TRUE; \
  1335. }
  1336. #define CHAIN_MSG_MAP(theChainClass) \
  1337. { \
  1338. if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
  1339. return TRUE; \
  1340. }
  1341. #define CHAIN_MSG_MAP_MEMBER(theChainMember) \
  1342. { \
  1343. if(theChainMember.ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
  1344. return TRUE; \
  1345. }
  1346. #define CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) \
  1347. { \
  1348. if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
  1349. return TRUE; \
  1350. }
  1351. #define CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) \
  1352. { \
  1353. if(theChainMember.ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
  1354. return TRUE; \
  1355. }
  1356. #define CHAIN_MSG_MAP_DYNAMIC(dynaChainID) \
  1357. { \
  1358. if(CDynamicChain::CallChain(dynaChainID, hWnd, uMsg, wParam, lParam, lResult)) \
  1359. return TRUE; \
  1360. }
  1361. #define END_MSG_MAP() \
  1362. break; \
  1363. default: \
  1364. ATLTRACE2(atlTraceWindowing, 0, _T("Invalid message map ID (%i)\n"), dwMsgMapID); \
  1365. ATLASSERT(FALSE); \
  1366. break; \
  1367. } \
  1368. return FALSE; \
  1369. }
  1370. // Handler prototypes:
  1371. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  1372. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  1373. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  1374. // Empty message map macro
  1375. #define DECLARE_EMPTY_MSG_MAP() \
  1376. public: \
  1377. BOOL ProcessWindowMessage(HWND, UINT, WPARAM, LPARAM, LRESULT&, DWORD) \
  1378. { \
  1379. return FALSE; \
  1380. }
  1381. // Message reflection macros
  1382. #define REFLECT_NOTIFICATIONS() \
  1383. { \
  1384. bHandled = TRUE; \
  1385. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  1386. if(bHandled) \
  1387. return TRUE; \
  1388. }
  1389. #define DEFAULT_REFLECTION_HANDLER() \
  1390. if(DefaultReflectionHandler(hWnd, uMsg, wParam, lParam, lResult)) \
  1391. return TRUE;
  1392. /////////////////////////////////////////////////////////////////////////////
  1393. // CDynamicChain - provides support for dynamic chaining
  1394. class CDynamicChain
  1395. {
  1396. public:
  1397. struct ATL_CHAIN_ENTRY
  1398. {
  1399. DWORD m_dwChainID;
  1400. CMessageMap* m_pObject;
  1401. DWORD m_dwMsgMapID;
  1402. };
  1403. CSimpleArray<ATL_CHAIN_ENTRY*> m_aChainEntry;
  1404. CDynamicChain()
  1405. { }
  1406. ~CDynamicChain()
  1407. {
  1408. for(int i = 0; i < m_aChainEntry.GetSize(); i++)
  1409. {
  1410. if(m_aChainEntry[i] != NULL)
  1411. delete m_aChainEntry[i];
  1412. }
  1413. }
  1414. BOOL SetChainEntry(DWORD dwChainID, CMessageMap* pObject, DWORD dwMsgMapID = 0)
  1415. {
  1416. // first search for an existing entry
  1417. for(int i = 0; i < m_aChainEntry.GetSize(); i++)
  1418. {
  1419. if(m_aChainEntry[i] != NULL && m_aChainEntry[i]->m_dwChainID == dwChainID)
  1420. {
  1421. m_aChainEntry[i]->m_pObject = pObject;
  1422. m_aChainEntry[i]->m_dwMsgMapID = dwMsgMapID;
  1423. return TRUE;
  1424. }
  1425. }
  1426. // create a new one
  1427. ATL_CHAIN_ENTRY* pEntry = NULL;
  1428. ATLTRY(pEntry = new ATL_CHAIN_ENTRY);
  1429. if(pEntry == NULL)
  1430. return FALSE;
  1431. pEntry->m_dwChainID = dwChainID;
  1432. pEntry->m_pObject = pObject;
  1433. pEntry->m_dwMsgMapID = dwMsgMapID;
  1434. // search for an empty one
  1435. for(i = 0; i < m_aChainEntry.GetSize(); i++)
  1436. {
  1437. if(m_aChainEntry[i] == NULL)
  1438. {
  1439. m_aChainEntry[i] = pEntry;
  1440. return TRUE;
  1441. }
  1442. }
  1443. // add a new one
  1444. BOOL bRet = m_aChainEntry.Add(pEntry);
  1445. if(!bRet)
  1446. {
  1447. delete pEntry;
  1448. return FALSE;
  1449. }
  1450. return TRUE;
  1451. }
  1452. BOOL RemoveChainEntry(DWORD dwChainID)
  1453. {
  1454. for(int i = 0; i < m_aChainEntry.GetSize(); i++)
  1455. {
  1456. if(m_aChainEntry[i] != NULL && m_aChainEntry[i]->m_dwChainID == dwChainID)
  1457. {
  1458. delete m_aChainEntry[i];
  1459. m_aChainEntry[i] = NULL;
  1460. return TRUE;
  1461. }
  1462. }
  1463. return FALSE;
  1464. }
  1465. BOOL CallChain(DWORD dwChainID, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult)
  1466. {
  1467. for(int i = 0; i < m_aChainEntry.GetSize(); i++)
  1468. {
  1469. if(m_aChainEntry[i] != NULL && m_aChainEntry[i]->m_dwChainID == dwChainID)
  1470. return (m_aChainEntry[i]->m_pObject)->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, m_aChainEntry[i]->m_dwMsgMapID);
  1471. }
  1472. return FALSE;
  1473. }
  1474. };
  1475. /////////////////////////////////////////////////////////////////////////////
  1476. // CWndClassInfo - Manages Windows class information
  1477. #define DECLARE_WND_CLASS(WndClassName) \
  1478. static CWndClassInfo& GetWndClassInfo() \
  1479. { \
  1480. static CWndClassInfo wc = \
  1481. { \
  1482. { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, StartWindowProc, \
  1483. 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName, NULL }, \
  1484. NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
  1485. }; \
  1486. return wc; \
  1487. }
  1488. #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \
  1489. static CWndClassInfo& GetWndClassInfo() \
  1490. { \
  1491. static CWndClassInfo wc = \
  1492. { \
  1493. { sizeof(WNDCLASSEX), style, StartWindowProc, \
  1494. 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
  1495. NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
  1496. }; \
  1497. return wc; \
  1498. }
  1499. #define DECLARE_WND_SUPERCLASS(WndClassName, OrigWndClassName) \
  1500. static CWndClassInfo& GetWndClassInfo() \
  1501. { \
  1502. static CWndClassInfo wc = \
  1503. { \
  1504. { sizeof(WNDCLASSEX), 0, StartWindowProc, \
  1505. 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \
  1506. OrigWndClassName, NULL, NULL, TRUE, 0, _T("") \
  1507. }; \
  1508. return wc; \
  1509. }
  1510. /////////////////////////////////////////////////////////////////////////////
  1511. // CWinTraits - Defines various default values for a window
  1512. template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0>
  1513. class CWinTraits
  1514. {
  1515. public:
  1516. static DWORD GetWndStyle(DWORD dwStyle)
  1517. {
  1518. return dwStyle == 0 ? t_dwStyle : dwStyle;
  1519. }
  1520. static DWORD GetWndExStyle(DWORD dwExStyle)
  1521. {
  1522. return dwExStyle == 0 ? t_dwExStyle : dwExStyle;
  1523. }
  1524. };
  1525. typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0> CControlWinTraits;
  1526. typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> CFrameWinTraits;
  1527. typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_MDICHILD> CMDIChildWinTraits;
  1528. typedef CWinTraits<0, 0> CNullTraits;
  1529. template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0, class TWinTraits = CControlWinTraits>
  1530. class CWinTraitsOR
  1531. {
  1532. public:
  1533. static DWORD GetWndStyle(DWORD dwStyle)
  1534. {
  1535. return dwStyle | t_dwStyle | TWinTraits::GetWndStyle(dwStyle);
  1536. }
  1537. static DWORD GetWndExStyle(DWORD dwExStyle)
  1538. {
  1539. return dwExStyle | t_dwExStyle | TWinTraits::GetWndExStyle(dwExStyle);
  1540. }
  1541. };
  1542. /////////////////////////////////////////////////////////////////////////////
  1543. // CWindowImpl - Implements a window
  1544. template <class TBase = CWindow>
  1545. class ATL_NO_VTABLE CWindowImplRoot : public TBase, public CMessageMap
  1546. {
  1547. public:
  1548. CWndProcThunk m_thunk;
  1549. const MSG* m_pCurrentMsg;
  1550. // Constructor/destructor
  1551. CWindowImplRoot() : m_pCurrentMsg(NULL)
  1552. { }
  1553. ~CWindowImplRoot()
  1554. {
  1555. #ifdef _DEBUG
  1556. if(m_hWnd != NULL) // should be cleared in WindowProc
  1557. {
  1558. ATLTRACE2(atlTraceWindowing, 0, _T("ERROR - Object deleted before window was destroyed\n"));
  1559. ATLASSERT(FALSE);
  1560. }
  1561. #endif //_DEBUG
  1562. }
  1563. // Current message
  1564. const MSG* GetCurrentMessage() const
  1565. {
  1566. return m_pCurrentMsg;
  1567. }
  1568. // Message reflection support
  1569. LRESULT ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  1570. static BOOL DefaultReflectionHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult);
  1571. };
  1572. template <class TBase>
  1573. LRESULT CWindowImplRoot< TBase >::ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1574. {
  1575. HWND hWndChild = NULL;
  1576. switch(uMsg)
  1577. {
  1578. case WM_COMMAND:
  1579. if(lParam != NULL) // not from a menu
  1580. hWndChild = (HWND)lParam;
  1581. break;
  1582. case WM_NOTIFY:
  1583. hWndChild = ((LPNMHDR)lParam)->hwndFrom;
  1584. break;
  1585. case WM_PARENTNOTIFY:
  1586. switch(LOWORD(wParam))
  1587. {
  1588. case WM_CREATE:
  1589. case WM_DESTROY:
  1590. hWndChild = (HWND)lParam;
  1591. break;
  1592. default:
  1593. hWndChild = GetDlgItem(HIWORD(wParam));
  1594. break;
  1595. }
  1596. break;
  1597. case WM_DRAWITEM:
  1598. if(wParam) // not from a menu
  1599. hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
  1600. break;
  1601. case WM_MEASUREITEM:
  1602. if(wParam) // not from a menu
  1603. hWndChild = GetDlgItem(((LPMEASUREITEMSTRUCT)lParam)->CtlID);
  1604. break;
  1605. case WM_COMPAREITEM:
  1606. if(wParam) // not from a menu
  1607. hWndChild = GetDlgItem(((LPCOMPAREITEMSTRUCT)lParam)->CtlID);
  1608. break;
  1609. case WM_DELETEITEM:
  1610. if(wParam) // not from a menu
  1611. hWndChild = GetDlgItem(((LPDELETEITEMSTRUCT)lParam)->CtlID);
  1612. break;
  1613. case WM_VKEYTOITEM:
  1614. case WM_CHARTOITEM:
  1615. case WM_HSCROLL:
  1616. case WM_VSCROLL:
  1617. hWndChild = (HWND)lParam;
  1618. break;
  1619. case WM_CTLCOLORBTN:
  1620. case WM_CTLCOLORDLG:
  1621. case WM_CTLCOLOREDIT:
  1622. case WM_CTLCOLORLISTBOX:
  1623. case WM_CTLCOLORMSGBOX:
  1624. case WM_CTLCOLORSCROLLBAR:
  1625. case WM_CTLCOLORSTATIC:
  1626. hWndChild = (HWND)lParam;
  1627. break;
  1628. default:
  1629. break;
  1630. }
  1631. if(hWndChild == NULL)
  1632. {
  1633. bHandled = FALSE;
  1634. return 1;
  1635. }
  1636. ATLASSERT(::IsWindow(hWndChild));
  1637. return ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
  1638. }
  1639. template <class TBase>
  1640. BOOL CWindowImplRoot< TBase >::DefaultReflectionHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult)
  1641. {
  1642. switch(uMsg)
  1643. {
  1644. case OCM_COMMAND:
  1645. case OCM_NOTIFY:
  1646. case OCM_PARENTNOTIFY:
  1647. case OCM_DRAWITEM:
  1648. case OCM_MEASUREITEM:
  1649. case OCM_COMPAREITEM:
  1650. case OCM_DELETEITEM:
  1651. case OCM_VKEYTOITEM:
  1652. case OCM_CHARTOITEM:
  1653. case OCM_HSCROLL:
  1654. case OCM_VSCROLL:
  1655. case OCM_CTLCOLORBTN:
  1656. case OCM_CTLCOLORDLG:
  1657. case OCM_CTLCOLOREDIT:
  1658. case OCM_CTLCOLORLISTBOX:
  1659. case OCM_CTLCOLORMSGBOX:
  1660. case OCM_CTLCOLORSCROLLBAR:
  1661. case OCM_CTLCOLORSTATIC:
  1662. lResult = ::DefWindowProc(hWnd, uMsg - OCM__BASE, wParam, lParam);
  1663. return TRUE;
  1664. default:
  1665. break;
  1666. }
  1667. return FALSE;
  1668. }
  1669. template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
  1670. class ATL_NO_VTABLE CWindowImplBaseT : public CWindowImplRoot< TBase >
  1671. {
  1672. public:
  1673. WNDPROC m_pfnSuperWindowProc;
  1674. CWindowImplBaseT() : m_pfnSuperWindowProc(::DefWindowProc)
  1675. {}
  1676. static DWORD GetWndStyle(DWORD dwStyle)
  1677. {
  1678. return TWinTraits::GetWndStyle(dwStyle);
  1679. }
  1680. static DWORD GetWndExStyle(DWORD dwExStyle)
  1681. {
  1682. return TWinTraits::GetWndExStyle(dwExStyle);
  1683. }
  1684. virtual WNDPROC GetWindowProc()
  1685. {
  1686. return WindowProc;
  1687. }
  1688. static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1689. static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1690. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName,
  1691. DWORD dwStyle, DWORD dwExStyle, UINT nID, ATOM atom, LPVOID lpCreateParam = NULL);
  1692. BOOL DestroyWindow()
  1693. {
  1694. ATLASSERT(::IsWindow(m_hWnd));
  1695. return ::DestroyWindow(m_hWnd);
  1696. }
  1697. BOOL SubclassWindow(HWND hWnd);
  1698. HWND UnsubclassWindow(BOOL bForce = FALSE);
  1699. LRESULT DefWindowProc()
  1700. {
  1701. const MSG* pMsg = m_pCurrentMsg;
  1702. LRESULT lRes = 0;
  1703. if (pMsg != NULL)
  1704. lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
  1705. return lRes;
  1706. }
  1707. LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1708. {
  1709. #ifdef STRICT
  1710. return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  1711. #else
  1712. return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  1713. #endif
  1714. }
  1715. virtual void OnFinalMessage(HWND /*hWnd*/)
  1716. {
  1717. // override to do something, if needed
  1718. }
  1719. };
  1720. typedef CWindowImplBaseT<CWindow> CWindowImplBase;
  1721. template <class TBase, class TWinTraits>
  1722. LRESULT CALLBACK CWindowImplBaseT< TBase, TWinTraits >::StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1723. {
  1724. CWindowImplBaseT< TBase, TWinTraits >* pThis = (CWindowImplBaseT< TBase, TWinTraits >*)_Module.ExtractCreateWndData();
  1725. ATLASSERT(pThis != NULL);
  1726. pThis->m_hWnd = hWnd;
  1727. pThis->m_thunk.Init(pThis->GetWindowProc(), pThis);
  1728. WNDPROC pProc = (WNDPROC)(pThis->m_thunk.thunk.pThunk);
  1729. WNDPROC pOldProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LPARAM)pProc);
  1730. #ifdef _DEBUG
  1731. // check if somebody has subclassed us already since we discard it
  1732. if(pOldProc != StartWindowProc)
  1733. ATLTRACE2(atlTraceWindowing, 0, _T("Subclassing through a hook discarded.\n"));
  1734. #else
  1735. pOldProc; // avoid unused warning
  1736. #endif
  1737. return pProc(hWnd, uMsg, wParam, lParam);
  1738. }
  1739. template <class TBase, class TWinTraits>
  1740. LRESULT CALLBACK CWindowImplBaseT< TBase, TWinTraits >::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1741. {
  1742. CWindowImplBaseT< TBase, TWinTraits >* pThis = (CWindowImplBaseT< TBase, TWinTraits >*)hWnd;
  1743. // set a ptr to this message and save the old value
  1744. MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
  1745. const MSG* pOldMsg = pThis->m_pCurrentMsg;
  1746. pThis->m_pCurrentMsg = &msg;
  1747. // pass to the message map to process
  1748. LRESULT lRes;
  1749. BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
  1750. // restore saved value for the current message
  1751. ATLASSERT(pThis->m_pCurrentMsg == &msg);
  1752. pThis->m_pCurrentMsg = pOldMsg;
  1753. // do the default processing if message was not handled
  1754. if(!bRet)
  1755. {
  1756. if(uMsg != WM_NCDESTROY)
  1757. lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  1758. else
  1759. {
  1760. // unsubclass, if needed
  1761. LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
  1762. lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  1763. if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
  1764. ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
  1765. // clear out window handle
  1766. HWND hWnd = pThis->m_hWnd;
  1767. pThis->m_hWnd = NULL;
  1768. // clean up after window is destroyed
  1769. pThis->OnFinalMessage(hWnd);
  1770. }
  1771. }
  1772. return lRes;
  1773. }
  1774. template <class TBase, class TWinTraits>
  1775. HWND CWindowImplBaseT< TBase, TWinTraits >::Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName,
  1776. DWORD dwStyle, DWORD dwExStyle, UINT nID, ATOM atom, LPVOID lpCreateParam)
  1777. {
  1778. ATLASSERT(m_hWnd == NULL);
  1779. if(atom == 0)
  1780. return NULL;
  1781. _Module.AddCreateWndData(&m_thunk.cd, this);
  1782. if(nID == 0 && (dwStyle & WS_CHILD))
  1783. #if _ATL_VER > 0x0300
  1784. nID = _Module.GetNextWindowID();
  1785. #else
  1786. nID = (UINT)this;
  1787. #endif
  1788. HWND hWnd = ::CreateWindowEx(dwExStyle, (LPCTSTR)(LONG_PTR)MAKELONG(atom, 0), szWindowName,
  1789. dwStyle, rcPos.left, rcPos.top, rcPos.right - rcPos.left,
  1790. rcPos.bottom - rcPos.top, hWndParent, (HMENU)(DWORD_PTR)nID,
  1791. _Module.GetModuleInstance(), lpCreateParam);
  1792. ATLASSERT(m_hWnd == hWnd);
  1793. return hWnd;
  1794. }
  1795. template <class TBase, class TWinTraits>
  1796. BOOL CWindowImplBaseT< TBase, TWinTraits >::SubclassWindow(HWND hWnd)
  1797. {
  1798. ATLASSERT(m_hWnd == NULL);
  1799. ATLASSERT(::IsWindow(hWnd));
  1800. m_thunk.Init(GetWindowProc(), this);
  1801. WNDPROC pProc = (WNDPROC)(m_thunk.thunk.pThunk);
  1802. WNDPROC pfnWndProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LPARAM)pProc);
  1803. if(pfnWndProc == NULL)
  1804. return FALSE;
  1805. m_pfnSuperWindowProc = pfnWndProc;
  1806. m_hWnd = hWnd;
  1807. return TRUE;
  1808. }
  1809. // Use only if you want to subclass before window is destroyed,
  1810. // WindowProc will automatically subclass when window goes away
  1811. template <class TBase, class TWinTraits>
  1812. HWND CWindowImplBaseT< TBase, TWinTraits >::UnsubclassWindow(BOOL bForce /*= FALSE*/)
  1813. {
  1814. ATLASSERT(m_hWnd != NULL);
  1815. WNDPROC pOurProc = (WNDPROC)(m_thunk.thunk.pThunk);
  1816. WNDPROC pActiveProc = (WNDPROC)::GetWindowLongPtr(m_hWnd, GWLP_WNDPROC);
  1817. HWND hWnd = NULL;
  1818. if (bForce || pOurProc == pActiveProc)
  1819. {
  1820. if(!::SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pfnSuperWindowProc))
  1821. return NULL;
  1822. m_pfnSuperWindowProc = ::DefWindowProc;
  1823. hWnd = m_hWnd;
  1824. m_hWnd = NULL;
  1825. }
  1826. return hWnd;
  1827. }
  1828. template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
  1829. class ATL_NO_VTABLE CWindowImpl : public CWindowImplBaseT< TBase, TWinTraits >
  1830. {
  1831. public:
  1832. DECLARE_WND_CLASS(NULL)
  1833. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  1834. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  1835. UINT nID = 0, LPVOID lpCreateParam = NULL)
  1836. {
  1837. if (T::GetWndClassInfo().m_lpszOrigName == NULL)
  1838. T::GetWndClassInfo().m_lpszOrigName = GetWndClassName();
  1839. ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
  1840. dwStyle = T::GetWndStyle(dwStyle);
  1841. dwExStyle = T::GetWndExStyle(dwExStyle);
  1842. return CWindowImplBaseT< TBase, TWinTraits >::Create(hWndParent, rcPos, szWindowName,
  1843. dwStyle, dwExStyle, nID, atom, lpCreateParam);
  1844. }
  1845. };
  1846. /////////////////////////////////////////////////////////////////////////////
  1847. // CDialogImpl - Implements a dialog box
  1848. template <class TBase = CWindow>
  1849. class ATL_NO_VTABLE CDialogImplBaseT : public CWindowImplRoot< TBase >
  1850. {
  1851. public:
  1852. virtual WNDPROC GetDialogProc()
  1853. {
  1854. return DialogProc;
  1855. }
  1856. static LRESULT CALLBACK StartDialogProc(HWND hWnd, UINT uMsg,
  1857. WPARAM wParam, LPARAM lParam);
  1858. static LRESULT CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  1859. BOOL MapDialogRect(LPRECT lpRect)
  1860. {
  1861. ATLASSERT(::IsWindow(m_hWnd));
  1862. return ::MapDialogRect(m_hWnd, lpRect);
  1863. }
  1864. virtual void OnFinalMessage(HWND /*hWnd*/)
  1865. {
  1866. // override to do something, if needed
  1867. }
  1868. // has no meaning for a dialog, but needed for handlers that use it
  1869. LRESULT DefWindowProc()
  1870. {
  1871. return 0;
  1872. }
  1873. };
  1874. template <class TBase>
  1875. LRESULT CALLBACK CDialogImplBaseT< TBase >::StartDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1876. {
  1877. CDialogImplBaseT< TBase >* pThis = (CDialogImplBaseT< TBase >*)_Module.ExtractCreateWndData();
  1878. ATLASSERT(pThis != NULL);
  1879. pThis->m_hWnd = hWnd;
  1880. pThis->m_thunk.Init(pThis->GetDialogProc(), pThis);
  1881. WNDPROC pProc = (WNDPROC)(pThis->m_thunk.thunk.pThunk);
  1882. WNDPROC pOldProc = (WNDPROC)::SetWindowLongPtr(hWnd, DWLP_DLGPROC, (LPARAM)pProc);
  1883. #ifdef _DEBUG
  1884. // check if somebody has subclassed us already since we discard it
  1885. if(pOldProc != StartDialogProc)
  1886. ATLTRACE2(atlTraceWindowing, 0, _T("Subclassing through a hook discarded.\n"));
  1887. #else
  1888. pOldProc; // avoid unused warning
  1889. #endif
  1890. return pProc(hWnd, uMsg, wParam, lParam);
  1891. }
  1892. template <class TBase>
  1893. LRESULT CALLBACK CDialogImplBaseT< TBase >::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1894. {
  1895. CDialogImplBaseT< TBase >* pThis = (CDialogImplBaseT< TBase >*)hWnd;
  1896. // set a ptr to this message and save the old value
  1897. MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
  1898. const MSG* pOldMsg = pThis->m_pCurrentMsg;
  1899. pThis->m_pCurrentMsg = &msg;
  1900. // pass to the message map to process
  1901. LRESULT lRes;
  1902. BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
  1903. // restore saved value for the current message
  1904. ATLASSERT(pThis->m_pCurrentMsg == &msg);
  1905. pThis->m_pCurrentMsg = pOldMsg;
  1906. // set result if message was handled
  1907. if(bRet)
  1908. {
  1909. switch (uMsg)
  1910. {
  1911. case WM_COMPAREITEM:
  1912. case WM_VKEYTOITEM:
  1913. case WM_CHARTOITEM:
  1914. case WM_INITDIALOG:
  1915. case WM_QUERYDRAGICON:
  1916. case WM_CTLCOLORMSGBOX:
  1917. case WM_CTLCOLOREDIT:
  1918. case WM_CTLCOLORLISTBOX:
  1919. case WM_CTLCOLORBTN:
  1920. case WM_CTLCOLORDLG:
  1921. case WM_CTLCOLORSCROLLBAR:
  1922. case WM_CTLCOLORSTATIC:
  1923. return lRes;
  1924. break;
  1925. }
  1926. ::SetWindowLongPtr(pThis->m_hWnd, DWLP_MSGRESULT, lRes);
  1927. return TRUE;
  1928. }
  1929. if(uMsg == WM_NCDESTROY)
  1930. {
  1931. // clear out window handle
  1932. HWND hWnd = pThis->m_hWnd;
  1933. pThis->m_hWnd = NULL;
  1934. // clean up after dialog is destroyed
  1935. pThis->OnFinalMessage(hWnd);
  1936. }
  1937. return FALSE;
  1938. }
  1939. typedef CDialogImplBaseT<CWindow> CDialogImplBase;
  1940. template <class T, class TBase = CWindow>
  1941. class ATL_NO_VTABLE CDialogImpl : public CDialogImplBaseT< TBase >
  1942. {
  1943. public:
  1944. #ifdef _DEBUG
  1945. bool m_bModal;
  1946. CDialogImpl() : m_bModal(false) { }
  1947. #endif //_DEBUG
  1948. // modal dialogs
  1949. INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
  1950. {
  1951. ATLASSERT(m_hWnd == NULL);
  1952. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT< TBase >*)this);
  1953. #ifdef _DEBUG
  1954. m_bModal = true;
  1955. #endif //_DEBUG
  1956. return ::DialogBoxParam(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
  1957. hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
  1958. }
  1959. BOOL EndDialog(INT_PTR nRetCode)
  1960. {
  1961. ATLASSERT(::IsWindow(m_hWnd));
  1962. ATLASSERT(m_bModal); // must be a modal dialog
  1963. return ::EndDialog(m_hWnd, nRetCode);
  1964. }
  1965. // modeless dialogs
  1966. HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
  1967. {
  1968. ATLASSERT(m_hWnd == NULL);
  1969. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT< TBase >*)this);
  1970. #ifdef _DEBUG
  1971. m_bModal = false;
  1972. #endif //_DEBUG
  1973. HWND hWnd = ::CreateDialogParam(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
  1974. hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
  1975. ATLASSERT(m_hWnd == hWnd);
  1976. return hWnd;
  1977. }
  1978. // for CComControl
  1979. HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL)
  1980. {
  1981. return Create(hWndParent, dwInitParam);
  1982. }
  1983. BOOL DestroyWindow()
  1984. {
  1985. ATLASSERT(::IsWindow(m_hWnd));
  1986. ATLASSERT(!m_bModal); // must not be a modal dialog
  1987. return ::DestroyWindow(m_hWnd);
  1988. }
  1989. };
  1990. /////////////////////////////////////////////////////////////////////////////
  1991. // CAxDialogImpl - Implements a dialog box that hosts ActiveX controls
  1992. #ifndef _ATL_NO_HOSTING
  1993. template <class T, class TBase = CWindow>
  1994. class ATL_NO_VTABLE CAxDialogImpl : public CDialogImplBaseT< TBase >
  1995. {
  1996. public:
  1997. #ifdef _DEBUG
  1998. bool m_bModal;
  1999. CAxDialogImpl() : m_bModal(false) { }
  2000. #endif //_DEBUG
  2001. // modal dialogs
  2002. INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
  2003. {
  2004. ATLASSERT(m_hWnd == NULL);
  2005. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT< TBase >*)this);
  2006. #ifdef _DEBUG
  2007. m_bModal = true;
  2008. #endif //_DEBUG
  2009. return AtlAxDialogBox(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
  2010. hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
  2011. }
  2012. BOOL EndDialog(int nRetCode)
  2013. {
  2014. ATLASSERT(::IsWindow(m_hWnd));
  2015. ATLASSERT(m_bModal); // must be a modal dialog
  2016. return ::EndDialog(m_hWnd, nRetCode);
  2017. }
  2018. // modeless dialogs
  2019. HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
  2020. {
  2021. ATLASSERT(m_hWnd == NULL);
  2022. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT< TBase >*)this);
  2023. #ifdef _DEBUG
  2024. m_bModal = false;
  2025. #endif //_DEBUG
  2026. HWND hWnd = AtlAxCreateDialog(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
  2027. hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
  2028. ATLASSERT(m_hWnd == hWnd);
  2029. return hWnd;
  2030. }
  2031. // for CComControl
  2032. HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL)
  2033. {
  2034. return Create(hWndParent, dwInitParam);
  2035. }
  2036. BOOL DestroyWindow()
  2037. {
  2038. ATLASSERT(::IsWindow(m_hWnd));
  2039. ATLASSERT(!m_bModal); // must not be a modal dialog
  2040. return ::DestroyWindow(m_hWnd);
  2041. }
  2042. };
  2043. #endif //_ATL_NO_HOSTING
  2044. /////////////////////////////////////////////////////////////////////////////
  2045. // CSimpleDialog - Prebuilt modal dialog that uses standard buttons
  2046. template <WORD t_wDlgTemplateID, BOOL t_bCenter = TRUE>
  2047. class CSimpleDialog : public CDialogImplBase
  2048. {
  2049. public:
  2050. INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
  2051. {
  2052. ATLASSERT(m_hWnd == NULL);
  2053. _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBase*)this);
  2054. INT_PTR nRet = ::DialogBox(_Module.GetResourceInstance(),
  2055. MAKEINTRESOURCE(t_wDlgTemplateID), hWndParent, (DLGPROC)StartDialogProc);
  2056. m_hWnd = NULL;
  2057. return nRet;
  2058. }
  2059. typedef CSimpleDialog<t_wDlgTemplateID, t_bCenter> thisClass;
  2060. BEGIN_MSG_MAP(thisClass)
  2061. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  2062. COMMAND_RANGE_HANDLER(IDOK, IDNO, OnCloseCmd)
  2063. END_MSG_MAP()
  2064. LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  2065. {
  2066. if(t_bCenter)
  2067. CenterWindow(GetParent());
  2068. return TRUE;
  2069. }
  2070. LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  2071. {
  2072. ::EndDialog(m_hWnd, wID);
  2073. return 0;
  2074. }
  2075. };
  2076. /////////////////////////////////////////////////////////////////////////////
  2077. // CContainedWindow - Implements a contained window
  2078. template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
  2079. class CContainedWindowT : public TBase
  2080. {
  2081. public:
  2082. CWndProcThunk m_thunk;
  2083. LPCTSTR m_lpszClassName;
  2084. WNDPROC m_pfnSuperWindowProc;
  2085. CMessageMap* m_pObject;
  2086. DWORD m_dwMsgMapID;
  2087. const MSG* m_pCurrentMsg;
  2088. // If you use this constructor you must supply
  2089. // the Window Class Name, Object* and Message Map ID
  2090. // Later to the Create call
  2091. CContainedWindowT() : m_pCurrentMsg(NULL)
  2092. { }
  2093. CContainedWindowT(LPTSTR lpszClassName, CMessageMap* pObject, DWORD dwMsgMapID = 0)
  2094. : m_lpszClassName(lpszClassName),
  2095. m_pfnSuperWindowProc(::DefWindowProc),
  2096. m_pObject(pObject), m_dwMsgMapID(dwMsgMapID),
  2097. m_pCurrentMsg(NULL)
  2098. { }
  2099. CContainedWindowT(CMessageMap* pObject, DWORD dwMsgMapID = 0)
  2100. : m_lpszClassName(TBase::GetWndClassName()),
  2101. m_pfnSuperWindowProc(::DefWindowProc),
  2102. m_pObject(pObject), m_dwMsgMapID(dwMsgMapID),
  2103. m_pCurrentMsg(NULL)
  2104. { }
  2105. void SwitchMessageMap(DWORD dwMsgMapID)
  2106. {
  2107. m_dwMsgMapID = dwMsgMapID;
  2108. }
  2109. const MSG* GetCurrentMessage() const
  2110. {
  2111. return m_pCurrentMsg;
  2112. }
  2113. LRESULT DefWindowProc()
  2114. {
  2115. const MSG* pMsg = m_pCurrentMsg;
  2116. LRESULT lRes = 0;
  2117. if (pMsg != NULL)
  2118. lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
  2119. return lRes;
  2120. }
  2121. LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  2122. {
  2123. #ifdef STRICT
  2124. return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  2125. #else
  2126. return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
  2127. #endif
  2128. }
  2129. static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg,
  2130. WPARAM wParam, LPARAM lParam)
  2131. {
  2132. CContainedWindowT< TBase >* pThis = (CContainedWindowT< TBase >*)_Module.ExtractCreateWndData();
  2133. ATLASSERT(pThis != NULL);
  2134. pThis->m_hWnd = hWnd;
  2135. pThis->m_thunk.Init(WindowProc, pThis);
  2136. WNDPROC pProc = (WNDPROC)(pThis->m_thunk.thunk.pThunk);
  2137. WNDPROC pOldProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pProc);
  2138. #ifdef _DEBUG
  2139. // check if somebody has subclassed us already since we discard it
  2140. if(pOldProc != StartWindowProc)
  2141. ATLTRACE2(atlTraceWindowing, 0, _T("Subclassing through a hook discarded.\n"));
  2142. #else
  2143. pOldProc; // avoid unused warning
  2144. #endif
  2145. return pProc(hWnd, uMsg, wParam, lParam);
  2146. }
  2147. static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2148. {
  2149. CContainedWindowT< TBase >* pThis = (CContainedWindowT< TBase >*)hWnd;
  2150. ATLASSERT(pThis->m_hWnd != NULL);
  2151. ATLASSERT(pThis->m_pObject != NULL);
  2152. // set a ptr to this message and save the old value
  2153. MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
  2154. const MSG* pOldMsg = pThis->m_pCurrentMsg;
  2155. pThis->m_pCurrentMsg = &msg;
  2156. // pass to the message map to process
  2157. LRESULT lRes;
  2158. BOOL bRet = pThis->m_pObject->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, pThis->m_dwMsgMapID);
  2159. // restore saved value for the current message
  2160. ATLASSERT(pThis->m_pCurrentMsg == &msg);
  2161. pThis->m_pCurrentMsg = pOldMsg;
  2162. // do the default processing if message was not handled
  2163. if(!bRet)
  2164. {
  2165. if(uMsg != WM_NCDESTROY)
  2166. lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  2167. else
  2168. {
  2169. // unsubclass, if needed
  2170. LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
  2171. lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  2172. if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
  2173. ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
  2174. // clear out window handle
  2175. pThis->m_hWnd = NULL;
  2176. }
  2177. }
  2178. return lRes;
  2179. }
  2180. ATOM RegisterWndSuperclass()
  2181. {
  2182. ATOM atom = 0;
  2183. LPTSTR szBuff = (LPTSTR)_alloca((lstrlen(m_lpszClassName) + 14) * sizeof(TCHAR));
  2184. WNDCLASSEX wc;
  2185. wc.cbSize = sizeof(WNDCLASSEX);
  2186. // Try global class
  2187. if(!::GetClassInfoEx(NULL, m_lpszClassName, &wc))
  2188. {
  2189. // try local class
  2190. if(!::GetClassInfoEx(_Module.GetModuleInstance(), m_lpszClassName, &wc))
  2191. return atom;
  2192. }
  2193. m_pfnSuperWindowProc = wc.lpfnWndProc;
  2194. lstrcpy(szBuff, _T("ATL:"));
  2195. lstrcat(szBuff, m_lpszClassName);
  2196. WNDCLASSEX wc1;
  2197. wc1.cbSize = sizeof(WNDCLASSEX);
  2198. atom = (ATOM)::GetClassInfoEx(_Module.GetModuleInstance(), szBuff, &wc1);
  2199. if(atom == 0) // register class
  2200. {
  2201. wc.lpszClassName = szBuff;
  2202. wc.lpfnWndProc = StartWindowProc;
  2203. wc.hInstance = _Module.GetModuleInstance();
  2204. wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
  2205. atom = ::RegisterClassEx(&wc);
  2206. }
  2207. return atom;
  2208. }
  2209. HWND Create(CMessageMap* pObject, DWORD dwMsgMapID, HWND hWndParent, RECT* prcPos,
  2210. LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0,
  2211. UINT nID = 0, LPVOID lpCreateParam = NULL)
  2212. {
  2213. m_lpszClassName = TBase::GetWndClassName();
  2214. m_pfnSuperWindowProc = ::DefWindowProc;
  2215. m_pObject = pObject;
  2216. m_dwMsgMapID = dwMsgMapID;
  2217. return Create(hWndParent, prcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  2218. }
  2219. HWND Create(LPCTSTR lpszClassName, CMessageMap* pObject, DWORD dwMsgMapID, HWND hWndParent, RECT* prcPos, LPCTSTR szWindowName = NULL,
  2220. DWORD dwStyle = 0, DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL)
  2221. {
  2222. m_lpszClassName = lpszClassName;
  2223. m_pfnSuperWindowProc = ::DefWindowProc;
  2224. m_pObject = pObject;
  2225. m_dwMsgMapID = dwMsgMapID;
  2226. return Create(hWndParent, prcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  2227. }
  2228. // This function is Deprecated, use the version
  2229. // which takes a RECT* instead
  2230. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  2231. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  2232. UINT nID = 0, LPVOID lpCreateParam = NULL)
  2233. {
  2234. return Create(hWndParent, &rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  2235. }
  2236. HWND Create(HWND hWndParent, RECT* prcPos, LPCTSTR szWindowName = NULL,
  2237. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  2238. UINT nID = 0, LPVOID lpCreateParam = NULL)
  2239. {
  2240. ATLASSERT(m_hWnd == NULL);
  2241. ATOM atom = RegisterWndSuperclass();
  2242. if(atom == 0)
  2243. return NULL;
  2244. _Module.AddCreateWndData(&m_thunk.cd, this);
  2245. dwStyle = TWinTraits::GetWndStyle(dwStyle);
  2246. dwExStyle = TWinTraits::GetWndExStyle(dwExStyle);
  2247. HWND hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWindowName,
  2248. dwStyle,
  2249. prcPos->left, prcPos->top,
  2250. prcPos->right - prcPos->left,
  2251. prcPos->bottom - prcPos->top,
  2252. hWndParent,
  2253. (nID == 0 && (dwStyle & WS_CHILD)) ? (HMENU)this : (HMENU)(DWORD_PTR)nID,
  2254. _Module.GetModuleInstance(), lpCreateParam);
  2255. ATLASSERT(m_hWnd == hWnd);
  2256. return hWnd;
  2257. }
  2258. BOOL SubclassWindow(HWND hWnd)
  2259. {
  2260. ATLASSERT(m_hWnd == NULL);
  2261. ATLASSERT(::IsWindow(hWnd));
  2262. m_thunk.Init(WindowProc, this);
  2263. WNDPROC pProc = (WNDPROC)m_thunk.thunk.pThunk;
  2264. WNDPROC pfnWndProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pProc);
  2265. if(pfnWndProc == NULL)
  2266. return FALSE;
  2267. m_pfnSuperWindowProc = pfnWndProc;
  2268. m_hWnd = hWnd;
  2269. return TRUE;
  2270. }
  2271. // Use only if you want to subclass before window is destroyed,
  2272. // WindowProc will automatically subclass when window goes away
  2273. HWND UnsubclassWindow(BOOL bForce = FALSE)
  2274. {
  2275. ATLASSERT(m_hWnd != NULL);
  2276. WNDPROC pOurProc = (WNDPROC)(m_thunk.thunk.pThunk);
  2277. WNDPROC pActiveProc = (WNDPROC)::GetWindowLongPtr(m_hWnd, GWLP_WNDPROC);
  2278. HWND hWnd = NULL;
  2279. if (bForce || pOurProc == pActiveProc)
  2280. {
  2281. if(!::SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pfnSuperWindowProc))
  2282. return NULL;
  2283. m_pfnSuperWindowProc = ::DefWindowProc;
  2284. hWnd = m_hWnd;
  2285. m_hWnd = NULL;
  2286. }
  2287. return hWnd;
  2288. }
  2289. };
  2290. typedef CContainedWindowT<CWindow> CContainedWindow;
  2291. /////////////////////////////////////////////////////////////////////////////
  2292. // _DialogSizeHelper - helpers for calculating the size of a dialog template
  2293. class _DialogSizeHelper
  2294. {
  2295. public:
  2296. //local struct used for implementation
  2297. #pragma pack(push, 1)
  2298. struct _ATL_DLGTEMPLATEEX
  2299. {
  2300. WORD dlgVer;
  2301. WORD signature;
  2302. DWORD helpID;
  2303. DWORD exStyle;
  2304. DWORD style;
  2305. WORD cDlgItems;
  2306. short x;
  2307. short y;
  2308. short cx;
  2309. short cy;
  2310. };
  2311. #pragma pack(pop)
  2312. static void GetDialogSize(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  2313. {
  2314. // If the dialog has a font we use it otherwise we default
  2315. // to the system font.
  2316. if (HasFont(pTemplate))
  2317. {
  2318. TCHAR szFace[LF_FACESIZE];
  2319. WORD wFontSize = 0;
  2320. GetFont(pTemplate, szFace, &wFontSize);
  2321. GetSizeInDialogUnits(pTemplate, pSize);
  2322. ConvertDialogUnitsToPixels(szFace, wFontSize, pSize);
  2323. }
  2324. else
  2325. {
  2326. GetSizeInDialogUnits(pTemplate, pSize);
  2327. LONG nDlgBaseUnits = GetDialogBaseUnits();
  2328. pSize->cx = MulDiv(pSize->cx, LOWORD(nDlgBaseUnits), 4);
  2329. pSize->cy = MulDiv(pSize->cy, HIWORD(nDlgBaseUnits), 8);
  2330. }
  2331. }
  2332. static void ConvertDialogUnitsToPixels(LPCTSTR pszFontFace, WORD wFontSize, SIZE* pSizePixel)
  2333. {
  2334. // Attempt to create the font to be used in the dialog box
  2335. UINT cxSysChar, cySysChar;
  2336. LOGFONT lf;
  2337. HDC hDC = ::GetDC(NULL);
  2338. int cxDlg = pSizePixel->cx;
  2339. int cyDlg = pSizePixel->cy;
  2340. ZeroMemory(&lf, sizeof(LOGFONT));
  2341. lf.lfHeight = -MulDiv(wFontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  2342. lf.lfWeight = FW_NORMAL;
  2343. lf.lfCharSet = DEFAULT_CHARSET;
  2344. lstrcpy(lf.lfFaceName, pszFontFace);
  2345. HFONT hNewFont = CreateFontIndirect(&lf);
  2346. if (hNewFont != NULL)
  2347. {
  2348. TEXTMETRIC tm;
  2349. SIZE size;
  2350. HFONT hFontOld = (HFONT)SelectObject(hDC, hNewFont);
  2351. GetTextMetrics(hDC, &tm);
  2352. cySysChar = tm.tmHeight + tm.tmExternalLeading;
  2353. ::GetTextExtentPoint(hDC,
  2354. _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52,
  2355. &size);
  2356. cxSysChar = (size.cx + 26) / 52;
  2357. SelectObject(hDC, hFontOld);
  2358. DeleteObject(hNewFont);
  2359. }
  2360. else
  2361. {
  2362. // Could not create the font so just use the system's values
  2363. cxSysChar = LOWORD(GetDialogBaseUnits());
  2364. cySysChar = HIWORD(GetDialogBaseUnits());
  2365. }
  2366. ::ReleaseDC(NULL, hDC);
  2367. // Translate dialog units to pixels
  2368. pSizePixel->cx = MulDiv(cxDlg, cxSysChar, 4);
  2369. pSizePixel->cy = MulDiv(cyDlg, cySysChar, 8);
  2370. }
  2371. static BOOL IsDialogEx(const DLGTEMPLATE* pTemplate)
  2372. {
  2373. return ((_ATL_DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
  2374. }
  2375. static BOOL HasFont(const DLGTEMPLATE* pTemplate)
  2376. {
  2377. return (DS_SETFONT &
  2378. (IsDialogEx(pTemplate) ?
  2379. ((_ATL_DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style));
  2380. }
  2381. static BYTE* GetFontSizeField(const DLGTEMPLATE* pTemplate)
  2382. {
  2383. BOOL bDialogEx = IsDialogEx(pTemplate);
  2384. WORD* pw;
  2385. if (bDialogEx)
  2386. pw = (WORD*)((_ATL_DLGTEMPLATEEX*)pTemplate + 1);
  2387. else
  2388. pw = (WORD*)(pTemplate + 1);
  2389. if (*pw == (WORD)-1) // Skip menu name string or ordinal
  2390. pw += 2; // WORDs
  2391. else
  2392. while(*pw++);
  2393. if (*pw == (WORD)-1) // Skip class name string or ordinal
  2394. pw += 2; // WORDs
  2395. else
  2396. while(*pw++);
  2397. while (*pw++); // Skip caption string
  2398. return (BYTE*)pw;
  2399. }
  2400. static BOOL GetFont(const DLGTEMPLATE* pTemplate, TCHAR* pszFace, WORD* pFontSize)
  2401. {
  2402. USES_CONVERSION;
  2403. if (!HasFont(pTemplate))
  2404. return FALSE;
  2405. BYTE* pb = GetFontSizeField(pTemplate);
  2406. *pFontSize = *(WORD*)pb;
  2407. // Skip over font attributes to get to the font name
  2408. pb += sizeof(WORD) * (IsDialogEx(pTemplate) ? 3 : 1);
  2409. _tcscpy(pszFace, W2T((WCHAR*)pb));
  2410. return TRUE;
  2411. }
  2412. static void GetSizeInDialogUnits(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  2413. {
  2414. if (IsDialogEx(pTemplate))
  2415. {
  2416. pSize->cx = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cx;
  2417. pSize->cy = ((_ATL_DLGTEMPLATEEX*)pTemplate)->cy;
  2418. }
  2419. else
  2420. {
  2421. pSize->cx = pTemplate->cx;
  2422. pSize->cy = pTemplate->cy;
  2423. }
  2424. }
  2425. };
  2426. inline void AtlGetDialogSize(const DLGTEMPLATE* pTemplate, SIZE* pSize)
  2427. {
  2428. _DialogSizeHelper::GetDialogSize(pTemplate, pSize);
  2429. }
  2430. }; //namespace ATL
  2431. #ifndef _ATL_DLL_IMPL
  2432. #ifndef _ATL_DLL
  2433. #define _ATLWIN_IMPL
  2434. #endif
  2435. #endif
  2436. #endif // __ATLWIN_H__
  2437. //All exports go here
  2438. #ifdef _ATLWIN_IMPL
  2439. #ifndef _ATL_DLL_IMPL
  2440. namespace ATL
  2441. {
  2442. #endif
  2443. ATLINLINE ATLAPI_(ATOM) AtlModuleRegisterWndClassInfoA(_ATL_MODULE* pM, _ATL_WNDCLASSINFOA* p, WNDPROC* pProc)
  2444. {
  2445. if (p->m_atom == 0)
  2446. {
  2447. ::EnterCriticalSection(&pM->m_csWindowCreate);
  2448. if(p->m_atom == 0)
  2449. {
  2450. HINSTANCE hInst = pM->m_hInst;
  2451. if (p->m_lpszOrigName != NULL)
  2452. {
  2453. ATLASSERT(pProc != NULL);
  2454. LPCSTR lpsz = p->m_wc.lpszClassName;
  2455. WNDPROC proc = p->m_wc.lpfnWndProc;
  2456. WNDCLASSEXA wc;
  2457. wc.cbSize = sizeof(WNDCLASSEX);
  2458. // Try global class
  2459. if(!::GetClassInfoExA(NULL, p->m_lpszOrigName, &wc))
  2460. {
  2461. // try process local
  2462. if(!::GetClassInfoExA(_Module.GetModuleInstance(), p->m_lpszOrigName, &wc))
  2463. {
  2464. ::LeaveCriticalSection(&pM->m_csWindowCreate);
  2465. return 0;
  2466. }
  2467. }
  2468. memcpy(&p->m_wc, &wc, sizeof(WNDCLASSEX));
  2469. p->pWndProc = p->m_wc.lpfnWndProc;
  2470. p->m_wc.lpszClassName = lpsz;
  2471. p->m_wc.lpfnWndProc = proc;
  2472. }
  2473. else
  2474. {
  2475. p->m_wc.hCursor = ::LoadCursorA(p->m_bSystemCursor ? NULL : hInst,
  2476. p->m_lpszCursorID);
  2477. }
  2478. p->m_wc.hInstance = hInst;
  2479. p->m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
  2480. if (p->m_wc.lpszClassName == NULL)
  2481. {
  2482. #ifdef _WIN64 // %p isn't available on Win2k/Win9x
  2483. wsprintfA(p->m_szAutoName, "ATL:%p", &p->m_wc);
  2484. #else
  2485. wsprintfA(p->m_szAutoName, "ATL:%8.8X", PtrToUlong(&p->m_wc));
  2486. #endif
  2487. p->m_wc.lpszClassName = p->m_szAutoName;
  2488. }
  2489. WNDCLASSEXA wcTemp;
  2490. memcpy(&wcTemp, &p->m_wc, sizeof(WNDCLASSEXW));
  2491. p->m_atom = (ATOM)::GetClassInfoExA(p->m_wc.hInstance, p->m_wc.lpszClassName, &wcTemp);
  2492. if (p->m_atom == 0)
  2493. p->m_atom = ::RegisterClassExA(&p->m_wc);
  2494. }
  2495. ::LeaveCriticalSection(&pM->m_csWindowCreate);
  2496. }
  2497. if (p->m_lpszOrigName != NULL)
  2498. {
  2499. ATLASSERT(pProc != NULL);
  2500. ATLASSERT(p->pWndProc != NULL);
  2501. *pProc = p->pWndProc;
  2502. }
  2503. return p->m_atom;
  2504. }
  2505. ATLINLINE ATLAPI_(ATOM) AtlModuleRegisterWndClassInfoW(_ATL_MODULE* pM, _ATL_WNDCLASSINFOW* p, WNDPROC* pProc)
  2506. {
  2507. if (p->m_atom == 0)
  2508. {
  2509. ::EnterCriticalSection(&pM->m_csWindowCreate);
  2510. if(p->m_atom == 0)
  2511. {
  2512. HINSTANCE hInst = pM->m_hInst;
  2513. if (p->m_lpszOrigName != NULL)
  2514. {
  2515. ATLASSERT(pProc != NULL);
  2516. LPCWSTR lpsz = p->m_wc.lpszClassName;
  2517. WNDPROC proc = p->m_wc.lpfnWndProc;
  2518. WNDCLASSEXW wc;
  2519. wc.cbSize = sizeof(WNDCLASSEX);
  2520. // Try global class
  2521. if(!::GetClassInfoExW(NULL, p->m_lpszOrigName, &wc))
  2522. {
  2523. // try process local
  2524. if(!::GetClassInfoExW(_Module.GetModuleInstance(), p->m_lpszOrigName, &wc))
  2525. {
  2526. ::LeaveCriticalSection(&pM->m_csWindowCreate);
  2527. return 0;
  2528. }
  2529. }
  2530. memcpy(&p->m_wc, &wc, sizeof(WNDCLASSEX));
  2531. p->pWndProc = p->m_wc.lpfnWndProc;
  2532. p->m_wc.lpszClassName = lpsz;
  2533. p->m_wc.lpfnWndProc = proc;
  2534. }
  2535. else
  2536. {
  2537. p->m_wc.hCursor = ::LoadCursorW(p->m_bSystemCursor ? NULL : hInst,
  2538. p->m_lpszCursorID);
  2539. }
  2540. p->m_wc.hInstance = hInst;
  2541. p->m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes
  2542. if (p->m_wc.lpszClassName == NULL)
  2543. {
  2544. #ifdef _WIN64 // %p isn't available on Win2k/Win9x
  2545. wsprintfW(p->m_szAutoName, L"ATL:%p", &p->m_wc);
  2546. #else
  2547. wsprintfW(p->m_szAutoName, L"ATL:%8.8X", PtrToUlong(&p->m_wc));
  2548. #endif
  2549. p->m_wc.lpszClassName = p->m_szAutoName;
  2550. }
  2551. WNDCLASSEXW wcTemp;
  2552. memcpy(&wcTemp, &p->m_wc, sizeof(WNDCLASSEXW));
  2553. p->m_atom = (ATOM)::GetClassInfoExW(p->m_wc.hInstance, p->m_wc.lpszClassName, &wcTemp);
  2554. if (p->m_atom == 0)
  2555. p->m_atom = ::RegisterClassExW(&p->m_wc);
  2556. }
  2557. ::LeaveCriticalSection(&pM->m_csWindowCreate);
  2558. }
  2559. if (p->m_lpszOrigName != NULL)
  2560. {
  2561. ATLASSERT(pProc != NULL);
  2562. ATLASSERT(p->pWndProc != NULL);
  2563. *pProc = p->pWndProc;
  2564. }
  2565. return p->m_atom;
  2566. }
  2567. ATLINLINE ATLAPI_(HDC) AtlCreateTargetDC(HDC hdc, DVTARGETDEVICE* ptd)
  2568. {
  2569. USES_CONVERSION;
  2570. // cases hdc, ptd, hdc is metafile, hic
  2571. // NULL, NULL, n/a, Display
  2572. // NULL, !NULL, n/a, ptd
  2573. // !NULL, NULL, FALSE, hdc
  2574. // !NULL, NULL, TRUE, display
  2575. // !NULL, !NULL, FALSE, ptd
  2576. // !NULL, !NULL, TRUE, ptd
  2577. if (ptd != NULL)
  2578. {
  2579. LPDEVMODEOLE lpDevMode;
  2580. LPOLESTR lpszDriverName;
  2581. LPOLESTR lpszDeviceName;
  2582. LPOLESTR lpszPortName;
  2583. if (ptd->tdExtDevmodeOffset == 0)
  2584. lpDevMode = NULL;
  2585. else
  2586. lpDevMode = (LPDEVMODEOLE) ((LPSTR)ptd + ptd->tdExtDevmodeOffset);
  2587. lpszDriverName = (LPOLESTR)((BYTE*)ptd + ptd->tdDriverNameOffset);
  2588. lpszDeviceName = (LPOLESTR)((BYTE*)ptd + ptd->tdDeviceNameOffset);
  2589. lpszPortName = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  2590. return ::CreateDC(OLE2CT(lpszDriverName), OLE2CT(lpszDeviceName),
  2591. OLE2CT(lpszPortName), DEVMODEOLE2T(lpDevMode));
  2592. }
  2593. else if (hdc == NULL || GetDeviceCaps(hdc, TECHNOLOGY) == DT_METAFILE)
  2594. return ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
  2595. else
  2596. return hdc;
  2597. }
  2598. ATLINLINE ATLAPI_(void) AtlHiMetricToPixel(const SIZEL * lpSizeInHiMetric, LPSIZEL lpSizeInPix)
  2599. {
  2600. int nPixelsPerInchX; // Pixels per logical inch along width
  2601. int nPixelsPerInchY; // Pixels per logical inch along height
  2602. HDC hDCScreen = GetDC(NULL);
  2603. if (hDCScreen) {
  2604. nPixelsPerInchX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
  2605. nPixelsPerInchY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
  2606. ReleaseDC(NULL, hDCScreen);
  2607. } else {
  2608. nPixelsPerInchX = nPixelsPerInchY = 1;
  2609. }
  2610. lpSizeInPix->cx = MAP_LOGHIM_TO_PIX(lpSizeInHiMetric->cx, nPixelsPerInchX);
  2611. lpSizeInPix->cy = MAP_LOGHIM_TO_PIX(lpSizeInHiMetric->cy, nPixelsPerInchY);
  2612. }
  2613. ATLINLINE ATLAPI_(void) AtlPixelToHiMetric(const SIZEL * lpSizeInPix, LPSIZEL lpSizeInHiMetric)
  2614. {
  2615. int nPixelsPerInchX; // Pixels per logical inch along width
  2616. int nPixelsPerInchY; // Pixels per logical inch along height
  2617. HDC hDCScreen = GetDC(NULL);
  2618. if (hDCScreen) {
  2619. nPixelsPerInchX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
  2620. nPixelsPerInchY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
  2621. ReleaseDC(NULL, hDCScreen);
  2622. } else {
  2623. nPixelsPerInchX = nPixelsPerInchY = 1;
  2624. }
  2625. lpSizeInHiMetric->cx = MAP_PIX_TO_LOGHIM(lpSizeInPix->cx, nPixelsPerInchX);
  2626. lpSizeInHiMetric->cy = MAP_PIX_TO_LOGHIM(lpSizeInPix->cy, nPixelsPerInchY);
  2627. }
  2628. #ifndef _ATL_DLL_IMPL
  2629. }; //namespace ATL
  2630. #endif
  2631. //Prevent pulling in second time
  2632. #undef _ATLWIN_IMPL
  2633. #endif // _ATLWIN_IMPL