home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / ATL / include / Atlwin.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  89.7 KB  |  3,373 lines

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