////////////////// // Set each control's tofit (desired) size to current size. Useful for // dialogs, to "remember" the current sizes as desired size. // void CWinMgr::InitToFitSizeFromCurrent(CWnd* pWnd) { ASSERT(pWnd); ASSERT(m_map); GetWindowPositions(pWnd); for (WINRECT* w = m_map; !w->IsEnd(); w++) { if (w->Type()==WRCT_TOFIT && !w->IsGroup()) { w->SetToFitSize(w->GetRect().Size()); } } }
////////////////// // Set each control's tofit (desired) size to current size. Useful for // dialogs, to "remember" the current sizes as desired size. // void CWinMgr::InitToFitSizeFromCurrent(HWND hWnd) { assert(hWnd); assert(m_map); GetWindowPositions(hWnd); for (WINRECT* w = m_map; !w->IsEnd(); ++w) { if (w->Type()==WRCT_TOFIT && !w->IsGroup()) { w->SetToFitSize(RectToSize(w->GetRect())); } } }
////////////////// // Calculate size/positions for a row or column group This is the main // algorithm. If a window is given, it's used to get the min/max size and // desired size for TOFIT types. // void CWinMgr::CalcGroup(WINRECT* pGroup, CWnd* pWnd) { // If this bombs, most likely the first entry in your map is not a group! ASSERT(pGroup && pGroup->IsGroup()); ASSERT(pWnd); // adjust total avail by margins CRect rcTotal = pGroup->GetRect(); int w,h; if (pGroup->GetMargins(w,h)) { w = min(abs(w), rcTotal.Width()/2); h = min(abs(h), rcTotal.Height()/2); rcTotal.DeflateRect(w,h); } BOOL bRow = pGroup->IsRowGroup(); // Is this a row group? // Running height or width: start with total int hwRemaining = bRow ? rcTotal.Height() : rcTotal.Width(); // First, set all rects to their minimum sizes. // This ensures that each rect gets its min size. CWinGroupIterator it; for (it=pGroup; it; it.Next()) { WINRECT* wrc = it; SIZEINFO szi; OnGetSizeInfo(szi, wrc, pWnd); int hwMin = bRow ? szi.szMin.cy : szi.szMin.cx; hwMin = min(hwMin, hwRemaining); // truncate wrc->SetHeightOrWidth(hwMin, bRow); // set hwRemaining -= hwMin; // decrement remaining height/width ASSERT(hwRemaining>=0); } // Now adjust all rects upward to desired size. Save REST rect for last. WINRECT* pRestRect = NULL; for (it=pGroup; it; it.Next()) { WINRECT* wrc = it; if (wrc->Type()==WRCT_REST) { ASSERT(pRestRect==NULL); // can only be one REST rect! pRestRect = wrc; // remember it } else { AdjustSize(wrc, bRow, hwRemaining, pWnd); } } ASSERT(hwRemaining>=0); // Adjust REST rect if any if (pRestRect) { AdjustSize(pRestRect, bRow, hwRemaining, pWnd); ASSERT(hwRemaining==0); } // All the sizes of the entries have been calculated, including // groups (but not their children). Now move all the rects so they're // adjacent to one another, without altering sizes. PositionRects(pGroup, rcTotal, bRow); // Finally, descend recursively into each subgroup. for (it=pGroup; it; it.Next()) { WINRECT* wrc = it; if (wrc->IsGroup()) CalcGroup(wrc, pWnd); // recurse! } }