#48 CZoomScrollImpl: zoom child windows

closed-fixed
None
5
2014-03-21
2005-10-15
No

// I guess it could be useful

void Zoom(float fZoomScale, bool bCenter = true)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));

if(fZoomScale <= 0)
return;

fZoomScale = max(fZoomScale,
m_fZoomScaleMin);

float fZoomCurrentScaleDelta = fZoomScale /
m_fZoomScale;

POINT pt = { 0 };
if(bCenter)
{
RECT rc;
::GetClientRect(pT->m_hWnd, &rc);
pt.x = rc.right / 2;
pt.y = rc.bottom / 2;
ViewDPtoLP(&pt);
}

// Modify the Viewport extent
m_fZoomScale = fZoomScale;
SIZE sizeAll = { 0 };
sizeAll.cx = (int)((float)m_sizeLogAll.cx *
fZoomScale);
sizeAll.cy = (int)((float)m_sizeLogAll.cy *
fZoomScale);

// Update scroll bars and window
CScrollImpl< T >::SetScrollSize(sizeAll);

// Zoom all children if needed
if(IsScrollingChildren() && 1.0f !=
fZoomCurrentScaleDelta)
{
for(HWND hWndChild = ::GetWindow(pT-
>m_hWnd, GW_CHILD); hWndChild != NULL;
hWndChild = ::GetWindow(hWndChild,
GW_HWNDNEXT))
{
CRect rect;
::GetWindowRect(hWndChild, &rect);
::MapWindowPoints(NULL, pT-
>m_hWnd, (LPPOINT)&rect, 2);
::SetWindowPos(hWndChild, NULL,
(int)(((float)rect.left + 0.5f) *
fZoomCurrentScaleDelta),
(int)(((float)rect.top + 0.5f) *
fZoomCurrentScaleDelta),
(int)(((float)rect.Width() + 0.5f) *
fZoomCurrentScaleDelta),
(int)(((float)rect.Height() + 0.5f) *
fZoomCurrentScaleDelta),
SWP_NOZORDER |
SWP_NOACTIVATE);
}
}

if(bCenter)
CenterOnLogicalPoint(pt);
}

Discussion

  • Done, with some changes. If you zoom in or out a lot, rounding errors between float and int will moze/size child windows incorrectly. So, I added code to save initial position and size of child windows, so that we can use them to scale.

    Commit #544, atlscrl.h

     


Anonymous


Cancel   Add attachments