Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
15 KiB

  1. #ifndef __VWINDOW_HPP
  2. #define __VWINDOW_HPP
  3. #ifndef VWCL_WRAP_WINDOWS_ONLY
  4. #include "vApplication.hpp"
  5. #endif
  6. #include "vRTTI.hpp"
  7. #include <commctrl.h>
  8. class VWindow;
  9. typedef struct tagVWCL_ENUM_PARAM
  10. {
  11. UINT nMessageOrID;
  12. LPVOID lpInData; // Normally input pointer
  13. LPVOID lpOutData; // Normally output pointer
  14. } VWCL_ENUM_PARAM;
  15. // <VDOC<CLASS=VWindow><BASE=VRTTI><DESC=Base window object encapsulation><FAMILY=VWCL Core><AUTHOR=Todd Osborne ([email protected])>VDOC>
  16. class VWindow : public VRTTI
  17. {
  18. #ifndef VWCL_WRAP_WINDOWS_ONLY
  19. friend class VApplication;
  20. #endif
  21. public:
  22. VWindow(UINT nRTTI = VWCL_RTTI_WINDOW)
  23. : VRTTI(nRTTI)
  24. {
  25. m_hWindow = NULL;
  26. #ifndef VWCL_WRAP_WINDOWS_ONLY
  27. m_lpfnOldWndProc = NULL;
  28. #endif
  29. }
  30. virtual ~VWindow()
  31. {
  32. #ifndef VWCL_WRAP_WINDOWS_ONLY
  33. DestroyWindow();
  34. #endif
  35. }
  36. // Returns HWND
  37. operator HWND ()
  38. { return GetSafeWindow(); }
  39. #ifndef VWCL_WRAP_WINDOWS_ONLY
  40. // Attach an existing Windows window to a VWindow object, subclassing it routing messages through the object
  41. BOOL Attach(HWND hWnd);
  42. #else
  43. // Simply assign hWnd to this object, but do not subclass it
  44. HWND Attach(HWND hWnd)
  45. { assert(hWnd && ::IsWindow(hWnd)); m_hWindow = hWnd; return m_hWindow; }
  46. #endif
  47. // Center a window on screen
  48. void CenterWindow()
  49. {
  50. assert(GetSafeWindow());
  51. // Center a window on screen
  52. RECT r;
  53. GetWindowRect(&r);
  54. SetWindowPos( m_hWindow,
  55. HWND_TOP,
  56. ((GetSystemMetrics(SM_CXSCREEN) - (r.right - r.left)) / 2),
  57. ((GetSystemMetrics(SM_CYSCREEN) - (r.bottom - r.top)) / 2),
  58. 0,
  59. 0,
  60. SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
  61. }
  62. void CheckDlgButton(int nID, UINT nCheck = BST_CHECKED)
  63. { assert(GetSafeWindow()); ::CheckDlgButton(m_hWindow, nID, nCheck); }
  64. BOOL ClientToScreen(LPPOINT lpPoint)
  65. { assert(GetSafeWindow() && lpPoint); return ::ClientToScreen(m_hWindow, lpPoint); }
  66. #ifndef VWCL_WRAP_WINDOWS_ONLY
  67. // Lowest common denominator of window creation functions
  68. BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, LPRECT lpRect, HWND hWndParent, UINT nIDorMenu, BOOL bDontCallPostCreateWindow = FALSE);
  69. #endif
  70. virtual BOOL DestroyWindow()
  71. { if ( GetSafeWindow() ) return ::DestroyWindow(m_hWindow); return FALSE; }
  72. #ifndef VWCL_WRAP_WINDOWS_ONLY
  73. // Detach an existing Windows window with an associated VWindow object, removing any subclassing, and restore to previous state
  74. void Detach();
  75. #else
  76. // Simply remove the window handle from object
  77. void Detach()
  78. { m_hWindow = NULL; }
  79. #endif
  80. BOOL EnableWindow(BOOL bEnable = TRUE)
  81. { assert(GetSafeWindow()); return ::EnableWindow(m_hWindow, bEnable); }
  82. #ifndef VWCL_WRAP_WINDOWS_ONLY
  83. // Enter a message loop
  84. WPARAM EnterMessageLoop(HACCEL hAccel)
  85. {
  86. MSG msg;
  87. // Enter message loop
  88. while ( GetMessage(&msg, NULL, 0, 0) != 0 )
  89. {
  90. if ( hAccel == NULL || hAccel && TranslateAccelerator(m_hWindow, hAccel, &msg) == 0 )
  91. HandleMessage(&msg);
  92. }
  93. return msg.wParam;
  94. }
  95. #endif
  96. // Find a child window when the class is known
  97. HWND FindChildWindowByClass(LPCTSTR lpszClass)
  98. {
  99. assert(lpszClass && lstrlen(lpszClass));
  100. // Iterate child windows
  101. VWCL_ENUM_PARAM EnumParam = {ENUM_FIND_CHILD_BY_CLASS, (LPVOID)lpszClass, NULL};
  102. EnumChildWindows(m_hWindow, (WNDENUMPROC)EnumChildWndProc, (LPARAM)&EnumParam);
  103. // EnumParam.lpOutData will be non-NULL if a handle was found
  104. if ( EnumParam.lpOutData )
  105. return (HWND)EnumParam.lpOutData;
  106. return NULL;
  107. }
  108. HWND GetDlgItem(int nID)
  109. { assert(GetSafeWindow()); return ::GetDlgItem(m_hWindow, nID); }
  110. UINT GetDlgItemInt(int nID, LPBOOL lpTranslated = NULL, BOOL bSigned = FALSE)
  111. { assert(GetSafeWindow()); return ::GetDlgItemInt(m_hWindow, nID, lpTranslated, bSigned); }
  112. int GetDlgItemText(int nID, LPTSTR lpszBuffer, int nSizeOfBuffer)
  113. { assert(GetSafeWindow()); return ::GetDlgItemText(m_hWindow, nID, lpszBuffer, nSizeOfBuffer); }
  114. HFONT GetFont()
  115. { assert(GetSafeWindow()); return (HFONT)::SendMessage(m_hWindow, WM_GETFONT, 0, 0); }
  116. HMENU GetMenu()
  117. { assert(GetSafeWindow()); return ::GetMenu(m_hWindow); }
  118. HWND GetParent()
  119. { assert(GetSafeWindow()); return ::GetParent(m_hWindow); }
  120. HWND GetSafeWindow()
  121. { return (IsWindow()) ? m_hWindow : NULL; }
  122. LONG GetStyle()
  123. { return GetWindowLong(GWL_STYLE); }
  124. LONG GetWindowLong(int nIndex)
  125. { assert(GetSafeWindow()); return ::GetWindowLong(m_hWindow, nIndex); }
  126. #ifdef WIN32
  127. BOOL GetClientRect(LPRECT lpRect)
  128. { assert(lpRect && GetSafeWindow()); return ::GetClientRect(m_hWindow, lpRect); }
  129. BOOL GetWindowRect(LPRECT lpRect)
  130. { assert(lpRect && GetSafeWindow()); return ::GetWindowRect(m_hWindow, lpRect); }
  131. #else
  132. void GetClientRect(LPRECT lpRect)
  133. { assert(lpRect && GetSafeWindow()); ::GetClientRect(m_hWindow, lpRect); }
  134. void GetWindowRect(LPRECT lpRect)
  135. { assert(lpRect && GetSafeWindow()); ::GetWindowRect(m_hWindow, lpRect); }
  136. #endif
  137. #ifndef VWCL_WRAP_WINDOWS_ONLY
  138. // Called from a VWindow class that implements a message loop
  139. virtual void HandleMessage(LPMSG lpMsg)
  140. {
  141. assert(lpMsg);
  142. // Called from a VWindow derived class that implements a message loop
  143. if ( !PreTranslateMessage(lpMsg) )
  144. {
  145. TranslateMessage(lpMsg);
  146. DispatchMessage(lpMsg);
  147. }
  148. }
  149. #endif
  150. void InvalidateRect(LPRECT lpRect = NULL, BOOL bErase = TRUE)
  151. { assert(GetSafeWindow()); ::InvalidateRect(m_hWindow, lpRect, bErase); }
  152. // Return TRUE if the object is a VDialog type (That is, a VDialogXXX class, not all VDialog derivitives)
  153. BOOL IsVDialogType()
  154. {
  155. switch ( RTTI() )
  156. {
  157. // Top level window is a dialog
  158. case VWindow::VWCL_RTTI_DIALOG:
  159. case VWindow::VWCL_RTTI_MAIN_DIALOG:
  160. case VWindow::VWCL_RTTI_SPLIT_MAIN_DIALOG:
  161. case VWindow::VWCL_RTTI_SPLIT_DIALOG:
  162. return TRUE;
  163. }
  164. return FALSE;
  165. }
  166. UINT IsDlgButtonChecked(int nID)
  167. { assert(GetSafeWindow()); return ::IsDlgButtonChecked(m_hWindow, nID); }
  168. BOOL IsIconic()
  169. { assert(GetSafeWindow()); return ::IsIconic(m_hWindow); }
  170. BOOL IsWindow()
  171. { return (m_hWindow) ? ::IsWindow(m_hWindow) : FALSE; }
  172. BOOL IsWindowEnabled()
  173. { assert(GetSafeWindow()); return ::IsWindowEnabled(m_hWindow); }
  174. BOOL IsWindowVisible()
  175. { assert(GetSafeWindow()); return ::IsWindowVisible(m_hWindow); }
  176. int MessageBox(LPCTSTR lpcszText, LPCTSTR lpcszCaption, UINT nType = MB_OK)
  177. { int nResult; HWND hWndFocus = GetFocus(); nResult = ::MessageBox(m_hWindow, lpcszText, lpcszCaption, nType); if ( hWndFocus ) ::SetFocus(hWndFocus); return nResult; }
  178. int MessageBox(LPCTSTR lpcszText, UINT nType = MB_OK)
  179. { return MessageBox(lpcszText, VGetAppTitle(), nType); }
  180. // If VString.hpp is included, implement these functions
  181. #ifdef __VSTRING_HPP
  182. int MessageBox(UINT nStringID, UINT nType = MB_OK, HINSTANCE hResource = NULL)
  183. { return MessageBox(VString(nStringID, hResource), nType); }
  184. int MessageBox(UINT nStringID, LPCTSTR lpcszCaption, UINT nType = MB_OK, HINSTANCE hResource = NULL)
  185. { return MessageBox(VString(nStringID, hResource), lpcszCaption, nType); }
  186. int MessageBox(UINT nStringID, UINT nCaptionID, UINT nType, HINSTANCE hResource = NULL)
  187. { return MessageBox(VString(nStringID, hResource), VString(nCaptionID, hResource), nType); }
  188. #endif
  189. BOOL MoveWindow(int x, int y, int cx, int cy, BOOL bRedraw = TRUE)
  190. { assert(GetSafeWindow()); return ::MoveWindow(m_hWindow, x, y, cx, cy, bRedraw); }
  191. BOOL MoveWindow(LPRECT lpRect, BOOL bRedraw = TRUE)
  192. { assert(lpRect); assert(GetSafeWindow()); return ::MoveWindow(m_hWindow, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, bRedraw); }
  193. BOOL PostMessage(UINT nMessage, WPARAM wParam, LPARAM lParam)
  194. { assert(GetSafeWindow()); return ::PostMessage(m_hWindow, nMessage, wParam, lParam); }
  195. // Override to allow user to call IsDialogMessage() or perform other
  196. // processing before message is dispatched. Return TRUE if message was processed
  197. virtual BOOL PreTranslateMessage(LPMSG lpMsg)
  198. { return FALSE; }
  199. BOOL ReleaseCapture()
  200. { assert(GetSafeWindow()); return ::ReleaseCapture(); }
  201. BOOL ScreenToClient(LPPOINT lpPoint)
  202. { assert(GetSafeWindow() && lpPoint); return ::ScreenToClient(m_hWindow, lpPoint); }
  203. LRESULT SendDlgItemMessage(UINT nID, UINT nMessage, WPARAM wParam, LPARAM lParam)
  204. { assert(GetSafeWindow()); return ::SendDlgItemMessage(m_hWindow, nID, nMessage, wParam, lParam); }
  205. LRESULT SendMessage(UINT nMessage, WPARAM wParam, LPARAM lParam)
  206. { assert(GetSafeWindow()); return ::SendMessage(m_hWindow, nMessage, wParam, lParam); }
  207. HWND SetCapture()
  208. { assert(GetSafeWindow()); return ::SetCapture(m_hWindow); }
  209. BOOL SetDlgItemInt(int nID, UINT nValue, BOOL bSigned = FALSE)
  210. { assert(GetSafeWindow()); return ::SetDlgItemInt(m_hWindow, nID, nValue, bSigned); }
  211. #ifdef WIN32
  212. BOOL SetDlgItemText(int nID, LPCTSTR lpszText)
  213. { assert(GetSafeWindow()); return ::SetDlgItemText(m_hWindow, nID, lpszText); }
  214. #else
  215. void SetDlgItemText(int nID, LPCTSTR lpszText)
  216. { assert(GetSafeWindow()); ::SetDlgItemText(m_hWindow, nID, lpszText); }
  217. #endif
  218. HWND SetFocus()
  219. { assert(GetSafeWindow()); return ::SetFocus(m_hWindow); }
  220. BOOL SetMenu(HMENU hMenu)
  221. { assert(GetSafeWindow()); return ::SetMenu(m_hWindow, hMenu); }
  222. LONG SetStyle(DWORD dwStyle)
  223. { return SetWindowLong(GWL_STYLE, dwStyle); }
  224. LONG SetWindowLong(int nIndex, LONG nNewLong)
  225. { assert(GetSafeWindow()); return ::SetWindowLong(m_hWindow, nIndex, nNewLong); }
  226. #if defined(_WIN64)
  227. LONG_PTR SetWindowLongPtr(int nIndex, LONG_PTR nNewLongPtr)
  228. { assert(GetSafeWindow()); return ::SetWindowLongPtr(m_hWindow, nIndex, nNewLongPtr); }
  229. #endif
  230. #ifdef WIN32
  231. BOOL SetWindowText(LPCTSTR lpszText)
  232. { assert(GetSafeWindow()); return ::SetWindowText(m_hWindow, lpszText); }
  233. #else
  234. void SetWindowText(LPCTSTR lpszText)
  235. { assert(GetSafeWindow()); ::SetWindowText(m_hWindow, lpszText); }
  236. #endif
  237. BOOL ShowWindow(int nCmdShow = SW_SHOWNORMAL)
  238. { assert(GetSafeWindow()); return ::ShowWindow(m_hWindow, nCmdShow); }
  239. #ifdef WIN32
  240. BOOL UpdateWindow()
  241. { assert(GetSafeWindow()); return ::UpdateWindow(m_hWindow); }
  242. #else
  243. void UpdateWindow()
  244. { assert(GetSafeWindow()); ::UpdateWindow(m_hWindow); }
  245. #endif
  246. #ifndef VWCL_WRAP_WINDOWS_ONLY
  247. // Window procedure
  248. virtual LRESULT WindowProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam);
  249. #endif
  250. // Fast Runtime Type Information supported on ALL compilers
  251. // Implemented int VRTTI base class for VWindow and derived classes
  252. enum { VWCL_RTTI_UNKNOWN,
  253. VWCL_RTTI_BUTTON,
  254. VWCL_RTTI_CHECKBOX,
  255. VWCL_RTTI_COMBOBOX,
  256. VWCL_RTTI_DIALOG,
  257. VWCL_RTTI_EDIT,
  258. VWCL_RTTI_GROUPBOX,
  259. VWCL_RTTI_LISTBOX,
  260. VWCL_RTTI_LISTVIEW_CTRL,
  261. VWCL_RTTI_MAIN_DIALOG,
  262. VWCL_RTTI_MAIN_WINDOW,
  263. VWCL_RTTI_PAGE_SETUP_DIALOG,
  264. VWCL_RTTI_PRINT_DIALOG,
  265. VWCL_RTTI_PRINT_SETUP_DIALOG,
  266. VWCL_RTTI_RADIO_BUTTON,
  267. VWCL_RTTI_SCROLLBAR,
  268. VWCL_RTTI_SPLASH_WINDOW,
  269. VWCL_RTTI_SPLIT_MAIN_DIALOG,
  270. VWCL_RTTI_SPLIT_MAIN_WINDOW,
  271. VWCL_RTTI_SPLIT_WINDOW,
  272. VWCL_RTTI_SS_TREE_CTRL,
  273. VWCL_RTTI_STATIC,
  274. VWCL_RTTI_STATUSBAR_CTRL,
  275. VWCL_RTTI_TAB_CTRL,
  276. VWCL_RTTI_TAB_CTRL_WINDOW,
  277. VWCL_RTTI_TOOLBAR_CTRL,
  278. VWCL_RTTI_TREE_CTRL,
  279. VWCL_RTTI_WINDOW,
  280. VWCL_RTTI_SPLIT_DIALOG,
  281. VWCL_RTTI_SHELL_TAB_WINDOW,
  282. VWCL_RTTI_MINI_WINDOW,
  283. VWCL_RTTI_DIRECTORY_TREE_CTRL,
  284. VWCL_RTTI_XTREE_CTRL,
  285. VWCL_RTTI_XEDIT,
  286. VWCL_RTTI_SS_INDEXED_TREE_CTRL,
  287. VWCL_RTTI_PROPERTY_SHEET,
  288. VWCL_RTTI_PROPERTY_PAGE,
  289. VWCL_RTTI_PROGRESS_CTRL,
  290. };
  291. // Handle this object encapsulates
  292. HWND m_hWindow;
  293. #ifndef VWCL_WRAP_WINDOWS_ONLY
  294. // For subclased windows, the old Window Procedure
  295. WNDPROC m_lpfnOldWndProc;
  296. #endif
  297. // Enumeration is VWLC_ENUM_PARAM::nMessageOrID in EnumChildWndProc() call
  298. enum { ENUM_FIND_CHILD_BY_CLASS = WM_USER + 4096,
  299. };
  300. protected:
  301. // Enumerate child windows (for various reasons). LPARAM is a pointer to a VWLC_ENUM_PARAM struct
  302. static BOOL CALLBACK EnumChildWndProc(HWND hWnd, LPARAM lParam)
  303. {
  304. VWCL_ENUM_PARAM* pEnumParam = (VWCL_ENUM_PARAM*)lParam;
  305. assert(pEnumParam);
  306. // Determine what we need to do
  307. switch ( pEnumParam->nMessageOrID )
  308. {
  309. case WM_DESTROY:
  310. ::DestroyWindow(hWnd);
  311. break;
  312. case ENUM_FIND_CHILD_BY_CLASS:
  313. {
  314. // pEnumParam->lpInData is a string
  315. LPCTSTR lpszFind = (LPCTSTR)pEnumParam->lpInData;
  316. assert(lpszFind && lstrlen(lpszFind));
  317. // Get the class of this window
  318. TCHAR szClass[50];
  319. ::GetClassName(hWnd, szClass, sizeof(szClass)/sizeof(TCHAR));
  320. // Did we find a hit?
  321. if ( lstrcmpi(szClass, lpszFind) == 0 )
  322. {
  323. // Set the hWnd into the pEnumParam->lpOutData field and quit
  324. pEnumParam->lpOutData = hWnd;
  325. return FALSE;
  326. }
  327. break;
  328. }
  329. }
  330. return TRUE;
  331. }
  332. #ifndef VWCL_WRAP_WINDOWS_ONLY
  333. // Handler for WM_CLOSE. Default implementation calls DestroyWindow()
  334. virtual void OnClose()
  335. { DestroyWindow(); }
  336. // Handler for WM_COMMAND. Return 0 if message was handled
  337. virtual int OnCommand(WORD wNotifyCode, WORD wID, HWND hWndControl)
  338. { return 1; }
  339. // Handler for WM_CREATE. Return 0 if message was handled, -1 to stop window creation
  340. virtual int OnCreate(LPCREATESTRUCT lpCreateStruct)
  341. { return 1; }
  342. // Handler for WM_DESTROY. Return 0 if message was handled
  343. virtual int OnDestroy()
  344. { return 1; }
  345. // Handler for WM_PAINT. Return 0 if message was handled
  346. virtual int OnPaint()
  347. { return 1; }
  348. // Handler for WM_SIZE. Return 0 if message was handled
  349. virtual int OnSize(WPARAM wFlags, int cx, int cy)
  350. { return 1; }
  351. // Handler for WM_NOTIFY. Return 0 if message was handled
  352. virtual LRESULT OnNotify(int nIDControl, LPNMHDR lpNMHDR)
  353. { return 1; }
  354. // Support for reflected WM_NOTIFY messages. Derived class must
  355. // return 0 is message was handled, -1 if handled and parent should
  356. // NOT be notified, or 1 if message was not handled and parent should
  357. // be notified. If -1 if returned, derived classes must also set
  358. // the lCommonControlResult to the return value expected by the common control
  359. virtual int OnReflectedNotify(LPNMHDR lpNMHDR, LPARAM& lCommonControlResult)
  360. { return 1; }
  361. // Called after Attach() returns successfully
  362. virtual void PostAttachWindow()
  363. {;}
  364. // Called after Create() returns successfully. Returning FALSE from
  365. // this override will cause the window to be destroyed
  366. virtual BOOL PostCreateWindow()
  367. { return TRUE;}
  368. // Called after WM_DESTROY completes. Safe to do a delete this on VWindow object
  369. virtual void PostNcDestroy()
  370. {;}
  371. // Custom virtual functions for common overrides and default returns
  372. virtual BOOL PreCreateWindow(LPCREATESTRUCT lpCreateStruct)
  373. { return TRUE; }
  374. #endif
  375. };
  376. #endif // __VWINDOW_HPP