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.

497 lines
16 KiB

  1. // FrameMetrics.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "resource.h"
  5. #define MAX_LOADSTRING 100
  6. // Global Variables:
  7. HINSTANCE hInst; // current instance
  8. TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
  9. TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
  10. enum {
  11. NCCAPTION,
  12. NCBORDERS,
  13. NCMENUBAR,
  14. NCSCROLLBARS,
  15. NCCLOSEBUTTON,
  16. NCMAXBUTTON,
  17. NCMINBUTTON,
  18. NCHELPBUTTON,
  19. NCSYSICON,
  20. _cNCXXX,
  21. };
  22. BOOL _rgf[_cNCXXX] = {FALSE};
  23. HBRUSH _rghbr[_cNCXXX] = {0};
  24. COLORREF _rgrgb[_cNCXXX] = {
  25. RGB(255,0,255),
  26. RGB(0,255,255),
  27. RGB(255,255,0),
  28. RGB(0,0,255),
  29. RGB(0,255,255),
  30. RGB(0,255,255),
  31. RGB(0,255,255),
  32. RGB(0,255,255),
  33. RGB(0,255,255),
  34. };
  35. // Foward declarations of functions included in this code module:
  36. ATOM MyRegisterClass(HINSTANCE hInstance);
  37. BOOL InitInstance(HINSTANCE, int);
  38. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  39. LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  40. int APIENTRY WinMain(HINSTANCE hInstance,
  41. HINSTANCE hPrevInstance,
  42. LPSTR lpCmdLine,
  43. int nCmdShow)
  44. {
  45. // TODO: Place code here.
  46. MSG msg;
  47. HACCEL hAccelTable;
  48. // Initialize global strings
  49. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  50. LoadString(hInstance, IDC_FRAMEMETRICS, szWindowClass, MAX_LOADSTRING);
  51. MyRegisterClass(hInstance);
  52. // Perform application initialization:
  53. if (!InitInstance (hInstance, nCmdShow))
  54. {
  55. return FALSE;
  56. }
  57. for( int i=0; i<ARRAYSIZE(_rghbr); i++ )
  58. {
  59. _rghbr[i] = CreateSolidBrush(_rgrgb[i]);
  60. }
  61. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_FRAMEMETRICS);
  62. // Main message loop:
  63. while (GetMessage(&msg, NULL, 0, 0))
  64. {
  65. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  66. {
  67. TranslateMessage(&msg);
  68. DispatchMessage(&msg);
  69. }
  70. }
  71. for( i=0; i<ARRAYSIZE(_rghbr); i++ )
  72. {
  73. DeleteObject(_rghbr[i]);
  74. }
  75. return msg.wParam;
  76. }
  77. //
  78. // FUNCTION: MyRegisterClass()
  79. //
  80. // PURPOSE: Registers the window class.
  81. //
  82. // COMMENTS:
  83. //
  84. // This function and its usage is only necessary if you want this code
  85. // to be compatible with Win32 systems prior to the 'RegisterClassEx'
  86. // function that was added to Windows 95. It is important to call this function
  87. // so that the application will get 'well formed' small icons associated
  88. // with it.
  89. //
  90. ATOM MyRegisterClass(HINSTANCE hInstance)
  91. {
  92. WNDCLASSEX wcex;
  93. wcex.cbSize = sizeof(WNDCLASSEX);
  94. wcex.style = CS_HREDRAW | CS_VREDRAW;
  95. wcex.lpfnWndProc = (WNDPROC)WndProc;
  96. wcex.cbClsExtra = 0;
  97. wcex.cbWndExtra = 0;
  98. wcex.hInstance = hInstance;
  99. wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_FRAMEMETRICS);
  100. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  101. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  102. wcex.lpszMenuName = (LPCTSTR)IDC_FRAMEMETRICS;
  103. wcex.lpszClassName = szWindowClass;
  104. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  105. return RegisterClassEx(&wcex);
  106. }
  107. //
  108. // FUNCTION: InitInstance(HANDLE, int)
  109. //
  110. // PURPOSE: Saves instance handle and creates main window
  111. //
  112. // COMMENTS:
  113. //
  114. // In this function, we save the instance handle in a global variable and
  115. // create and display the main program window.
  116. //
  117. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  118. {
  119. HWND hwnd;
  120. hInst = hInstance; // Store instance handle in our global variable
  121. hwnd = CreateWindowEx( WS_EX_CONTEXTHELP, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,
  122. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  123. if (!hwnd)
  124. {
  125. return FALSE;
  126. }
  127. ShowWindow(hwnd, nCmdShow);
  128. UpdateWindow(hwnd);
  129. return TRUE;
  130. }
  131. //-------------------------------------------------------------------------//
  132. //
  133. // GetWindowBorders() - port from win32k, rtl\winmgr.c
  134. //
  135. // Computes window border dimensions based on style bits.
  136. //
  137. int _GetWindowBorders(LONG lStyle, DWORD dwExStyle )
  138. {
  139. int cBorders = 0;
  140. //
  141. // Is there a 3D border around the window?
  142. //
  143. if( TESTFLAG(dwExStyle, WS_EX_WINDOWEDGE) )
  144. cBorders += 2;
  145. else if ( TESTFLAG(dwExStyle, WS_EX_STATICEDGE) )
  146. ++cBorders;
  147. //
  148. // Is there a single flat border around the window? This is true for
  149. // WS_BORDER, WS_DLGFRAME, and WS_EX_DLGMODALFRAME windows.
  150. //
  151. if( TESTFLAG(lStyle, WS_CAPTION) || TESTFLAG(dwExStyle, WS_EX_DLGMODALFRAME) )
  152. ++cBorders;
  153. //
  154. // Is there a sizing flat border around the window?
  155. //
  156. if( TESTFLAG(lStyle, WS_THICKFRAME) )
  157. {
  158. NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(ncm);
  159. if( SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, FALSE ) )
  160. cBorders += ncm.iBorderWidth;
  161. else
  162. cBorders += GetSystemMetrics( SM_CXBORDER );
  163. }
  164. return(cBorders);
  165. }
  166. BOOL NcPaint(HWND hwnd, HRGN hrgnUpdate)
  167. {
  168. BOOL fRet = FALSE;
  169. int cPaint = 0;
  170. for( int i = 0; i < ARRAYSIZE(_rgf); i++ )
  171. {
  172. if( _rgf[i] )
  173. cPaint++;
  174. }
  175. if( 0 == cPaint )
  176. return FALSE;
  177. // private GetDCEx #defines from user
  178. #define DCX_USESTYLE 0x00010000L
  179. #define DCX_NODELETERGN 0x00040000L
  180. HDC hdc = (hrgnUpdate != NULL) ?
  181. GetDCEx( hwnd, hrgnUpdate, DCX_USESTYLE|DCX_WINDOW|DCX_LOCKWINDOWUPDATE|
  182. DCX_INTERSECTRGN|DCX_NODELETERGN ) :
  183. GetDCEx( hwnd, NULL, DCX_USESTYLE|DCX_WINDOW|DCX_LOCKWINDOWUPDATE );
  184. if( hdc )
  185. {
  186. WINDOWINFO wi;
  187. wi.cbSize = sizeof(wi);
  188. const RECT rcNil = {0};
  189. if( GetWindowInfo(hwnd, &wi) )
  190. {
  191. NONCLIENTMETRICS ncm;
  192. ncm.cbSize = sizeof(ncm);
  193. SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, FALSE );
  194. int cxEdge = GetSystemMetrics( SM_CXEDGE );
  195. int cyEdge = GetSystemMetrics( SM_CYEDGE );
  196. int cxBtn = GetSystemMetrics( SM_CXSIZE );
  197. int cyBtn = GetSystemMetrics( SM_CYSIZE );
  198. int cyCaption = GetSystemMetrics( SM_CYCAPTION );
  199. int cyMenu = GetSystemMetrics( SM_CYMENU );
  200. int cnBorders = _GetWindowBorders( wi.dwStyle, wi.dwExStyle );
  201. RECT rcWnd, rcCaption, rcMenuBar, rcHscroll, rcVscroll, rcSys;
  202. rcWnd = wi.rcWindow;
  203. OffsetRect( &rcWnd, -wi.rcWindow.left, -wi.rcWindow.top );
  204. rcCaption = rcMenuBar = rcWnd;
  205. rcHscroll = rcVscroll = rcNil;
  206. rcCaption.bottom = rcCaption.top + ncm.iCaptionHeight ;
  207. rcMenuBar.bottom = rcMenuBar.top + cyMenu;
  208. OffsetRect( &rcCaption, 0, cnBorders );
  209. OffsetRect( &rcMenuBar, 0, rcCaption.top + cyCaption );
  210. rcCaption.left += cnBorders;
  211. rcMenuBar.left += cnBorders;
  212. rcCaption.right -= cnBorders;
  213. rcMenuBar.right -= cnBorders;
  214. if( TESTFLAG(wi.dwStyle, WS_HSCROLL) )
  215. {
  216. rcHscroll = rcWnd;
  217. rcHscroll.top = rcHscroll.bottom - GetSystemMetrics(SM_CYHSCROLL);
  218. OffsetRect( &rcHscroll, 0, -cnBorders );
  219. rcHscroll.left += cnBorders;
  220. rcHscroll.right -= (cnBorders + (TESTFLAG(wi.dwStyle, WS_VSCROLL) ? GetSystemMetrics(SM_CXVSCROLL) : 0));
  221. }
  222. if( TESTFLAG(wi.dwStyle, WS_VSCROLL) )
  223. {
  224. rcVscroll = rcWnd;
  225. rcVscroll.left = rcVscroll.right - GetSystemMetrics(SM_CXVSCROLL);
  226. OffsetRect( &rcVscroll, -cnBorders, 0 );
  227. rcVscroll.top = rcMenuBar.bottom;
  228. rcVscroll.bottom -= (cnBorders + (TESTFLAG(wi.dwStyle, WS_HSCROLL) ? GetSystemMetrics(SM_CYHSCROLL) : 0));
  229. }
  230. // buttons
  231. RECT rcClose, rcMin, rcMax, rcHelp;
  232. rcClose.top = rcMin.top = rcMax.top = rcHelp.top = rcCaption.top;
  233. rcClose.bottom = rcMin.bottom = rcMax.bottom = rcHelp.bottom = rcCaption.top + (cyBtn - (cyEdge * 2));
  234. rcSys.top = rcCaption.top;
  235. rcSys.bottom = rcSys.top + GetSystemMetrics(SM_CYSMICON);
  236. rcSys.left = rcCaption.left + cxEdge; rcSys.right = rcSys.left + GetSystemMetrics(SM_CXSMICON);
  237. rcClose.right = rcCaption.right - cxEdge; rcClose.left = rcClose.right - (cxBtn - cxEdge);
  238. rcMax.right = rcClose.left - cxEdge; rcMax.left = rcMax.right - (cxBtn - cxEdge);
  239. rcMin.right = rcMax.left; rcMin.left = rcMin.right - (cxBtn - cxEdge);
  240. rcHelp = rcMax;
  241. // vertically center
  242. OffsetRect( &rcSys, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcSys))/2 );
  243. OffsetRect( &rcClose, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcClose))/2 );
  244. OffsetRect( &rcMax, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcMax))/2 );
  245. OffsetRect( &rcMin, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcMin))/2 );
  246. OffsetRect( &rcHelp, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcHelp))/2 );
  247. DefWindowProc( hwnd, WM_NCPAINT, (WPARAM)hrgnUpdate, 0L );
  248. GdiSetBatchLimit(1);
  249. if( _rgf[NCCAPTION] )
  250. {
  251. FillRect( hdc, &rcCaption, _rghbr[NCCAPTION] );
  252. }
  253. if( _rgf[NCMENUBAR] )
  254. {
  255. FillRect( hdc, &rcMenuBar, _rghbr[NCMENUBAR] );
  256. }
  257. if( _rgf[NCSCROLLBARS] )
  258. {
  259. FillRect( hdc, &rcHscroll, _rghbr[NCSCROLLBARS] );
  260. FillRect( hdc, &rcVscroll, _rghbr[NCSCROLLBARS] );
  261. }
  262. if( _rgf[NCBORDERS] )
  263. {
  264. RECT rcBorders = rcWnd;
  265. for( int i=0; i<cnBorders; i++ )
  266. {
  267. FrameRect( hdc, &rcBorders, _rghbr[NCBORDERS] );
  268. GetLastError();
  269. InflateRect( &rcBorders, -1, -1 );
  270. }
  271. }
  272. if( _rgf[NCCLOSEBUTTON] )
  273. FillRect( hdc, &rcClose, _rghbr[NCCLOSEBUTTON] );
  274. if( _rgf[NCMAXBUTTON] && TESTFLAG(wi.dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX) )
  275. FillRect( hdc, &rcMax, _rghbr[NCMAXBUTTON] );
  276. if( _rgf[NCMINBUTTON] && TESTFLAG(wi.dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX) )
  277. FillRect( hdc, &rcMin, _rghbr[NCMINBUTTON] );
  278. if( _rgf[NCHELPBUTTON] && !TESTFLAG(wi.dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX) )
  279. FillRect( hdc, &rcHelp, _rghbr[NCHELPBUTTON] );
  280. if( _rgf[NCSYSICON] && TESTFLAG(wi.dwStyle, WS_SYSMENU) )
  281. FillRect( hdc, &rcSys, _rghbr[NCSYSICON] );
  282. GdiSetBatchLimit(0) ;
  283. ReleaseDC( hwnd, hdc );
  284. fRet = TRUE;
  285. }
  286. }
  287. return fRet;
  288. }
  289. //
  290. // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
  291. //
  292. // PURPOSE: Processes messages for the main window.
  293. //
  294. // WM_COMMAND - process the application menu
  295. // WM_PAINT - Paint the main window
  296. // WM_DESTROY - post a quit message and return
  297. //
  298. //
  299. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  300. {
  301. LRESULT lRet = 0;
  302. int wmId, wmEvent;
  303. switch (message)
  304. {
  305. case WM_COMMAND:
  306. {
  307. wmId = LOWORD(wParam);
  308. wmEvent = HIWORD(wParam);
  309. BOOL fSwp = FALSE;
  310. // Parse the menu selections:
  311. switch (wmId)
  312. {
  313. #define IMPLEMENT_NCCOMMANDID(cmd) \
  314. case ID_##cmd: _rgf[NC##cmd] = !_rgf[NC##cmd]; fSwp = TRUE; break;
  315. IMPLEMENT_NCCOMMANDID(CAPTION)
  316. IMPLEMENT_NCCOMMANDID(MENUBAR)
  317. IMPLEMENT_NCCOMMANDID(BORDERS)
  318. IMPLEMENT_NCCOMMANDID(SCROLLBARS)
  319. IMPLEMENT_NCCOMMANDID(CLOSEBUTTON)
  320. IMPLEMENT_NCCOMMANDID(MAXBUTTON)
  321. IMPLEMENT_NCCOMMANDID(MINBUTTON)
  322. IMPLEMENT_NCCOMMANDID(HELPBUTTON)
  323. IMPLEMENT_NCCOMMANDID(SYSICON)
  324. case ID_NONE:
  325. case ID_ALL:
  326. for( int i = 0; i<ARRAYSIZE(_rgf); i++ )
  327. {
  328. _rgf[i] = wmId == ID_ALL;
  329. }
  330. fSwp = TRUE;
  331. break;
  332. case ID_THICKFRAME:
  333. {
  334. DWORD dwStyle = GetWindowLong( hwnd, GWL_STYLE );
  335. if( TESTFLAG( dwStyle, WS_THICKFRAME ) )
  336. dwStyle &= ~WS_THICKFRAME;
  337. else
  338. dwStyle |= WS_THICKFRAME;
  339. SetWindowLong( hwnd, GWL_STYLE, dwStyle );
  340. fSwp = TRUE;
  341. break;
  342. }
  343. case ID_MINMAX:
  344. {
  345. DWORD dwStyle = GetWindowLong( hwnd, GWL_STYLE );
  346. if( TESTFLAG( dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX ) )
  347. dwStyle &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
  348. else
  349. dwStyle |= (WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
  350. SetWindowLong( hwnd, GWL_STYLE, dwStyle );
  351. fSwp = TRUE;
  352. break;
  353. }
  354. case IDM_ABOUT:
  355. DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hwnd, (DLGPROC)About);
  356. break;
  357. case IDM_EXIT:
  358. DestroyWindow(hwnd);
  359. break;
  360. default:
  361. return DefWindowProc(hwnd, message, wParam, lParam);
  362. }
  363. if( fSwp )
  364. SetWindowPos( hwnd, NULL, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_DRAWFRAME );
  365. break;
  366. }
  367. case WM_NCPAINT:
  368. if( !NcPaint(hwnd, (HRGN)wParam) )
  369. lRet = DefWindowProc( hwnd, message, wParam, lParam );
  370. break;
  371. case WM_NCACTIVATE:
  372. lRet = DefWindowProc( hwnd, message, wParam, lParam );
  373. NcPaint(hwnd, NULL);
  374. break;
  375. case WM_INITMENUPOPUP:
  376. {
  377. CheckMenuItem( (HMENU)wParam, ID_CAPTION, MF_BYCOMMAND | (_rgf[NCCAPTION] ? MF_CHECKED : MF_UNCHECKED) );
  378. CheckMenuItem( (HMENU)wParam, ID_MENUBAR, MF_BYCOMMAND | (_rgf[NCMENUBAR] ? MF_CHECKED : MF_UNCHECKED) );
  379. CheckMenuItem( (HMENU)wParam, ID_BORDERS, MF_BYCOMMAND | (_rgf[NCBORDERS] ? MF_CHECKED : MF_UNCHECKED) );
  380. CheckMenuItem( (HMENU)wParam, ID_SCROLLBARS, MF_BYCOMMAND | (_rgf[NCSCROLLBARS] ? MF_CHECKED : MF_UNCHECKED) );
  381. CheckMenuItem( (HMENU)wParam, ID_CLOSEBUTTON, MF_BYCOMMAND | (_rgf[NCCLOSEBUTTON] ? MF_CHECKED : MF_UNCHECKED) );
  382. CheckMenuItem( (HMENU)wParam, ID_MAXBUTTON, MF_BYCOMMAND | (_rgf[NCMAXBUTTON] ? MF_CHECKED : MF_UNCHECKED) );
  383. CheckMenuItem( (HMENU)wParam, ID_MINBUTTON, MF_BYCOMMAND | (_rgf[NCMINBUTTON] ? MF_CHECKED : MF_UNCHECKED) );
  384. CheckMenuItem( (HMENU)wParam, ID_HELPBUTTON, MF_BYCOMMAND | (_rgf[NCHELPBUTTON] ? MF_CHECKED : MF_UNCHECKED) );
  385. CheckMenuItem( (HMENU)wParam, ID_SYSICON, MF_BYCOMMAND | (_rgf[NCSYSICON] ? MF_CHECKED : MF_UNCHECKED) );
  386. ULONG dwStyle = GetWindowLong(hwnd, GWL_STYLE);
  387. CheckMenuItem( (HMENU)wParam, ID_THICKFRAME, MF_BYCOMMAND | (TESTFLAG(dwStyle, WS_THICKFRAME) ? MF_CHECKED : MF_UNCHECKED) );
  388. CheckMenuItem( (HMENU)wParam, ID_MINMAX, MF_BYCOMMAND | (TESTFLAG(dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX) ? MF_CHECKED : MF_UNCHECKED) );
  389. break;
  390. }
  391. case WM_DESTROY:
  392. PostQuitMessage(0);
  393. break;
  394. default:
  395. return DefWindowProc(hwnd, message, wParam, lParam);
  396. }
  397. return lRet;
  398. }
  399. // Mesage handler for about box.
  400. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  401. {
  402. switch (message)
  403. {
  404. case WM_INITDIALOG:
  405. return TRUE;
  406. case WM_COMMAND:
  407. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  408. {
  409. EndDialog(hDlg, LOWORD(wParam));
  410. return TRUE;
  411. }
  412. break;
  413. }
  414. return FALSE;
  415. }