void CResizableSheet::PresetLayout()
{
	if (IsWizard())	// wizard mode
	{
		// hide tab control
		GetTabControl()->ShowWindow(SW_HIDE);

		AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);
	}
	else	// tab mode
	{
		AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);
	}

	// add a callback for active page (which can change at run-time)
	AddAnchorCallback(1);

	// use *total* parent size to have correct margins
	CRect rectPage, rectSheet;
	GetTotalClientRect(&rectSheet);

	GetActivePage()->GetWindowRect(&rectPage);
	ScreenToClient(&rectPage);

	// pre-calculate margins
	m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();
	m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();

	// add all possible buttons, if they exist
	for (int i = 0; i < 7; i++)
	{
		if (NULL != GetDlgItem(_propButtons[i]))
			AddAnchor(_propButtons[i], BOTTOM_RIGHT);
	}
}
void CResizableSheet::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) 
{
	MinMaxInfo(lpMMI);

	CTabCtrl* pTab = GetTabControl();
	if (!pTab)
		return;

	int nCount = GetPageCount();
	for (int idx = 0; idx < nCount; ++idx)
	{
		if (IsWizard())	// wizard mode
		{
			// use pre-calculated margins
			CRect rectExtra(-CPoint(m_sizePageTL), -CPoint(m_sizePageBR));
			// add non-client size
			::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&
				::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
			ChainMinMaxInfo(lpMMI, *GetPage(idx), rectExtra.Size());
		}
		else	// tab mode
		{
			ChainMinMaxInfoCB(lpMMI, *GetPage(idx));
		}
	}
}
BOOL CResizableSheet::ArrangeLayoutCallback(LAYOUTINFO &layout) const
{
	if (layout.nCallbackID != m_nCallbackID)	// we only added 1 callback
		return CResizableLayout::ArrangeLayoutCallback(layout);

	// set layout info for active page
	layout.hWnd = (HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0);
	if (!::IsWindow(layout.hWnd))
		return FALSE;

	// set margins
	if (IsWizard())	// wizard mode
	{
		// use pre-calculated margins
		layout.marginTopLeft = m_sizePageTL;
		layout.marginBottomRight = m_sizePageBR;
	}
	else	// tab mode
	{
		CTabCtrl* pTab = GetTabControl();
		ASSERT(pTab != NULL);

		// get tab position after resizing and calc page rect
		CRect rectPage, rectSheet;
		GetTotalClientRect(&rectSheet);

		if (!GetAnchorPosition(pTab->m_hWnd, rectSheet, rectPage))
			return FALSE; // no page yet

		// temporarily resize the tab control to calc page size
		CRect rectSave;
		pTab->GetWindowRect(rectSave);
		::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectSave, 2);
		pTab->SetRedraw(FALSE);
		pTab->MoveWindow(rectPage, FALSE);
		pTab->AdjustRect(FALSE, &rectPage);
		pTab->MoveWindow(rectSave, FALSE);
		pTab->SetRedraw(TRUE);

		// set margins
		layout.marginTopLeft = rectPage.TopLeft() - rectSheet.TopLeft();
		layout.marginBottomRight = rectPage.BottomRight() - rectSheet.BottomRight();
	}

	// set anchor types
	layout.anchorTopLeft = TOP_LEFT;
	layout.anchorBottomRight = BOTTOM_RIGHT;

	// use this layout info
	return TRUE;
}
void CResizableSheet::PresetLayout()
{
	// set the initial size as the min track size
	CRect rc;
	GetWindowRect(&rc);
	SetMinTrackSize(rc.Size());

	if (GetStyle() & WS_CHILD)
	{
		GetClientRect(&rc);
		GetTabControl()->MoveWindow(&rc);
	}

	if (IsWizard())	// wizard mode
	{
		// hide tab control
		GetTabControl()->ShowWindow(SW_HIDE);

		AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);
	}
	else	// tab mode
	{
		AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);
	}

	// add a callback for active page (which can change at run-time)
	m_nCallbackID = AddAnchorCallback();

	// use *total* parent size to have correct margins
	CRect rectPage, rectSheet;
	GetTotalClientRect(&rectSheet);

	GetActivePage()->GetWindowRect(&rectPage);
	::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectPage, 2);

	// pre-calculate margins
	m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();
	m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();

	// add all possible buttons, if they exist
	for (int i = 0; i < _propButtonsCount; i++)
	{
		if (NULL != GetDlgItem(_propButtons[i]))
			AddAnchor(_propButtons[i], BOTTOM_RIGHT);
	}

	// prevent flickering
	GetTabControl()->ModifyStyle(0, WS_CLIPSIBLINGS);
}
BOOL CXTPResizePropertySheet::OnPageChanging(NMHDR* /*pNotifyStruct*/, LRESULT* /*pResult*/)
{
	// When in wizard mode, the property sheet seems to resize/move the page
	// back to it's original size/position on the sheet.  We need to let the
	// size manager know that this has occurred, so that it can move the pages
	// back to the correct position
	if (IsWizard())
	{
		CXTPResize::Reset();
	}

	// Update new wizard page, the active page changes after this notification
	CXTPResize::Size();

	// and continue routing...
	return FALSE;
}
void CResizableSheetEx::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) 
{
	MinMaxInfo(lpMMI);

	CTabCtrl* pTab = GetTabControl();
	if (!pTab)
		return;

	int nCount = GetPageCount();
	for (int idx = 0; idx < nCount; ++idx)
	{
		if (IsWizard())	// wizard mode
		{
			// use pre-calculated margins
			CRect rectExtra(-CPoint(m_sizePageTL), -CPoint(m_sizePageBR));
			// add non-client size
			::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&
				::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
			ChainMinMaxInfo(lpMMI, *GetPage(idx), rectExtra.Size());
		}
		else if (IsWizard97())	// wizard 97
		{
			// use pre-calculated margins
			CRect rectExtra(-CPoint(m_sizePageTL), -CPoint(m_sizePageBR));

			if (!(GetPage(idx)->m_psp.dwFlags & PSP_HIDEHEADER))
			{
				// add header vertical offset
				CRect rectLine, rectSheet;
				GetTotalClientRect(&rectSheet);
				GetAnchorPosition(ID_WIZLINEHDR, rectSheet, rectLine);

				rectExtra.top = -rectLine.bottom;
			}
			// add non-client size
			::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&
				::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
			ChainMinMaxInfo(lpMMI, *GetPage(idx), rectExtra.Size());
		}
		else	// tab mode
		{
			ChainMinMaxInfoCB(lpMMI, *GetPage(idx));
		}
	}
}
void CResizableSheetEx::PresetLayout()
{
	if (IsWizard() || IsWizard97())	// wizard mode
	{
		// hide tab control
		GetTabControl()->ShowWindow(SW_HIDE);

		AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);

		if (IsWizard97())	// add header line for wizard97 dialogs
			AddAnchor(ID_WIZLINEHDR, TOP_LEFT, TOP_RIGHT);
	}
	else	// tab mode
	{
		AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);
	}

	// add a callback for active page (which can change at run-time)
	m_nCallbackID = AddAnchorCallback();

	// use *total* parent size to have correct margins
	CRect rectPage, rectSheet;
	GetTotalClientRect(&rectSheet);

	GetActivePage()->GetWindowRect(&rectPage);
	::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectPage, 2);

	// pre-calculate margins
	m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();
	m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();

	// add all possible buttons, if they exist
	for (int i = 0; i < _propButtonsCount; i++)
	{
		if (NULL != GetDlgItem(_propButtons[i]))
			AddAnchor(_propButtons[i], BOTTOM_RIGHT);
	}
}
BOOL CResizableSheet::ArrangeLayoutCallback(LayoutInfo &layout)
{
	if (layout.nCallbackID != 1)	// we only added 1 callback
		return CResizableLayout::ArrangeLayoutCallback(layout);

	// set layout info for active page
	layout.hWnd = GetActivePage()->GetSafeHwnd();

	// set margins
	if (IsWizard())	// wizard mode
	{
		// use pre-calculated margins
		layout.sizeMarginTL = m_sizePageTL;
		layout.sizeMarginBR = m_sizePageBR;
	}
	else	// tab mode
	{
		CRect rectPage, rectSheet;
		GetTotalClientRect(&rectSheet);

		CTabCtrl* pTab = GetTabControl();
		pTab->GetWindowRect(&rectPage);
		pTab->AdjustRect(FALSE, &rectPage);
		ScreenToClient(&rectPage);

		// use tab control
		layout.sizeMarginTL = rectPage.TopLeft() - rectSheet.TopLeft();
		layout.sizeMarginBR = rectPage.BottomRight() - rectSheet.BottomRight();
	}

	// set anchor types
	layout.sizeTypeTL = TOP_LEFT;
	layout.sizeTypeBR = BOTTOM_RIGHT;

	// use this layout info
	return TRUE;
}
BOOL CXTPResizePropertySheet::OnInitDialog()
{

	CRect rcClientBegin, rcClientEnd;
	GetWindowRect(rcClientBegin);
	SendMessage(WM_NCCALCSIZE, FALSE, (LPARAM)(LPRECT)rcClientBegin);

	// Modify the window style to include WS_THICKFRAME for resizing.
	::SetWindowLong(m_hWnd,
		GWL_STYLE, GetStyle() | WS_THICKFRAME);

	GetWindowRect(rcClientEnd);
	SendMessage(WM_NCCALCSIZE, FALSE, (LPARAM)(LPRECT)rcClientEnd);

	CPropertySheet::OnInitDialog();

	// subclass our "flicker-free" tab control.
	m_tabCtrl.SubclassWindow(GetTabControl()->m_hWnd);

	// the size icon is too close to the buttons, so inflate the sheet
	CRect rc;
	GetWindowRect(rc);

	if (rcClientBegin.Width() - rcClientEnd.Width() > 3)
	{
		rc.InflateRect((rcClientBegin.Width() - rcClientEnd.Width()) / 2,
			(rcClientBegin.Height() - rcClientEnd.Height()) / 2);
		MoveWindow(rc);
	}
	// Do this last so that any prop pages are moved accordingly
	else if (!HasFlag(xtpResizeNoSizeIcon) && !IsWizard())
	{
		rc.InflateRect(1, 1, 2, 2);
		MoveWindow(rc);
	}

	// add sizing entries to the system menu
	CMenu* pSysMenu = (CMenu*)GetSystemMenu(FALSE);
	if (pSysMenu)
	{
		CString szMaximize, szMinimize, szSize, szRestore;
		// try to get the strings from the topmost window
		CWnd* pwndTop;
		for (pwndTop = this; pwndTop->GetParent(); pwndTop = pwndTop->GetParent());

		CMenu* pTopSysMenu = (CMenu*)pwndTop->GetSystemMenu(FALSE);
		if (pTopSysMenu)
		{
			pTopSysMenu->GetMenuString(SC_MAXIMIZE, szMaximize, MF_BYCOMMAND);
			pTopSysMenu->GetMenuString(SC_MINIMIZE, szMinimize, MF_BYCOMMAND);
			pTopSysMenu->GetMenuString(SC_SIZE, szSize, MF_BYCOMMAND);
			pTopSysMenu->GetMenuString(SC_RESTORE, szRestore, MF_BYCOMMAND);
		}
		// if we din't get the strings then set them to the English defaults
		if (szMaximize.IsEmpty()) szMaximize = _T("Ma&ximize");
		if (szMinimize.IsEmpty()) szMinimize = _T("Mi&nimize");
		if (szSize.IsEmpty()) szSize = _T("&Size");
		if (szRestore.IsEmpty()) szRestore = _T("&Restore");

		pSysMenu->InsertMenu(1, MF_BYPOSITION | MF_SEPARATOR, 0, (LPCTSTR) 0);
		pSysMenu->InsertMenu(1, MF_BYPOSITION | MF_STRING, SC_MAXIMIZE, szMaximize);
		pSysMenu->InsertMenu(1, MF_BYPOSITION | MF_STRING, SC_MINIMIZE, szMinimize);
		pSysMenu->InsertMenu(1, MF_BYPOSITION | MF_STRING, SC_SIZE, szSize);
		pSysMenu->InsertMenu(0, MF_BYPOSITION | MF_STRING, SC_RESTORE, szRestore);
	}

	DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
	if ((dwStyle & WS_THICKFRAME) == 0)
	{
		SetFlag(xtpResizeNoSizeIcon);
	}

	CXTPResize::Init();

	// Check which buttons are available in sheet or wizard
	if (IsWizard())
	{
		SetResize(ID_WIZBACK, XTP_ATTR_REPOS(1));
		SetResize(ID_WIZNEXT, XTP_ATTR_REPOS(1));
		SetResize(ID_WIZFINISH, XTP_ATTR_REPOS(1));
		SetResize(ID_WIZLINE, XTP_ANCHOR_BOTTOMLEFT, XTP_ANCHOR_BOTTOMRIGHT);
	}
	else
	{
		SetResize(IDOK, XTP_ATTR_REPOS(1));
		SetResize(ID_APPLY_NOW, XTP_ATTR_REPOS(1));
		SetResize(AFX_IDC_TAB_CONTROL, XTP_ATTR_RESIZE(1));
	}
	SetResize(IDCANCEL, XTP_ATTR_REPOS(1));
	SetResize(IDHELP, XTP_ATTR_REPOS(1));

	// set page sizings
	CRect rcPage;
	GetActivePage()->GetWindowRect(rcPage);
	ScreenToClient(rcPage);
	int i;
	for (i = 0; i <GetPageCount(); i++)
	{
		SetResize(GetPage(i), XTP_ATTR_RESIZE(1), rcPage);
	}


	return TRUE;
}
void CBasePropertySheet::AddPage(CPropertyPage* pPage)
{
	ASSERT_VALID(this);
	ASSERT(pPage != NULL);
	ASSERT_KINDOF(CPropertyPage, pPage);
	ASSERT_VALID(pPage);

	// add page to internal list
	m_pages.Add(pPage);

	// add page externally
	if (m_hWnd != NULL)
	{
		// build new prop page array
		AFX_OLDPROPSHEETPAGE *ppsp = new AFX_OLDPROPSHEETPAGE[m_pages.GetSize()];
		memcpy(ppsp, m_psh.ppsp, sizeof(AFX_OLDPROPSHEETPAGE) * (m_pages.GetSize()-1));
		delete[] (PROPSHEETPAGE*)m_psh.ppsp;
		m_psh.ppsp = (PROPSHEETPAGE*)ppsp;
		ppsp += m_pages.GetSize()-1;

		// copy processed PROPSHEETPAGE struct to end
		memcpy(ppsp, &pPage->m_psp, sizeof(pPage->m_psp));
//		pPage->PreProcessPageTemplate((PROPSHEETPAGE&)*ppsp, IsWizard());
		CPropertyPage_PreProcessPageTemplate((_CCPropertyPage*)pPage, (PROPSHEETPAGE&)*ppsp, IsWizard());
		HPROPSHEETPAGE hPSP = CreatePropertySheetPage((PROPSHEETPAGE*)ppsp);
		if (hPSP == NULL)
			AfxThrowMemoryException();

		if (!SendMessage(PSM_ADDPAGE, 0, (LPARAM)hPSP))
		{
			DestroyPropertySheetPage(hPSP);
			AfxThrowMemoryException();
		}
	}
}
void CBasePropertySheet::AddPage(CPropertyPage* pPage)
{
	ASSERT_VALID(this);
	ENSURE_VALID(pPage);
	ASSERT_KINDOF(CPropertyPage, pPage);

	// add page to internal list
	m_pages.Add(pPage);

	// add page externally
	if (m_hWnd != NULL)
	{
		// determine size of PROPSHEETPAGE array
		PROPSHEETPAGE* ppsp = const_cast<PROPSHEETPAGE*>(m_psh.ppsp);
		int nBytes = 0;
		int nNextBytes;
		for (UINT i = 0; i < m_psh.nPages; i++)
		{
			nNextBytes = nBytes + ppsp->dwSize;
			if ((nNextBytes < nBytes) || (nNextBytes < (int)ppsp->dwSize))
				AfxThrowMemoryException();
			nBytes = nNextBytes;
			(BYTE*&)ppsp += ppsp->dwSize;
		}

		nNextBytes = nBytes + pPage->m_psp.dwSize;
		if ((nNextBytes < nBytes) || (nNextBytes < (int)pPage->m_psp.dwSize))
			AfxThrowMemoryException();

		// build new prop page array
		ppsp = (PROPSHEETPAGE*)realloc((void*)m_psh.ppsp, nNextBytes);
		if (ppsp == NULL)
			AfxThrowMemoryException();
		m_psh.ppsp = ppsp;

		// copy processed PROPSHEETPAGE struct to end
		(BYTE*&)ppsp += nBytes;
		Checked::memcpy_s(ppsp, nNextBytes - nBytes , &pPage->m_psp, pPage->m_psp.dwSize);
//		pPage->PreProcessPageTemplate(*ppsp, IsWizard());
		CPropertyPage_PreProcessPageTemplate((_CCPropertyPage*)pPage, *ppsp, IsWizard());
		if (!((_CCPropertyPage*)pPage)->m_strHeaderTitle.IsEmpty())
		{
			ppsp->pszHeaderTitle = ((_CCPropertyPage*)pPage)->m_strHeaderTitle;
			ppsp->dwFlags |= PSP_USEHEADERTITLE;
		}
		if (!((_CCPropertyPage*)pPage)->m_strHeaderSubTitle.IsEmpty())
		{
			ppsp->pszHeaderSubTitle = ((_CCPropertyPage*)pPage)->m_strHeaderSubTitle;
			ppsp->dwFlags |= PSP_USEHEADERSUBTITLE;
		}
		HPROPSHEETPAGE hPSP = AfxCreatePropertySheetPage(ppsp);
		if (hPSP == NULL)
			AfxThrowMemoryException();

		if (!SendMessage(PSM_ADDPAGE, 0, (LPARAM)hPSP))
		{
			AfxDestroyPropertySheetPage(hPSP);
			AfxThrowMemoryException();
		}
		++m_psh.nPages;
	}
}
void CResizableSheetEx::PresetLayout()
{
	if (IsWizard() || IsWizard97())	// wizard mode
	{
		// hide tab control
		GetTabControl()->ShowWindow(SW_HIDE);

		AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);

		if (IsWizard97())	// add header line for wizard97 dialogs
			AddAnchor(ID_WIZLINEHDR, TOP_LEFT, TOP_RIGHT);
	}
	else	// tab mode
	{
		AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);
	}

	// add a callback for active page (which can change at run-time)
	m_nCallbackID = AddAnchorCallback();

	// use *total* parent size to have correct margins
	CRect rectPage, rectSheet;
	GetTotalClientRect(&rectSheet);

	GetActivePage()->GetWindowRect(&rectPage);
	::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectPage, 2);

	// pre-calculate margins
	m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();
	m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();

	// add all possible buttons, if they exist
	for (int i = 0; i < _propButtonsCount; i++)
	{
		CButton* dlgBtn = reinterpret_cast<CButton*>(GetDlgItem(_propButtons[i]));
		if (dlgBtn != NULL)
		{
			CRect rcBtn;
			CString sBtn;

			dlgBtn->GetWindowRect(rcBtn);
			ScreenToClient(rcBtn);

			HBITMAP hBmp = NULL;
			switch(_propButtons[i])
			{
			case ID_WIZBACK:
				dlgBtn->SetWindowPos(NULL, rcBtn.left - 16, rcBtn.top - 8, rcBtn.Width(), rcBtn.Height() + 4, SWP_NOZORDER | SWP_NOREDRAW);
				sBtn.LoadString(IDS_BACK);
				//sBtn.Insert(0, _T("  "));
				dlgBtn->SetWindowText(sBtn);
				m_BtnNavBack.SubclassDlgItem(_propButtons[i], this);
				m_BtnNavBack.SetIcon(IDI_ICON_NAV_BACK);

				rcBtn.right = rcBtn.Width() * 2 + 10;
				rcBtn.left = 5;
				rcBtn.top -= 10;
				rcBtn.bottom -= 3;

				m_BtnDonate.Create(_T("Help keep us strong!"), WS_CHILD | WS_VISIBLE | WS_GROUP, rcBtn, this, ID_WIZDONATE);
				m_BtnDonate.SetIcon(IDI_ICON_DONATE);
				m_BtnDonate.SetAlign(CButtonST::ST_ALIGN_HORIZ);
				m_BtnDonate.SetDisplayStyle(CButtonST::DISP_FLAT);
				m_BtnDonate.SetFont(GetFont(), FALSE);

				AddAnchor(ID_WIZDONATE, BOTTOM_LEFT);
				AddAnchor(_propButtons[i], BOTTOM_RIGHT);
				break;
			case ID_WIZNEXT:
				dlgBtn->SetWindowPos(NULL, rcBtn.left - 14, rcBtn.top - 8, rcBtn.Width(), rcBtn.Height() + 4, SWP_NOZORDER | SWP_NOREDRAW);
				sBtn.LoadString(IDS_NEXT);
				//sBtn.Append(_T("  "));
				dlgBtn->SetWindowText(sBtn);
				m_BtnNavNext.SubclassDlgItem(_propButtons[i], this);
				m_BtnNavNext.SetIcon(IDI_ICON_NAV_NEXT);
				m_BtnNavNext.SetAlign(CButtonST::ST_ALIGN_HORIZ_RIGHT);
				AddAnchor(_propButtons[i], BOTTOM_RIGHT);
				break;
			case IDCANCEL:
				dlgBtn->SetWindowPos(NULL, rcBtn.left - 14, rcBtn.top - 8, rcBtn.Width(), rcBtn.Height() + 4, SWP_NOZORDER | SWP_NOREDRAW);
				sBtn.LoadString(IDS_CANCEL);
				//sBtn.Append(_T("  "));
				dlgBtn->SetWindowText(sBtn);
				m_BtnNavCancel.SubclassDlgItem(_propButtons[i], this);
				m_BtnNavCancel.SetIcon(IDI_ICON_NAV_CANCEL);
				m_BtnNavCancel.SetAlign(CButtonST::ST_ALIGN_HORIZ_RIGHT);
				AddAnchor(_propButtons[i], BOTTOM_RIGHT);
				break;
			case ID_WIZFINISH:
				dlgBtn->SetWindowPos(NULL, rcBtn.left - 14, rcBtn.top - 8, rcBtn.Width(), rcBtn.Height() + 4, SWP_NOZORDER | SWP_NOREDRAW);
				sBtn.LoadString(IDS_FINISH);
				//sBtn.Append(_T("  "));
				dlgBtn->SetWindowText(sBtn);
				m_BtnNavFinish.SubclassDlgItem(_propButtons[i], this);
				m_BtnNavFinish.SetIcon(IDI_ICON_NAV_FINISH);
				m_BtnNavFinish.SetAlign(CButtonST::ST_ALIGN_HORIZ_RIGHT);
				AddAnchor(_propButtons[i], BOTTOM_RIGHT);
				break;
			}
		}
	}
}
void CResizableSheetEx::PresetLayout()
{
	// set the initial size as the min track size
	CRect rc;
	GetWindowRect(&rc);
	SetMinTrackSize(rc.Size());

	// use *total* parent size to have correct margins
	CRect rectPage, rectSheet;
	GetTotalClientRect(&rectSheet);

	// get page area
	if (IsWizard() || IsWizard97())
	{
		HWND hPage = PropSheet_GetCurrentPageHwnd(m_hWnd);
		::GetWindowRect(hPage, &rectPage);
	}
	else
	{
		GetTabControl()->GetWindowRect(&rectPage);
	}
	::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectPage, 2);

	// calculate margins
	CRect rect;
	int cxDiff = rectSheet.right - rectPage.right;
	int cyDiff = 0;

	// try all possible buttons
	for (int i = 0; i < _propButtonsCount; i++)
	{
		CWnd* pWnd = GetDlgItem(_propButtons[i]);
		if (NULL != pWnd)
		{
			// move buttons if necessary
			if (GetStyle() & WS_CHILD)
			{
				pWnd->GetWindowRect(&rect);
				::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rect, 2);

				cyDiff = rectSheet.bottom - rect.bottom;
				rect.OffsetRect(cxDiff, cyDiff);

				pWnd->MoveWindow(&rect);
			}
			// add buttons to the layout manager
			AddAnchor(_propButtons[i], BOTTOM_RIGHT);
		}
	}

	// setup pages area
	if (IsWizard() || IsWizard97())
	{
		// move line and pages if necessary
		if (GetStyle() & WS_CHILD)
		{
			GetDlgItem(ID_WIZLINE)->GetWindowRect(&rect);
			::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rect, 2);

			rect.OffsetRect(0, cyDiff);
			rect.InflateRect(cxDiff, 0);

			GetDlgItem(ID_WIZLINE)->MoveWindow(&rect);

			rectPage.bottom += cyDiff;
			rectPage.left = 0;
			rectPage.top = 0;
			rectPage.right = rectSheet.right;
		}

		AddAnchor(ID_WIZLINE, BOTTOM_LEFT, BOTTOM_RIGHT);

		if (IsWizard97())	// add header line for wizard97 dialogs
			AddAnchor(ID_WIZLINEHDR, TOP_LEFT, TOP_RIGHT);

		// hide tab control
		GetTabControl()->ShowWindow(SW_HIDE);

		// pre-calculate margins
		m_sizePageTL = rectPage.TopLeft() - rectSheet.TopLeft();
		m_sizePageBR = rectPage.BottomRight() - rectSheet.BottomRight();
	}
	else
	{
		// grow tab to the available sheet space
		if (cyDiff > 0)
			rectSheet.bottom = rectPage.bottom + cyDiff;
		
		if (GetStyle() & WS_CHILD)
			GetTabControl()->MoveWindow(&rectSheet);

		AddAnchor(AFX_IDC_TAB_CONTROL, TOP_LEFT, BOTTOM_RIGHT);
	}

	// add a callback for active page (which can change at run-time)
	m_nCallbackID = AddAnchorCallback();

	// prevent flickering
	GetTabControl()->ModifyStyle(0, WS_CLIPSIBLINGS);
}