PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/libusbK/src/inf-wizard2/src/ResizableSheetEx.cpp

http://usb-travis.googlecode.com/
C++ | 611 lines | 428 code | 97 blank | 86 comment | 58 complexity | 399e4d8041a4678821fd9588fedb11e7 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, LGPL-2.0
  1. // ResizableSheetEx.cpp : implementation file
  2. //
  3. /////////////////////////////////////////////////////////////////////////////
  4. //
  5. // This file is part of ResizableLib
  6. // http://sourceforge.net/projects/resizablelib
  7. //
  8. // Copyright (C) 2000-2004 by Paolo Messina
  9. // http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com
  10. //
  11. // The contents of this file are subject to the Artistic License (the "License").
  12. // You may not use this file except in compliance with the License.
  13. // You may obtain a copy of the License at:
  14. // http://www.opensource.org/licenses/artistic-license.html
  15. //
  16. // If you find this code useful, credits would be nice!
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "ResizableSheetEx.h"
  21. #include "Resource.h"
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CResizableSheetEx
  29. IMPLEMENT_DYNAMIC(CResizableSheetEx, CPropertySheetEx)
  30. inline void CResizableSheetEx::PrivateConstruct()
  31. {
  32. m_bEnableSaveRestore = FALSE;
  33. m_bSavePage = FALSE;
  34. m_dwGripTempState = 1;
  35. m_bLayoutDone = FALSE;
  36. m_psh.dwFlags |= PSH_NOCONTEXTHELP;
  37. m_psh.dwFlags &= ~(PSH_HASHELP);
  38. }
  39. inline BOOL CResizableSheetEx::IsWizard() const
  40. {
  41. return (m_psh.dwFlags & PSH_WIZARD);
  42. }
  43. inline BOOL CResizableSheetEx::IsWizard97() const
  44. {
  45. return (m_psh.dwFlags & (PSH_IE4WIZARD97 | PSH_IE5WIZARD97));
  46. }
  47. CResizableSheetEx::CResizableSheetEx()
  48. {
  49. PrivateConstruct();
  50. }
  51. CResizableSheetEx::CResizableSheetEx(UINT nIDCaption, CWnd* pParentWnd,
  52. UINT iSelectPage, HBITMAP hbmWatermark, HPALETTE hpalWatermark,
  53. HBITMAP hbmHeader)
  54. : CPropertySheetEx(nIDCaption, pParentWnd, iSelectPage,
  55. hbmWatermark, hpalWatermark, hbmHeader)
  56. {
  57. PrivateConstruct();
  58. }
  59. CResizableSheetEx::CResizableSheetEx(LPCTSTR pszCaption, CWnd* pParentWnd,
  60. UINT iSelectPage, HBITMAP hbmWatermark, HPALETTE hpalWatermark,
  61. HBITMAP hbmHeader)
  62. : CPropertySheetEx(pszCaption, pParentWnd, iSelectPage,
  63. hbmWatermark, hpalWatermark, hbmHeader)
  64. {
  65. PrivateConstruct();
  66. }
  67. CResizableSheetEx::~CResizableSheetEx()
  68. {
  69. }
  70. BEGIN_MESSAGE_MAP(CResizableSheetEx, CPropertySheetEx)
  71. //{{AFX_MSG_MAP(CResizableSheetEx)
  72. ON_WM_GETMINMAXINFO()
  73. ON_WM_SIZE()
  74. ON_WM_DESTROY()
  75. ON_WM_ERASEBKGND()
  76. ON_WM_NCCREATE()
  77. //}}AFX_MSG_MAP
  78. ON_NOTIFY_REFLECT_EX(PSN_SETACTIVE, OnPageChanging)
  79. ON_REGISTERED_MESSAGE(WMU_RESIZESUPPORT, OnResizeSupport)
  80. ON_BN_CLICKED(ID_WIZDONATE, OnBtnCLickWizDonate)
  81. END_MESSAGE_MAP()
  82. VOID CResizableSheetEx::OnBtnCLickWizDonate()
  83. {
  84. ShellExecute(NULL, NULL, _T("http://sourceforge.net/donate/index.php?group_id=78138"), NULL, NULL, SW_SHOWNORMAL);
  85. }
  86. void CResizableSheetEx::DoDataExchange(CDataExchange* pDX)
  87. {
  88. CPropertySheetEx::DoDataExchange(pDX);
  89. //{{AFX_DATA_MAP(CPageInstall)
  90. // NOTE: the ClassWizard will add DDX and DDV calls here
  91. //}}AFX_DATA_MAP
  92. DDX_Control(pDX, ID_WIZBACK, m_BtnNavBack);
  93. DDX_Control(pDX, ID_WIZNEXT, m_BtnNavNext);
  94. }
  95. /////////////////////////////////////////////////////////////////////////////
  96. // CResizableSheetEx message handlers
  97. BOOL CResizableSheetEx::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
  98. {
  99. if (!CPropertySheetEx::OnNcCreate(lpCreateStruct))
  100. return FALSE;
  101. // child dialogs don't want resizable border or size grip,
  102. // nor they can handle the min/max size constraints
  103. BOOL bChild = lpCreateStruct->style & WS_CHILD;
  104. // create and init the size-grip
  105. if (!CreateSizeGrip(!bChild))
  106. return FALSE;
  107. MakeResizable(lpCreateStruct);
  108. return TRUE;
  109. }
  110. BOOL CResizableSheetEx::OnInitDialog()
  111. {
  112. BOOL bResult = CPropertySheetEx::OnInitDialog();
  113. // set the initial size as the min track size
  114. CRect rc;
  115. GetWindowRect(&rc);
  116. SetMinTrackSize(rc.Size());
  117. // initialize layout
  118. PresetLayout();
  119. m_bLayoutDone = TRUE;
  120. return bResult;
  121. }
  122. LRESULT CResizableSheetEx::OnResizeSupport(WPARAM wParam, LPARAM lParam)
  123. {
  124. switch (wParam)
  125. {
  126. case RSZSUP_SHEETPAGEEXHACK:
  127. {
  128. // a window object must be still associated to the page handle
  129. // but MFC subclassing has been turned off to allow the system
  130. // to subclass it first, so we can catch all the messages
  131. CWnd* pWnd = CWnd::FromHandlePermanent((HWND)lParam);
  132. if (pWnd == NULL)
  133. return 0;
  134. // suclass the window again and refresh page and sheet
  135. pWnd->SubclassWindow(pWnd->Detach());
  136. RefreshLayout();
  137. pWnd->SendMessage(WM_SIZE);
  138. Invalidate();
  139. UnlockWindowUpdate();
  140. if (pWnd->IsWindowVisible())
  141. {
  142. // send lost PSN_SETACTIVE notification message
  143. CPropertyPage* pPage = DYNAMIC_DOWNCAST(CPropertyPage, pWnd);
  144. if (pPage != NULL)
  145. SetActivePage(pPage);
  146. }
  147. }
  148. break;
  149. default:
  150. return FALSE;
  151. }
  152. return TRUE;
  153. }
  154. void CResizableSheetEx::OnDestroy()
  155. {
  156. if (m_bEnableSaveRestore)
  157. {
  158. SaveWindowRect(m_sSection, m_bRectOnly);
  159. if (m_bSavePage)
  160. SavePage(m_sSection);
  161. }
  162. RemoveAllAnchors();
  163. CPropertySheetEx::OnDestroy();
  164. }
  165. // maps an index to a button ID and vice-versa
  166. static UINT _propButtons[] =
  167. {
  168. IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP,
  169. ID_WIZBACK, ID_WIZNEXT, ID_WIZFINISH
  170. };
  171. const int _propButtonsCount = sizeof(_propButtons) / sizeof(UINT);
  172. // horizontal line in wizard mode
  173. #define ID_WIZLINE ID_WIZFINISH+1
  174. #define ID_WIZLINEHDR ID_WIZFINISH+2
  175. void CResizableSheetEx::PresetLayout()
  176. {
  177. if (IsWizard() || IsWizard97()) // wizard mode
  178. {
  179. // hide tab control
  180. GetTabControl()->ShowWindow(SW_HIDE);
  181. AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);
  182. if (IsWizard97()) // add header line for wizard97 dialogs
  183. AddAnchor(ID_WIZLINEHDR, TOP_LEFT, TOP_RIGHT);
  184. }
  185. else // tab mode
  186. {
  187. AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);
  188. }
  189. // add a callback for active page (which can change at run-time)
  190. m_nCallbackID = AddAnchorCallback();
  191. // use *total* parent size to have correct margins
  192. CRect rectPage, rectSheet;
  193. GetTotalClientRect(&rectSheet);
  194. GetActivePage()->GetWindowRect(&rectPage);
  195. ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectPage, 2);
  196. // pre-calculate margins
  197. m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();
  198. m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();
  199. // add all possible buttons, if they exist
  200. for (int i = 0; i < _propButtonsCount; i++)
  201. {
  202. CButton* dlgBtn = reinterpret_cast<CButton*>(GetDlgItem(_propButtons[i]));
  203. if (dlgBtn != NULL)
  204. {
  205. CRect rcBtn;
  206. CString sBtn;
  207. dlgBtn->GetWindowRect(rcBtn);
  208. ScreenToClient(rcBtn);
  209. HBITMAP hBmp = NULL;
  210. switch(_propButtons[i])
  211. {
  212. case ID_WIZBACK:
  213. dlgBtn->SetWindowPos(NULL, rcBtn.left - 16, rcBtn.top - 8, rcBtn.Width(), rcBtn.Height() + 4, SWP_NOZORDER | SWP_NOREDRAW);
  214. sBtn.LoadString(IDS_BACK);
  215. //sBtn.Insert(0, _T(" "));
  216. dlgBtn->SetWindowText(sBtn);
  217. m_BtnNavBack.SubclassDlgItem(_propButtons[i], this);
  218. m_BtnNavBack.SetIcon(IDI_ICON_NAV_BACK);
  219. rcBtn.right = rcBtn.Width() * 2 + 10;
  220. rcBtn.left = 5;
  221. rcBtn.top -= 10;
  222. rcBtn.bottom -= 3;
  223. m_BtnDonate.Create(_T("Help keep us strong!"), WS_CHILD | WS_VISIBLE | WS_GROUP, rcBtn, this, ID_WIZDONATE);
  224. m_BtnDonate.SetIcon(IDI_ICON_DONATE);
  225. m_BtnDonate.SetAlign(CButtonST::ST_ALIGN_HORIZ);
  226. m_BtnDonate.SetDisplayStyle(CButtonST::DISP_FLAT);
  227. m_BtnDonate.SetFont(GetFont(), FALSE);
  228. AddAnchor(ID_WIZDONATE, BOTTOM_LEFT);
  229. AddAnchor(_propButtons[i], BOTTOM_RIGHT);
  230. break;
  231. case ID_WIZNEXT:
  232. dlgBtn->SetWindowPos(NULL, rcBtn.left - 14, rcBtn.top - 8, rcBtn.Width(), rcBtn.Height() + 4, SWP_NOZORDER | SWP_NOREDRAW);
  233. sBtn.LoadString(IDS_NEXT);
  234. //sBtn.Append(_T(" "));
  235. dlgBtn->SetWindowText(sBtn);
  236. m_BtnNavNext.SubclassDlgItem(_propButtons[i], this);
  237. m_BtnNavNext.SetIcon(IDI_ICON_NAV_NEXT);
  238. m_BtnNavNext.SetAlign(CButtonST::ST_ALIGN_HORIZ_RIGHT);
  239. AddAnchor(_propButtons[i], BOTTOM_RIGHT);
  240. break;
  241. case IDCANCEL:
  242. dlgBtn->SetWindowPos(NULL, rcBtn.left - 14, rcBtn.top - 8, rcBtn.Width(), rcBtn.Height() + 4, SWP_NOZORDER | SWP_NOREDRAW);
  243. sBtn.LoadString(IDS_CANCEL);
  244. //sBtn.Append(_T(" "));
  245. dlgBtn->SetWindowText(sBtn);
  246. m_BtnNavCancel.SubclassDlgItem(_propButtons[i], this);
  247. m_BtnNavCancel.SetIcon(IDI_ICON_NAV_CANCEL);
  248. m_BtnNavCancel.SetAlign(CButtonST::ST_ALIGN_HORIZ_RIGHT);
  249. AddAnchor(_propButtons[i], BOTTOM_RIGHT);
  250. break;
  251. case ID_WIZFINISH:
  252. dlgBtn->SetWindowPos(NULL, rcBtn.left - 14, rcBtn.top - 8, rcBtn.Width(), rcBtn.Height() + 4, SWP_NOZORDER | SWP_NOREDRAW);
  253. sBtn.LoadString(IDS_FINISH);
  254. //sBtn.Append(_T(" "));
  255. dlgBtn->SetWindowText(sBtn);
  256. m_BtnNavFinish.SubclassDlgItem(_propButtons[i], this);
  257. m_BtnNavFinish.SetIcon(IDI_ICON_NAV_FINISH);
  258. m_BtnNavFinish.SetAlign(CButtonST::ST_ALIGN_HORIZ_RIGHT);
  259. AddAnchor(_propButtons[i], BOTTOM_RIGHT);
  260. break;
  261. }
  262. }
  263. }
  264. }
  265. BOOL CResizableSheetEx::ArrangeLayoutCallback(LAYOUTINFO& layout) const
  266. {
  267. if (layout.nCallbackID != m_nCallbackID) // we only added 1 callback
  268. return CResizableLayout::ArrangeLayoutCallback(layout);
  269. // set layout info for active page
  270. layout.hWnd = (HWND)::SendMessage(GetSafeHwnd(), PSM_GETCURRENTPAGEHWND, 0, 0);
  271. if (!::IsWindow(layout.hWnd))
  272. return FALSE;
  273. // set margins
  274. if (IsWizard()) // wizard mode
  275. {
  276. // use pre-calculated margins
  277. layout.marginTopLeft = m_sizePageTL;
  278. layout.marginBottomRight = m_sizePageBR;
  279. }
  280. else if (IsWizard97()) // wizard 97
  281. {
  282. // use pre-calculated margins
  283. layout.marginTopLeft = m_sizePageTL;
  284. layout.marginBottomRight = m_sizePageBR;
  285. if (!(GetActivePage()->m_psp.dwFlags & PSP_HIDEHEADER))
  286. {
  287. // add header vertical offset
  288. CRect rectLine, rectSheet;
  289. GetTotalClientRect(&rectSheet);
  290. GetAnchorPosition(ID_WIZLINEHDR, rectSheet, rectLine);
  291. layout.marginTopLeft.cy = rectLine.bottom;
  292. }
  293. }
  294. else // tab mode
  295. {
  296. CTabCtrl* pTab = GetTabControl();
  297. ASSERT(pTab != NULL);
  298. // get tab position after resizing and calc page rect
  299. CRect rectPage, rectSheet;
  300. GetTotalClientRect(&rectSheet);
  301. if (!GetAnchorPosition(pTab->m_hWnd, rectSheet, rectPage))
  302. return FALSE; // no page yet
  303. // temporarily resize the tab control to calc page size
  304. CRect rectSave;
  305. pTab->GetWindowRect(rectSave);
  306. ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectSave, 2);
  307. pTab->SetRedraw(FALSE);
  308. pTab->MoveWindow(rectPage, FALSE);
  309. pTab->AdjustRect(FALSE, &rectPage);
  310. pTab->MoveWindow(rectSave, FALSE);
  311. pTab->SetRedraw(TRUE);
  312. // set margins
  313. layout.marginTopLeft = rectPage.TopLeft() - rectSheet.TopLeft();
  314. layout.marginBottomRight = rectPage.BottomRight() - rectSheet.BottomRight();
  315. }
  316. // set anchor types
  317. layout.anchorTopLeft = TOP_LEFT;
  318. layout.anchorBottomRight = BOTTOM_RIGHT;
  319. // use this layout info
  320. return TRUE;
  321. }
  322. void CResizableSheetEx::OnSize(UINT nType, int cx, int cy)
  323. {
  324. CWnd::OnSize(nType, cx, cy);
  325. if (nType == SIZE_MAXHIDE || nType == SIZE_MAXSHOW)
  326. return; // arrangement not needed
  327. if (nType == SIZE_MAXIMIZED)
  328. HideSizeGrip(&m_dwGripTempState);
  329. else
  330. ShowSizeGrip(&m_dwGripTempState);
  331. // update grip and layout
  332. UpdateSizeGrip();
  333. ArrangeLayout();
  334. if (IsWizard97())
  335. {
  336. // refresh header area
  337. CRect rect;
  338. GetHeaderRect(rect);
  339. InvalidateRect(rect, FALSE);
  340. }
  341. }
  342. BOOL CResizableSheetEx::OnPageChanging(NMHDR* /*pNotifyStruct*/, LRESULT* /*pResult*/)
  343. {
  344. // update new wizard page
  345. // active page changes after this notification
  346. PostMessage(WM_SIZE);
  347. return FALSE; // continue routing
  348. }
  349. BOOL CResizableSheetEx::OnEraseBkgnd(CDC* pDC)
  350. {
  351. if (ClipChildren(pDC, FALSE))
  352. {
  353. // when clipping, remove header from clipping area
  354. if (IsWizard97())
  355. {
  356. // clip header area out
  357. CRect rect;
  358. GetHeaderRect(rect);
  359. pDC->ExcludeClipRect(rect);
  360. }
  361. }
  362. BOOL bRet = CPropertySheetEx::OnEraseBkgnd(pDC);
  363. ClipChildren(pDC, TRUE);
  364. return bRet;
  365. }
  366. BOOL CResizableSheetEx::CalcSizeExtra(HWND /*hWndChild*/, CSize sizeChild, CSize& sizeExtra)
  367. {
  368. CTabCtrl* pTab = GetTabControl();
  369. if (!pTab)
  370. return FALSE;
  371. // get margins of tabcontrol
  372. CRect rectMargins;
  373. if (!GetAnchorMargins(pTab->m_hWnd, sizeChild, rectMargins))
  374. return FALSE;
  375. // get margin caused by tabcontrol
  376. CRect rectTabMargins(0, 0, 0, 0);
  377. // get tab position after resizing and calc page rect
  378. CRect rectPage, rectSheet;
  379. GetTotalClientRect(&rectSheet);
  380. if (!GetAnchorPosition(pTab->m_hWnd, rectSheet, rectPage))
  381. return FALSE; // no page yet
  382. // temporarily resize the tab control to calc page size
  383. CRect rectSave;
  384. pTab->GetWindowRect(rectSave);
  385. ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectSave, 2);
  386. pTab->SetRedraw(FALSE);
  387. pTab->MoveWindow(rectPage, FALSE);
  388. pTab->AdjustRect(TRUE, &rectTabMargins);
  389. pTab->MoveWindow(rectSave, FALSE);
  390. pTab->SetRedraw(TRUE);
  391. // add non-client size
  392. ::AdjustWindowRectEx(&rectTabMargins, GetStyle(), !(GetStyle() & WS_CHILD) &&
  393. ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
  394. // compute extra size
  395. sizeExtra = rectMargins.TopLeft() + rectMargins.BottomRight() +
  396. rectTabMargins.Size();
  397. return TRUE;
  398. }
  399. void CResizableSheetEx::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  400. {
  401. MinMaxInfo(lpMMI);
  402. CTabCtrl* pTab = GetTabControl();
  403. if (!pTab)
  404. return;
  405. int nCount = GetPageCount();
  406. for (int idx = 0; idx < nCount; ++idx)
  407. {
  408. if (IsWizard()) // wizard mode
  409. {
  410. // use pre-calculated margins
  411. CRect rectExtra(-CPoint(m_sizePageTL), -CPoint(m_sizePageBR));
  412. // add non-client size
  413. ::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&
  414. ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
  415. ChainMinMaxInfo(lpMMI, *GetPage(idx), rectExtra.Size());
  416. }
  417. else if (IsWizard97()) // wizard 97
  418. {
  419. // use pre-calculated margins
  420. CRect rectExtra(-CPoint(m_sizePageTL), -CPoint(m_sizePageBR));
  421. if (!(GetPage(idx)->m_psp.dwFlags & PSP_HIDEHEADER))
  422. {
  423. // add header vertical offset
  424. CRect rectLine, rectSheet;
  425. GetTotalClientRect(&rectSheet);
  426. GetAnchorPosition(ID_WIZLINEHDR, rectSheet, rectLine);
  427. rectExtra.top = -rectLine.bottom;
  428. }
  429. // add non-client size
  430. ::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&
  431. ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
  432. ChainMinMaxInfo(lpMMI, *GetPage(idx), rectExtra.Size());
  433. }
  434. else // tab mode
  435. {
  436. ChainMinMaxInfoCB(lpMMI, *GetPage(idx));
  437. }
  438. }
  439. }
  440. // protected members
  441. void CResizableSheetEx::GetHeaderRect(LPRECT lpRect)
  442. {
  443. CWnd* pWizLineHdr = GetDlgItem(ID_WIZLINEHDR);
  444. if (pWizLineHdr != NULL && pWizLineHdr->IsWindowVisible())
  445. {
  446. pWizLineHdr->GetWindowRect(lpRect);
  447. ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)lpRect, 2);
  448. LONG bottom = lpRect->top;
  449. GetClientRect(lpRect);
  450. lpRect->bottom = bottom;
  451. }
  452. else
  453. ::SetRectEmpty(lpRect);
  454. }
  455. int CResizableSheetEx::GetMinWidth()
  456. {
  457. CWnd* pWnd = NULL;
  458. CRect rectWnd, rectSheet;
  459. GetTotalClientRect(&rectSheet);
  460. int max = 0, min = rectSheet.Width();
  461. // search for leftmost and rightmost button margins
  462. for (int i = 0; i < 7; i++)
  463. {
  464. pWnd = GetDlgItem(_propButtons[i]);
  465. // exclude not present or hidden buttons
  466. if (pWnd == NULL || !(pWnd->GetStyle() & WS_VISIBLE))
  467. continue;
  468. // left position is relative to the right border
  469. // of the parent window (negative value)
  470. pWnd->GetWindowRect(&rectWnd);
  471. ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectWnd, 2);
  472. int left = rectSheet.right - rectWnd.left;
  473. int right = rectSheet.right - rectWnd.right;
  474. if (left > max)
  475. max = left;
  476. if (right < min)
  477. min = right;
  478. }
  479. // sizing border width
  480. int border = GetSystemMetrics(SM_CXSIZEFRAME);
  481. // compute total width
  482. return max + min + 2 * border;
  483. }
  484. // NOTE: this must be called after all the other settings
  485. // to have the window and its controls displayed properly
  486. void CResizableSheetEx::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly, BOOL bWithPage)
  487. {
  488. m_sSection = pszSection;
  489. m_bSavePage = bWithPage;
  490. m_bEnableSaveRestore = TRUE;
  491. m_bRectOnly = bRectOnly;
  492. // restore immediately
  493. LoadWindowRect(pszSection, bRectOnly);
  494. if (bWithPage)
  495. {
  496. LoadPage(pszSection);
  497. ArrangeLayout(); // needs refresh
  498. }
  499. }
  500. void CResizableSheetEx::RefreshLayout()
  501. {
  502. SendMessage(WM_SIZE);
  503. }
  504. LRESULT CResizableSheetEx::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  505. {
  506. if (message != WM_NCCALCSIZE || wParam == 0 || !m_bLayoutDone)
  507. return CPropertySheetEx::WindowProc(message, wParam, lParam);
  508. // specifying valid rects needs controls already anchored
  509. LRESULT lResult = 0;
  510. HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);
  511. lResult = CPropertySheetEx::WindowProc(message, wParam, lParam);
  512. HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);
  513. return lResult;
  514. }