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); } }
int CResizableSheetEx::GetMinWidth() { CWnd* pWnd = NULL; CRect rectWnd, rectSheet; GetTotalClientRect(&rectSheet); int max = 0, min = rectSheet.Width(); // search for leftmost and rightmost button margins for (int i = 0; i < 7; i++) { pWnd = GetDlgItem(_propButtons[i]); // exclude not present or hidden buttons if (pWnd == NULL || !(pWnd->GetStyle() & WS_VISIBLE)) continue; // left position is relative to the right border // of the parent window (negative value) pWnd->GetWindowRect(&rectWnd); ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rectWnd, 2); int left = rectSheet.right - rectWnd.left; int right = rectSheet.right - rectWnd.right; if (left > max) max = left; if (right < min) min = right; } // sizing border width int border = GetSystemMetrics(SM_CXSIZEFRAME); // compute total width return max + min + 2*border; }
void CResizableLayout::AddAnchor(HWND hWnd, CSize sizeTypeTL, CSize sizeTypeBR) { CWnd* pParent = GetResizableWnd(); // child window must be valid ASSERT(::IsWindow(hWnd)); // must be child of parent window // ASSERT(::IsChild(pParent->GetSafeHwnd(), hWnd)); // top-left anchor must be valid ASSERT(sizeTypeTL != NOANCHOR); // get control's window class CString sClassName; GetClassName(hWnd, sClassName.GetBufferSetLength(MAX_PATH), MAX_PATH); sClassName.ReleaseBuffer(); // get parent window's rect CRect rectParent; GetTotalClientRect(&rectParent); // and child control's rect CRect rectChild; ::GetWindowRect(hWnd, &rectChild); ::MapWindowPoints(NULL, pParent->m_hWnd, (LPPOINT)&rectChild, 2); // adjust position, if client area has been scrolled rectChild.OffsetRect(-rectParent.TopLeft()); // go calculate margins CSize sizeMarginTL, sizeMarginBR; if (sizeTypeBR == NOANCHOR) sizeTypeBR = sizeTypeTL; // calculate margin for the top-left corner sizeMarginTL.cx = rectChild.left - rectParent.Width() * sizeTypeTL.cx / 100; sizeMarginTL.cy = rectChild.top - rectParent.Height() * sizeTypeTL.cy / 100; // calculate margin for the bottom-right corner sizeMarginBR.cx = rectChild.right - rectParent.Width() * sizeTypeBR.cx / 100; sizeMarginBR.cy = rectChild.bottom - rectParent.Height() * sizeTypeBR.cy / 100; // prepare the structure LayoutInfo layout(hWnd, sizeTypeTL, sizeMarginTL, sizeTypeBR, sizeMarginBR, sClassName); // initialize resize properties (overridable) InitResizeProperties(layout); // must not be already there! // (this is probably due to a duplicate call to AddAnchor) POSITION pos; ASSERT(!m_mapLayout.Lookup(hWnd, pos)); // add to the list and the map pos = m_listLayout.AddTail(layout); m_mapLayout.SetAt(hWnd, pos); }
void CResizableLayout::ArrangeLayout() { // common vars UINT uFlags; LayoutInfo layout; CRect rectParent, rectChild; GetTotalClientRect(&rectParent); // get parent window's rect int count = m_listLayout.GetCount(); int countCB = m_listLayoutCB.GetCount(); // reposition child windows HDWP hdwp = ::BeginDeferWindowPos(count + countCB); POSITION pos = m_listLayout.GetHeadPosition(); while (pos != NULL) { // get layout info layout = m_listLayout.GetNext(pos); // calculate new child's position, size and flags for SetWindowPos CalcNewChildPosition(layout, rectParent, rectChild, uFlags); // only if size or position changed if ((uFlags & (SWP_NOMOVE|SWP_NOSIZE)) != (SWP_NOMOVE|SWP_NOSIZE)) { hdwp = ::DeferWindowPos(hdwp, layout.hWnd, NULL, rectChild.left, rectChild.top, rectChild.Width(), rectChild.Height(), uFlags); } } // for callback items you may use GetAnchorPosition to know the // new position and size of a non-callback item after resizing pos = m_listLayoutCB.GetHeadPosition(); while (pos != NULL) { // get layout info layout = m_listLayoutCB.GetNext(pos); // request layout data if (!ArrangeLayoutCallback(layout)) continue; // calculate new child's position, size and flags for SetWindowPos CalcNewChildPosition(layout, rectParent, rectChild, uFlags); // only if size or position changed if ((uFlags & (SWP_NOMOVE|SWP_NOSIZE)) != (SWP_NOMOVE|SWP_NOSIZE)) { hdwp = ::DeferWindowPos(hdwp, layout.hWnd, NULL, rectChild.left, rectChild.top, rectChild.Width(), rectChild.Height(), uFlags); } } // finally move all the windows at once ::EndDeferWindowPos(hdwp); }
/*! * This function adds a new control to the layout manager and sets anchor * points for its top-left and bottom-right corners. * * @param hWnd Window handle to the control to be added * @param anchorTopLeft Anchor point for the top-left corner * @param anchorBottomRight Anchor point for the bottom-right corner * * @remarks Overlapping controls, like group boxes and the controls inside, * must be added from the outer controls to the inner ones, to let * the clipping routines work correctly. * * @sa AddAnchorCallback RemoveAnchor */ void CResizableLayout::AddAnchor(HWND hWnd, ANCHOR anchorTopLeft, ANCHOR anchorBottomRight) { CWnd* pParent = GetResizableWnd(); // child window must be valid ASSERT(::IsWindow(hWnd)); // must be child of parent window ASSERT(::IsChild(pParent->GetSafeHwnd(), hWnd)); // get parent window's rect CRect rectParent; GetTotalClientRect(&rectParent); // and child control's rect CRect rectChild; ::GetWindowRect(hWnd, &rectChild); ::MapWindowPoints(NULL, pParent->m_hWnd, (LPPOINT)&rectChild, 2); // adjust position, if client area has been scrolled rectChild.OffsetRect(-rectParent.TopLeft()); // go calculate margins CSize marginTopLeft, marginBottomRight; // calculate margin for the top-left corner marginTopLeft.cx = rectChild.left - rectParent.Width() * anchorTopLeft.cx / 100; marginTopLeft.cy = rectChild.top - rectParent.Height() * anchorTopLeft.cy / 100; // calculate margin for the bottom-right corner marginBottomRight.cx = rectChild.right - rectParent.Width() * anchorBottomRight.cx / 100; marginBottomRight.cy = rectChild.bottom - rectParent.Height() * anchorBottomRight.cy / 100; // prepare the structure LAYOUTINFO layout(hWnd, anchorTopLeft, marginTopLeft, anchorBottomRight, marginBottomRight); // get control's window class GetClassName(hWnd, layout.sWndClass, MAX_PATH); // initialize resize properties (overridable) InitResizeProperties(layout); // must not be already there! // (this is probably due to a duplicate call to AddAnchor) POSITION pos; ASSERT(!m_mapLayout.Lookup(hWnd, pos)); // add to the list and the map pos = m_listLayout.AddTail(layout); m_mapLayout.SetAt(hWnd, pos); }
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); }
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)); } } }
BOOL CResizableSheetEx::CalcSizeExtra(HWND /*hWndChild*/, CSize sizeChild, CSize &sizeExtra) { CTabCtrl* pTab = GetTabControl(); if (!pTab) return FALSE; // get margins of tabcontrol CRect rectMargins; if (!GetAnchorMargins(pTab->m_hWnd, sizeChild, rectMargins)) return FALSE; // get margin caused by tabcontrol CRect rectTabMargins(0,0,0,0); // 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(TRUE, &rectTabMargins); pTab->MoveWindow(rectSave, FALSE); pTab->SetRedraw(TRUE); // add non-client size ::AdjustWindowRectEx(&rectTabMargins, GetStyle(), !(GetStyle() & WS_CHILD) && ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle()); // compute extra size sizeExtra = rectMargins.TopLeft() + rectMargins.BottomRight() + rectTabMargins.Size(); return TRUE; }
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; }
void CResizableLayout::AddAnchor(HWND hWnd, CSize sizeTypeTL, CSize sizeTypeBR) { CWnd* pParent = GetResizableWnd(); // child window must be valid ASSERT(::IsWindow(hWnd)); // must be child of parent window ASSERT(::IsChild(pParent->GetSafeHwnd(), hWnd)); // top-left anchor must be valid ASSERT(sizeTypeTL != NOANCHOR); // get control's window class CString st; GetClassName(hWnd, st.GetBufferSetLength(MAX_PATH), MAX_PATH); st.ReleaseBuffer(); st.MakeUpper(); // add the style 'clipsiblings' to a GroupBox // to avoid unnecessary repainting of controls inside if (st == "BUTTON") { DWORD style = GetWindowLong(hWnd, GWL_STYLE); if ((style & 0x0FL) == BS_GROUPBOX) SetWindowLong(hWnd, GWL_STYLE, style | WS_CLIPSIBLINGS); } // window classes that don't redraw client area correctly // when the hor scroll pos changes due to a resizing BOOL hscroll = FALSE; if (st == "LISTBOX") hscroll = TRUE; // window classes that need refresh when resized BOOL refresh = NeedsRefresh(hWnd); // get parent window's rect CRect rectParent; GetTotalClientRect(&rectParent); // and child control's rect CRect rectChild; ::GetWindowRect(hWnd, &rectChild); pParent->ScreenToClient(&rectChild); // go calculate margins CSize sizeMarginTL, sizeMarginBR; if (sizeTypeBR == NOANCHOR) sizeTypeBR = sizeTypeTL; // calculate margin for the top-left corner sizeMarginTL.cx = rectChild.left - rectParent.Width() * sizeTypeTL.cx / 100; sizeMarginTL.cy = rectChild.top - rectParent.Height() * sizeTypeTL.cy / 100; // calculate margin for the bottom-right corner sizeMarginBR.cx = rectChild.right - rectParent.Width() * sizeTypeBR.cx / 100; sizeMarginBR.cy = rectChild.bottom - rectParent.Height() * sizeTypeBR.cy / 100; // add to the list LayoutInfo layout(hWnd, sizeTypeTL, sizeMarginTL, sizeTypeBR, sizeMarginBR, hscroll, refresh); // always add to head (before callbacks) m_arrLayout.InsertAt(0, layout); }
void CResizableLayout::ArrangeLayout() { CWnd* pParent = GetResizableWnd(); // get parent window's rect CRect rectParent; GetTotalClientRect(&rectParent); // init some vars BOOL bCallbackPassed = FALSE; int i, count = (int)m_arrLayout.GetSize(); HDWP hdwp = BeginDeferWindowPos(count); for (i=0; i<count; ++i) { LayoutInfo layout = m_arrLayout[i]; if (layout.hWnd == NULL) // callback { if (!bCallbackPassed) // first time only { bCallbackPassed = TRUE; // update previous controls EndDeferWindowPos(hdwp); // start again for callback controls hdwp = BeginDeferWindowPos(count-i); } // callbacks are added at the end, so that // you don't have multiple screen updates if (!ArrangeLayoutCallback(layout)) // request data continue; } CRect rectChild, newrc; CWnd* pWnd = CWnd::FromHandle(layout.hWnd); // temporary solution pWnd->GetWindowRect(&rectChild); pParent->ScreenToClient(&rectChild); // calculate new top-left corner newrc.left = layout.sizeMarginTL.cx + rectParent.Width() * layout.sizeTypeTL.cx / 100; newrc.top = layout.sizeMarginTL.cy + rectParent.Height() * layout.sizeTypeTL.cy / 100; // calculate new bottom-right corner newrc.right = layout.sizeMarginBR.cx + rectParent.Width() * layout.sizeTypeBR.cx / 100; newrc.bottom = layout.sizeMarginBR.cy + rectParent.Height() * layout.sizeTypeBR.cy / 100; if (!newrc.EqualRect(&rectChild)) { if (layout.bAdjHScroll) { // needs repainting, due to horiz scrolling int diff = newrc.Width() - rectChild.Width(); int max = pWnd->GetScrollLimit(SB_HORZ); layout.bNeedRefresh = FALSE; if (max > 0 && pWnd->GetScrollPos(SB_HORZ) > max - diff) { layout.bNeedRefresh = TRUE; } } // set flags DWORD flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION; //if (layout.bNeedRefresh) // flags |= SWP_NOCOPYBITS; if (newrc.TopLeft() == rectChild.TopLeft()) flags |= SWP_NOMOVE; if (newrc.Size() == rectChild.Size()) flags |= SWP_NOSIZE; hdwp = DeferWindowPos(hdwp, layout.hWnd, NULL, newrc.left, newrc.top, newrc.Width(), newrc.Height(), flags); } } // go re-arrange child windows EndDeferWindowPos(hdwp); // refresh those that need for (i=0; i<count; ++i) { LayoutInfo& layout = m_arrLayout[i]; if (layout.bNeedRefresh) { ::RedrawWindow(layout.hWnd, NULL, NULL, RDW_INVALIDATE|RDW_NOFRAME); // ::InvalidateRect(layout.hWnd, NULL, TRUE); // ::UpdateWindow(layout.hWnd); } } }
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); }