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.

940 lines
24 KiB

  1. // MainFrm.cpp : implementation of the CMainFrame class
  2. //
  3. #include "stdafx.h"
  4. #include "mditest.h"
  5. #include "rgn.h"
  6. #include "MainFrm.h"
  7. #include "NCMetricsDlg.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. #define TESTFLAG(bits,flag) (((bits) & (flag))!=0)
  14. void TestRgnData();
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CMainFrame
  17. IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
  18. BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
  19. //{{AFX_MSG_MAP(CMainFrame)
  20. ON_WM_CREATE()
  21. ON_WM_GETMINMAXINFO()
  22. ON_COMMAND(ID_FULLSCRNMAXIMIZED, OnFullScrnMaximized)
  23. ON_UPDATE_COMMAND_UI(ID_FULLSCRNMAXIMIZED, OnUpdateFullScrnMaximized)
  24. ON_COMMAND(ID_AWRWINDOW, OnAwrWindow)
  25. ON_COMMAND(ID_AWRWINDOWMENU, OnAwrWindowMenu)
  26. ON_COMMAND(ID_NONCLIENTMETRICS, OnNonClientMetrics)
  27. ON_COMMAND(ID_THINFRAME, OnThinFrame)
  28. ON_COMMAND(ID_DUMPMETRICS, OnDumpMetrics)
  29. ON_COMMAND(ID_MINIMIZEBOX, OnMinimizeBox)
  30. ON_UPDATE_COMMAND_UI(ID_MINIMIZEBOX, OnUpdateMinimizeBox)
  31. ON_COMMAND(ID_MAXIMIZEBOX, OnMaximizeBox)
  32. ON_UPDATE_COMMAND_UI(ID_MAXIMIZEBOX, OnUpdateMaximizeBox)
  33. ON_COMMAND(ID_SYSMENU, OnSysMenu)
  34. ON_UPDATE_COMMAND_UI(ID_SYSMENU, OnUpdateSysMenu)
  35. ON_UPDATE_COMMAND_UI(ID_CLOSEBTN, OnUpdateCloseBtn)
  36. ON_COMMAND(ID_CLOSEBTN, OnCloseBtn)
  37. ON_COMMAND(ID_TOOLFRAME, OnToolframe)
  38. ON_COMMAND(ID_ALTICON, OnAltIcon)
  39. ON_UPDATE_COMMAND_UI(ID_ALTICON, OnUpdateAltIcon)
  40. ON_COMMAND(ID_ALTTEXT, OnAltTitle)
  41. ON_UPDATE_COMMAND_UI(ID_ALTTEXT, OnUpdateAltTitle)
  42. ON_COMMAND(IDC_DCAPPCOMPAT, OnDcAppcompat)
  43. ON_UPDATE_COMMAND_UI(IDC_DCAPPCOMPAT, OnUpdateDcAppcompat)
  44. ON_COMMAND(IDC_DFCAPPCOMPAT, OnDfcAppcompat)
  45. ON_UPDATE_COMMAND_UI(IDC_DFCAPPCOMPAT, OnUpdateDfcAppcompat)
  46. ON_WM_NCPAINT()
  47. ON_COMMAND(ID_MINMAXSTRESS, OnMinMaxStress)
  48. ON_UPDATE_COMMAND_UI(ID_MINMAXSTRESS, OnUpdateMinMaxStress)
  49. ON_WM_WINDOWPOSCHANGING()
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. static UINT indicators[] =
  53. {
  54. ID_SEPARATOR, // status line indicator
  55. ID_INDICATOR_CAPS,
  56. ID_INDICATOR_NUM,
  57. ID_INDICATOR_SCRL,
  58. };
  59. /////////////////////////////////////////////////////////////////////////////
  60. // CMainFrame construction/destruction
  61. CMainFrame::CMainFrame()
  62. : m_fFullScrnMax(TRUE),
  63. m_fAltIcon(FALSE),
  64. m_fAltTitle(FALSE),
  65. m_fDfcAppCompat(FALSE),
  66. m_fDcAppCompat(FALSE),
  67. m_fMinMaxStress(FALSE),
  68. m_pwiNormal0(NULL),
  69. m_hIcon(NULL)
  70. {
  71. }
  72. CMainFrame::~CMainFrame()
  73. {
  74. if( m_hAltIcon )
  75. DeleteObject( m_hAltIcon );
  76. if( m_hIcon )
  77. DeleteObject( m_hIcon );
  78. }
  79. LRESULT CALLBACK MsgWndProc( HWND hwnd, UINT uMsg, WPARAM lParam, LPARAM wParam )
  80. {
  81. return DefWindowProc( hwnd, uMsg, lParam, wParam );
  82. }
  83. int GetPrime( ULONG number )
  84. {
  85. int cPrimeCount = 0;
  86. if( number > 1 )
  87. {
  88. for( UINT i = 2; i < number; i++ )
  89. {
  90. if( 0 == number % i )
  91. cPrimeCount++;
  92. }
  93. }
  94. return cPrimeCount;
  95. }
  96. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  97. {
  98. if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
  99. return -1;
  100. if (!m_wndToolBar.CreateEx(this) ||
  101. !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
  102. {
  103. TRACE0("Failed to create toolbar\n");
  104. return -1; // fail to create
  105. }
  106. if (!m_wndDlgBar.Create(this, IDR_MAINFRAME,
  107. CBRS_ALIGN_TOP, AFX_IDW_DIALOGBAR))
  108. {
  109. TRACE0("Failed to create dialogbar\n");
  110. return -1; // fail to create
  111. }
  112. if (!m_wndReBar.Create(this) ||
  113. !m_wndReBar.AddBar(&m_wndToolBar) ||
  114. !m_wndReBar.AddBar(&m_wndDlgBar))
  115. {
  116. TRACE0("Failed to create rebar\n");
  117. return -1; // fail to create
  118. }
  119. if (!m_wndStatusBar.Create(this) ||
  120. !m_wndStatusBar.SetIndicators(indicators,
  121. sizeof(indicators)/sizeof(UINT)))
  122. {
  123. TRACE0("Failed to create status bar\n");
  124. return -1; // fail to create
  125. }
  126. m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
  127. CBRS_TOOLTIPS | CBRS_FLYBY);
  128. TestRgnData();
  129. return 0;
  130. }
  131. void _GetRectSize( LPCRECT prc, PPOINT pptSize )
  132. {
  133. pptSize->x = RECTWIDTH(prc);
  134. pptSize->y = RECTHEIGHT(prc);
  135. }
  136. BOOL _EqualPoint( PPOINT pt1, PPOINT pt2 )
  137. {
  138. return (pt1->x == pt2->x) && (pt1->y == pt2->y);
  139. }
  140. LRESULT CALLBACK AWRWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  141. {
  142. switch(uMsg)
  143. {
  144. case WM_COMMAND:
  145. {
  146. if( ID_CLOSE == LOWORD(wParam) )
  147. DestroyWindow(hwnd);
  148. break;
  149. }
  150. case WM_SIZE:
  151. {
  152. RECT rcCli, rcWnd, rcAwr;
  153. POINT sizeWnd, sizeCli, sizeAwr;
  154. GetWindowRect(hwnd, &rcWnd);
  155. _GetRectSize(&rcWnd, &sizeWnd);
  156. GetClientRect(hwnd, &rcCli);
  157. _GetRectSize(&rcCli, &sizeCli);
  158. int cyMenu = GetSystemMetrics(SM_CYMENU);
  159. int cyMenuSize = GetSystemMetrics(SM_CYMENUSIZE);
  160. WINDOWINFO wi = {0};
  161. wi.cbSize = sizeof(wi);
  162. GetWindowInfo(hwnd, &wi);
  163. rcAwr = rcCli;
  164. AdjustWindowRectEx(&rcAwr, wi.dwStyle, GetMenu(hwnd) != NULL, wi.dwExStyle);
  165. _GetRectSize(&rcAwr, &sizeAwr);
  166. TRACE( TEXT("AWRex: cli(%d,%d), wnd(%d,%d), awr(%d,%d), %s\n\n"),
  167. sizeCli, sizeWnd, sizeAwr,
  168. _EqualPoint(&sizeWnd, &sizeAwr) ? TEXT("Ok.") : TEXT("ERROR!") );
  169. break;
  170. }
  171. }
  172. return DefWindowProc( hwnd, uMsg, wParam, lParam );
  173. }
  174. //---------------------------------------------------------------------------
  175. HRESULT _PrepareRegionDataForScaling(RGNDATA *pRgnData, LPCRECT prcImage, MARGINS *pMargins)
  176. {
  177. //---- compute margin values ----
  178. int sw = prcImage->left;
  179. int lw = prcImage->left + pMargins->cxLeftWidth;
  180. int rw = prcImage->right - pMargins->cxRightWidth;
  181. int sh = prcImage->top;
  182. int th = prcImage->top + pMargins->cyTopHeight;
  183. int bh = prcImage->bottom - pMargins->cyBottomHeight;
  184. //---- step thru region data & customize it ----
  185. //---- classify each POINT according to a gridnum and ----
  186. //---- make it 0-relative to its grid location ----
  187. POINT *pt = (POINT *)pRgnData->Buffer;
  188. BYTE *pByte = (BYTE *)pRgnData->Buffer + pRgnData->rdh.nRgnSize;
  189. int iCount = 2 * pRgnData->rdh.nCount;
  190. for (int i=0; i < iCount; i++, pt++, pByte++)
  191. {
  192. if (pt->x < lw)
  193. {
  194. pt->x -= sw;
  195. if (pt->y < th) // left top
  196. {
  197. *pByte = GN_LEFTTOP;
  198. pt->y -= sh;
  199. }
  200. else if (pt->y < bh) // left middle
  201. {
  202. *pByte = GN_LEFTMIDDLE;
  203. pt->y -= th;
  204. }
  205. else // left bottom
  206. {
  207. *pByte = GN_LEFTBOTTOM;
  208. pt->y -= bh;
  209. }
  210. }
  211. else if (pt->x < rw)
  212. {
  213. pt->x -= lw;
  214. if (pt->y < th) // middle top
  215. {
  216. *pByte = GN_MIDDLETOP;
  217. pt->y -= sh;
  218. }
  219. else if (pt->y < bh) // middle middle
  220. {
  221. *pByte = GN_MIDDLEMIDDLE;
  222. pt->y -= th;
  223. }
  224. else // middle bottom
  225. {
  226. *pByte = GN_MIDDLEBOTTOM;
  227. pt->y -= bh;
  228. }
  229. }
  230. else
  231. {
  232. pt->x -= rw;
  233. if (pt->y < th) // right top
  234. {
  235. *pByte = GN_RIGHTTOP;
  236. pt->y -= sh;
  237. }
  238. else if (pt->y < bh) // right middle
  239. {
  240. *pByte = GN_RIGHTMIDDLE;
  241. pt->y -= th;
  242. }
  243. else // right bottom
  244. {
  245. *pByte = GN_RIGHTBOTTOM;
  246. pt->y -= bh;
  247. }
  248. }
  249. }
  250. return S_OK;
  251. }
  252. //---------------------------------------------------------------------------
  253. void TestRgnData()
  254. {
  255. HBITMAP hbm = (HBITMAP)LoadImage(
  256. NULL, TEXT("f:\\testapplets\\mditest\\rgndatatest.bmp"),
  257. IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
  258. if( hbm )
  259. {
  260. HRGN hrgn;
  261. BITMAP bm;
  262. GetObject( hbm, sizeof(bm), &bm );
  263. if( SUCCEEDED( CreateBitmapRgn( hbm, 0, 0, -1, -1, FALSE, 0, RGB(255,0,255), 0, &hrgn ) ) )
  264. {
  265. LONG cb = GetRegionData(hrgn, 0, NULL);
  266. LONG cbRgnData = cb + sizeof(RGNDATAHEADER);
  267. BYTE* pbData = NULL;
  268. if( (pbData = new BYTE[cbRgnData]) != NULL )
  269. {
  270. RGNDATA* pRgnData = (RGNDATA*)pbData;
  271. if( GetRegionData(hrgn, cbRgnData, pRgnData) )
  272. {
  273. MARGINS marSizing = {12,6,1,6};
  274. RECT rcImage;
  275. SetRect(&rcImage, 0, 0, bm.bmWidth, bm.bmHeight);
  276. _PrepareRegionDataForScaling( pRgnData, &rcImage, &marSizing );
  277. }
  278. delete [] pbData;
  279. }
  280. }
  281. }
  282. }
  283. void TestPidHash()
  284. {
  285. for( int rep = 0; rep < 500; rep++ )
  286. {
  287. ULONG cBestCollisions = -1;
  288. int cBestBuckets = 0;
  289. for( int cBuckets = 0xFD9; cBuckets <= 0xFF3; cBuckets++ )
  290. {
  291. ULONG hashtable[2][1000] = {0};
  292. srand(GetTickCount());
  293. ULONG cCollisions = 0;
  294. for( int i=0; i < 1000; i++ )
  295. {
  296. ULONG pid = rand();
  297. ULONG hash = (pid << 4);
  298. hash %= cBuckets;
  299. for( int j = 0; j < i; j++ )
  300. {
  301. if( hashtable[1][j] == hash )
  302. {
  303. ULONG pidOther = hashtable[0][j];
  304. ULONG hashOther = hashtable[1][j];
  305. cCollisions++;
  306. }
  307. }
  308. hashtable[0][i] = pid;
  309. hashtable[1][i] = hash;
  310. }
  311. if( cCollisions < cBestCollisions )
  312. {
  313. cBestCollisions = cCollisions;
  314. cBestBuckets = cBuckets;
  315. }
  316. //TRACE("Collision count using bucket count %04X: %d\n", cBuckets, cCollisions );
  317. }
  318. TRACE(TEXT("%04X\t%d\t%d\n"), cBestBuckets, cBestCollisions, GetPrime(cBestBuckets) );
  319. }
  320. }
  321. //---------------------------------------------------------------------------
  322. HWND CreateAWRWindow( HWND hwndParent, DWORD dwStyle, DWORD dwExStyle, BOOL fMenu )
  323. {
  324. static WNDCLASS wc = {0};
  325. if( !wc.lpfnWndProc )
  326. {
  327. wc.style = CS_HREDRAW|CS_VREDRAW;
  328. wc.lpfnWndProc = AWRWndProc;
  329. wc.hInstance = AfxGetInstanceHandle();
  330. wc.hCursor = ::LoadCursor( NULL, IDC_ARROW );
  331. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  332. wc.lpszClassName = TEXT("AWRTestWnd");
  333. if( !RegisterClass( &wc ) )
  334. return NULL;
  335. }
  336. HMENU hMenu = NULL;
  337. if( fMenu )
  338. hMenu = LoadMenu( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_AWRMENU) );
  339. return CreateWindowEx( dwExStyle, wc.lpszClassName, TEXT("AdustWindowRect test"), dwStyle,
  340. 0, 0, 640, 480, hwndParent, hMenu, wc.hInstance, NULL );
  341. }
  342. //---------------------------------------------------------------------------
  343. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  344. {
  345. if( !CMDIFrameWnd::PreCreateWindow(cs) )
  346. return FALSE;
  347. return TRUE;
  348. }
  349. /////////////////////////////////////////////////////////////////////////////
  350. // CMainFrame diagnostics
  351. #ifdef _DEBUG
  352. void CMainFrame::AssertValid() const
  353. {
  354. CMDIFrameWnd::AssertValid();
  355. }
  356. void CMainFrame::Dump(CDumpContext& dc) const
  357. {
  358. CMDIFrameWnd::Dump(dc);
  359. }
  360. #endif //_DEBUG
  361. /////////////////////////////////////////////////////////////////////////////
  362. // CMainFrame message handlers
  363. void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  364. {
  365. CMDIFrameWnd::OnGetMinMaxInfo(lpMMI);
  366. if( !m_fFullScrnMax )
  367. {
  368. //lpMMI->ptMaxPosition.x = lpMMI->ptMaxPosition.y = 0;
  369. lpMMI->ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN)/2;
  370. lpMMI->ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN)/2;
  371. }
  372. }
  373. void CMainFrame::OnFullScrnMaximized()
  374. {
  375. m_fFullScrnMax = !m_fFullScrnMax;
  376. }
  377. void CMainFrame::OnUpdateFullScrnMaximized(CCmdUI* pCmdUI)
  378. {
  379. pCmdUI->SetCheck( m_fFullScrnMax );
  380. }
  381. void CMainFrame::OnAwrWindow()
  382. {
  383. HWND hwnd;
  384. if( (hwnd = CreateAWRWindow(
  385. *this, WS_OVERLAPPEDWINDOW & ~WS_SYSMENU, WS_EX_CLIENTEDGE|WS_EX_CONTEXTHELP, FALSE )) != NULL )
  386. {
  387. ::ShowWindow(hwnd, SW_SHOW);
  388. ::UpdateWindow(hwnd);
  389. }
  390. }
  391. void CMainFrame::OnAwrWindowMenu()
  392. {
  393. HWND hwnd;
  394. if( (hwnd = CreateAWRWindow(
  395. *this, WS_OVERLAPPEDWINDOW, WS_EX_CLIENTEDGE, TRUE )) != NULL )
  396. {
  397. ::ShowWindow(hwnd, SW_SHOW);
  398. ::UpdateWindow(hwnd);
  399. }
  400. }
  401. void CMainFrame::OnNonClientMetrics()
  402. {
  403. CNCMetricsDlg dlg;
  404. dlg.DoModal();
  405. }
  406. LRESULT CALLBACK ToolFrameWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  407. {
  408. return DefWindowProc( hwnd, uMsg, wParam, lParam );
  409. }
  410. LRESULT CALLBACK ThinFrameWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  411. {
  412. return DefWindowProc( hwnd, uMsg, wParam, lParam );
  413. }
  414. void CMainFrame::OnToolframe()
  415. {
  416. static WNDCLASS wc = {0};
  417. if( !wc.lpfnWndProc )
  418. {
  419. wc.style = CS_HREDRAW|CS_VREDRAW;
  420. wc.lpfnWndProc = ToolFrameWndProc;
  421. wc.hInstance = AfxGetInstanceHandle();
  422. wc.hCursor = ::LoadCursor( NULL, IDC_ARROW );
  423. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  424. wc.lpszClassName = TEXT("ToolFrameTestWnd");
  425. if( !RegisterClass( &wc ) )
  426. return;
  427. }
  428. HWND hwnd = CreateWindowEx( WS_EX_TOOLWINDOW, wc.lpszClassName, TEXT("Tool Frame"),
  429. WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
  430. CW_USEDEFAULT, 0, 280, 320, *this, NULL, wc.hInstance, NULL );
  431. if( hwnd )
  432. {
  433. ::UpdateWindow(hwnd);
  434. ::ShowWindow(hwnd, SW_SHOW);
  435. }
  436. }
  437. void CMainFrame::OnThinFrame()
  438. {
  439. static WNDCLASS wc = {0};
  440. if( !wc.lpfnWndProc )
  441. {
  442. wc.style = CS_HREDRAW|CS_VREDRAW;
  443. wc.lpfnWndProc = ThinFrameWndProc;
  444. wc.hInstance = AfxGetInstanceHandle();
  445. wc.hCursor = ::LoadCursor( NULL, IDC_ARROW );
  446. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  447. wc.lpszClassName = TEXT("ThinFrameTestWnd");
  448. if( !RegisterClass( &wc ) )
  449. return;
  450. }
  451. HWND hwnd = CreateWindowEx( WS_EX_DLGMODALFRAME, wc.lpszClassName, TEXT("Thin Frame"), WS_CAPTION|WS_SYSMENU,
  452. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, *this, NULL, wc.hInstance, NULL );
  453. if( hwnd )
  454. {
  455. ::UpdateWindow(hwnd);
  456. ::ShowWindow(hwnd, SW_SHOW);
  457. }
  458. }
  459. void CMainFrame::OnDumpMetrics()
  460. {
  461. NONCLIENTMETRICS ncm = {0};
  462. ncm.cbSize = sizeof(ncm);
  463. int iBorder;
  464. SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0 );
  465. SystemParametersInfo( SPI_GETBORDER, 0, &iBorder, 0 );
  466. #define SPEW_NCM(i) TRACE(TEXT("NONCLIENTMETRICS::") TEXT(#i) TEXT(":\t%d\n"), ncm.##i );
  467. #define SPEW_SYSMET(sm) TRACE(TEXT(#sm) TEXT(":\t%d\n"), GetSystemMetrics(sm) );
  468. TRACE(TEXT("SPI_BORDER:\t%d\n"), iBorder);
  469. SPEW_NCM(iBorderWidth);
  470. SPEW_NCM(iScrollWidth);
  471. SPEW_NCM(iScrollHeight);
  472. SPEW_NCM(iCaptionWidth);
  473. SPEW_NCM(iCaptionHeight);
  474. SPEW_NCM(iSmCaptionWidth);
  475. SPEW_NCM(iSmCaptionHeight);
  476. SPEW_NCM(iMenuWidth);
  477. SPEW_NCM(iMenuHeight);
  478. SPEW_SYSMET( SM_CXVSCROLL )
  479. SPEW_SYSMET( SM_CYHSCROLL )
  480. SPEW_SYSMET( SM_CYCAPTION )
  481. SPEW_SYSMET( SM_CXBORDER )
  482. SPEW_SYSMET( SM_CYBORDER )
  483. SPEW_SYSMET( SM_CYVTHUMB )
  484. SPEW_SYSMET( SM_CXHTHUMB )
  485. SPEW_SYSMET( SM_CXICON )
  486. SPEW_SYSMET( SM_CYICON )
  487. SPEW_SYSMET( SM_CYMENU )
  488. SPEW_SYSMET( SM_CYVSCROLL )
  489. SPEW_SYSMET( SM_CXHSCROLL )
  490. SPEW_SYSMET( SM_SWAPBUTTON )
  491. SPEW_SYSMET( SM_CXSIZE )
  492. SPEW_SYSMET( SM_CYSIZE )
  493. SPEW_SYSMET( SM_CXFIXEDFRAME )
  494. SPEW_SYSMET( SM_CYFIXEDFRAME )
  495. SPEW_SYSMET( SM_CXSIZEFRAME )
  496. SPEW_SYSMET( SM_CYSIZEFRAME )
  497. SPEW_SYSMET( SM_CXEDGE )
  498. SPEW_SYSMET( SM_CYEDGE )
  499. SPEW_SYSMET( SM_CXSMICON )
  500. SPEW_SYSMET( SM_CYSMICON )
  501. SPEW_SYSMET( SM_CYSMCAPTION )
  502. SPEW_SYSMET( SM_CXSMSIZE )
  503. SPEW_SYSMET( SM_CYSMSIZE )
  504. SPEW_SYSMET( SM_CXMENUSIZE )
  505. SPEW_SYSMET( SM_CYMENUSIZE )
  506. SPEW_SYSMET( SM_CXMINIMIZED )
  507. SPEW_SYSMET( SM_CYMINIMIZED )
  508. SPEW_SYSMET( SM_CXMAXIMIZED )
  509. SPEW_SYSMET( SM_CYMAXIMIZED )
  510. SPEW_SYSMET( SM_CXDRAG )
  511. SPEW_SYSMET( SM_CYDRAG )
  512. }
  513. void _ToggleStyle( CWnd* pwnd, DWORD dwStyle )
  514. {
  515. BOOL fStyle = pwnd->GetStyle() & dwStyle;
  516. pwnd->ModifyStyle( fStyle ? dwStyle : 0,
  517. fStyle ? 0 : dwStyle );
  518. pwnd->SetWindowPos( NULL, 0, 0, 0, 0,
  519. SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_DRAWFRAME );
  520. }
  521. void CMainFrame::OnMinimizeBox()
  522. {
  523. _ToggleStyle( this, WS_MINIMIZEBOX );
  524. }
  525. void CMainFrame::OnUpdateMinimizeBox(CCmdUI* pCmdUI)
  526. {
  527. pCmdUI->Enable( GetStyle() & WS_SYSMENU );
  528. pCmdUI->SetCheck( GetStyle() & WS_MINIMIZEBOX );
  529. }
  530. void CMainFrame::OnMaximizeBox()
  531. {
  532. _ToggleStyle( this, WS_MAXIMIZEBOX );
  533. }
  534. void CMainFrame::OnUpdateMaximizeBox(CCmdUI* pCmdUI)
  535. {
  536. pCmdUI->Enable( GetStyle() & WS_SYSMENU );
  537. pCmdUI->SetCheck( GetStyle() & WS_MAXIMIZEBOX );
  538. }
  539. void CMainFrame::OnSysMenu()
  540. {
  541. _ToggleStyle( this, WS_SYSMENU );
  542. }
  543. void CMainFrame::OnUpdateSysMenu(CCmdUI* pCmdUI)
  544. {
  545. pCmdUI->SetCheck( GetStyle() & WS_SYSMENU );
  546. }
  547. BOOL _MNCanClose(HWND hwnd)
  548. {
  549. BOOL fRetVal = FALSE;
  550. TITLEBARINFO tbi = {sizeof(tbi)};
  551. //---- don't use GetSystemMenu() - has user handle leak issues ----
  552. if (GetTitleBarInfo(hwnd, &tbi))
  553. {
  554. //---- mask out the good bits ----
  555. DWORD dwVal = (tbi.rgstate[5] & (~(STATE_SYSTEM_PRESSED | STATE_SYSTEM_FOCUSABLE)));
  556. fRetVal = (dwVal == 0); // only if no bad bits are left
  557. }
  558. if ( !fRetVal && TESTFLAG(GetWindowLong(hwnd, GWL_EXSTYLE), WS_EX_MDICHILD) )
  559. {
  560. HMENU hMenu = GetSystemMenu(hwnd, FALSE);
  561. MENUITEMINFO menuInfo;
  562. menuInfo.cbSize = sizeof(MENUITEMINFO);
  563. menuInfo.fMask = MIIM_STATE;
  564. if ( GetMenuItemInfo(hMenu, SC_CLOSE, FALSE, &menuInfo) )
  565. {
  566. fRetVal = !(menuInfo.fState & MFS_GRAYED) ? TRUE : FALSE;
  567. }
  568. }
  569. return fRetVal;
  570. }
  571. void CMainFrame::OnUpdateCloseBtn(CCmdUI* pCmdUI)
  572. {
  573. pCmdUI->SetCheck( _MNCanClose(m_hWnd) );
  574. }
  575. void CMainFrame::OnCloseBtn()
  576. {
  577. HMENU hMenu = ::GetSystemMenu(m_hWnd, FALSE);
  578. if( hMenu )
  579. {
  580. MENUITEMINFO mii;
  581. mii.cbSize = sizeof(mii);
  582. mii.fMask = MIIM_ID|MIIM_STATE;
  583. if( GetMenuItemInfo(hMenu, SC_CLOSE, FALSE, &mii ) )
  584. {
  585. if( TESTFLAG(mii.fState, MF_DISABLED) )
  586. {
  587. mii.fState &= ~MF_DISABLED;
  588. }
  589. else
  590. {
  591. mii.fState |= MF_DISABLED;
  592. }
  593. SetMenuItemInfo(hMenu, SC_CLOSE, FALSE, &mii);
  594. SetWindowPos( NULL, 0, 0, 0, 0,
  595. SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_DRAWFRAME );
  596. }
  597. DestroyMenu(hMenu);
  598. }
  599. }
  600. void CMainFrame::OnAltIcon()
  601. {
  602. HICON hIcon = NULL;
  603. m_fAltIcon = !m_fAltIcon;
  604. if( m_fAltIcon )
  605. {
  606. if( !m_hAltIcon )
  607. m_hAltIcon = LoadIcon( AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ALTICON) );
  608. hIcon = m_hAltIcon;
  609. }
  610. else
  611. {
  612. if( !m_hIcon )
  613. m_hIcon = LoadIcon( AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME) );
  614. hIcon = m_hIcon;
  615. }
  616. if( hIcon )
  617. {
  618. SendMessage( WM_SETICON, ICON_BIG, (LPARAM)hIcon );
  619. }
  620. }
  621. void CMainFrame::OnUpdateAltIcon(CCmdUI* pCmdUI)
  622. {
  623. pCmdUI->SetCheck( m_fAltIcon );
  624. }
  625. void CMainFrame::OnAltTitle()
  626. {
  627. m_fAltTitle = !m_fAltTitle;
  628. LPCTSTR pszTitle = NULL;
  629. if( m_fAltTitle )
  630. {
  631. if( m_csAltTitle.IsEmpty() )
  632. m_csAltTitle.LoadString( IDS_ALTTEXT );
  633. pszTitle = m_csAltTitle;
  634. }
  635. else
  636. {
  637. if( m_csTitle.IsEmpty() )
  638. m_csTitle.LoadString( IDR_MAINFRAME );
  639. pszTitle = m_csTitle;
  640. }
  641. if( pszTitle )
  642. SetWindowText( pszTitle );
  643. }
  644. void CMainFrame::OnUpdateAltTitle(CCmdUI* pCmdUI)
  645. {
  646. pCmdUI->SetCheck( m_fAltTitle );
  647. }
  648. void CMainFrame::OnDcAppcompat()
  649. {
  650. m_fDcAppCompat = ! m_fDcAppCompat;
  651. if( m_fDcAppCompat )
  652. m_fDfcAppCompat = FALSE;
  653. SetWindowPos( NULL, 0, 0, 0, 0,
  654. SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_DRAWFRAME );
  655. }
  656. void CMainFrame::OnUpdateDcAppcompat(CCmdUI* pCmdUI)
  657. {
  658. pCmdUI->SetCheck(m_fDcAppCompat);
  659. }
  660. void CMainFrame::OnDfcAppcompat()
  661. {
  662. m_fDfcAppCompat = ! m_fDfcAppCompat;
  663. if( m_fDfcAppCompat )
  664. m_fDcAppCompat = FALSE;
  665. SetWindowPos( NULL, 0, 0, 0, 0,
  666. SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_DRAWFRAME );
  667. }
  668. void CMainFrame::OnUpdateDfcAppcompat(CCmdUI* pCmdUI)
  669. {
  670. pCmdUI->SetCheck(m_fDfcAppCompat);
  671. }
  672. void CMainFrame::OnNcPaint()
  673. {
  674. if( m_fDcAppCompat || m_fDfcAppCompat )
  675. {
  676. RECT rc, rcCaption;
  677. GetWindowRect(&rc);
  678. OffsetRect(&rc, -rc.left, -rc.top );
  679. int cxFrame = GetSystemMetrics( SM_CXSIZEFRAME );
  680. int cyFrame = GetSystemMetrics( SM_CYSIZEFRAME );
  681. int cyCaption = GetSystemMetrics( SM_CYCAPTION );
  682. rcCaption = rc;
  683. rcCaption.left += cxFrame;
  684. rcCaption.right -= cxFrame;
  685. rcCaption.top += cyFrame;
  686. rcCaption.bottom = rcCaption.top + cyCaption;
  687. HDC hdc = ::GetWindowDC(*this);
  688. if( hdc )
  689. {
  690. if( m_fDcAppCompat )
  691. {
  692. DrawCaption( *this, hdc, &rcCaption, DC_GRADIENT|DC_ICON|DC_SMALLCAP|DC_TEXT|0x1000 );
  693. }
  694. else if( m_fDfcAppCompat )
  695. {
  696. int cxEdge = GetSystemMetrics(SM_CXEDGE);
  697. int cyEdge = GetSystemMetrics(SM_CYEDGE);
  698. int cxSize = GetSystemMetrics(SM_CXSIZE);
  699. InflateRect(&rcCaption, -cxEdge, -cyEdge);
  700. rcCaption.left = rcCaption.right - cxSize;
  701. CMDIFrameWnd::OnNcPaint();
  702. DrawFrameControl( hdc, &rcCaption, DFC_CAPTION, DFCS_CAPTIONCLOSE );
  703. }
  704. ::ReleaseDC(*this, hdc);
  705. }
  706. }
  707. else
  708. {
  709. CMDIFrameWnd::OnNcPaint();
  710. }
  711. }
  712. void CMainFrame::DoMinMaxStress()
  713. {
  714. // Set up restored position as 1/2 screen size:
  715. int cxScrn = GetSystemMetrics(SM_CXSCREEN);
  716. int cyScrn = GetSystemMetrics(SM_CYSCREEN);
  717. ShowWindow( SW_SHOWNORMAL );
  718. SetWindowPos( NULL,
  719. cxScrn/4, cyScrn/4,
  720. cxScrn/2, cyScrn/2,
  721. SWP_NOZORDER|SWP_NOACTIVATE );
  722. // Make note of SHOWNORMAL window pos
  723. WINDOWINFO wiNormal0, wiNormal, wiTest;
  724. wiNormal.cbSize = wiTest.cbSize = sizeof(wiNormal);
  725. GetWindowInfo( m_hWnd, &wiNormal0 );
  726. int nCmdShowTest = SW_MINIMIZE;
  727. do
  728. {
  729. MSG msg;
  730. while( PeekMessage( &msg, m_hWnd, 0, 0, PM_REMOVE ) )
  731. {
  732. if( WM_KEYDOWN == msg.message && VK_ESCAPE == msg.wParam )
  733. {
  734. m_fMinMaxStress = FALSE;
  735. break;
  736. }
  737. TranslateMessage( &msg );
  738. DispatchMessage( &msg );
  739. }
  740. ShowWindow( nCmdShowTest );
  741. GetWindowInfo( m_hWnd, &wiTest );
  742. m_pwiNormal0 = &wiNormal0;
  743. ShowWindow( SW_SHOWNORMAL );
  744. m_pwiNormal0 = NULL;
  745. GetWindowInfo( m_hWnd, &wiNormal );
  746. if( RECTWIDTH(&wiNormal.rcWindow) != RECTWIDTH(&wiNormal0.rcWindow) ||
  747. RECTHEIGHT(&wiNormal.rcWindow) != RECTHEIGHT(&wiNormal0.rcWindow) )
  748. {
  749. OutputDebugString( TEXT("MDITEST: SW_SHOWNORMAL size mismatch!!!\n") );
  750. DebugBreak();
  751. }
  752. nCmdShowTest = nCmdShowTest==SW_MINIMIZE ? SW_MAXIMIZE : SW_MINIMIZE;
  753. } while( m_fMinMaxStress );
  754. m_fMinMaxStress = FALSE;
  755. }
  756. void CMainFrame::OnMinMaxStress()
  757. {
  758. m_fMinMaxStress = !m_fMinMaxStress;
  759. if( m_fMinMaxStress )
  760. {
  761. DoMinMaxStress();
  762. }
  763. }
  764. void CMainFrame::OnUpdateMinMaxStress(CCmdUI* pCmdUI)
  765. {
  766. pCmdUI->SetCheck(m_fMinMaxStress);
  767. }
  768. void CMainFrame::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
  769. {
  770. if( m_fMinMaxStress && m_pwiNormal0 )
  771. {
  772. if( 0 == (lpwndpos->flags & SWP_NOSIZE) )
  773. {
  774. if( lpwndpos->cx != RECTWIDTH(&m_pwiNormal0->rcWindow) ||
  775. lpwndpos->cy!= RECTHEIGHT(&m_pwiNormal0->rcWindow) )
  776. {
  777. OutputDebugString( TEXT("MDITEST: WM_WINDOWPOSCHANGING SW_SHOWNORMAL size mismatch!!!\n") );
  778. DebugBreak();
  779. }
  780. }
  781. }
  782. CMDIFrameWnd::OnWindowPosChanging(lpwndpos);
  783. // TODO: Add your message handler code here
  784. }