当框架窗口(CMainFrame)的大小改变时,视图窗口(CMyAppView)的大小也跟着变? 当框架窗口(CMainFrame)的大小改变时,视图窗口(CMyAppView)的大小也跟着变?MFC是怎样做到的? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 lz可以去看看MFC的源码,看看WM_SIZE里,框架类做了什么处理视图是附载在创建窗口之上的 阅读下面的代码,注意长注释条void CFrameWnd::OnSize(UINT nType, int cx, int cy){ CWnd::OnSize(nType, cx, cy); // important for MDI Children if (nType != SIZE_MINIMIZED) RecalcLayout();///////////////}void CFrameWnd::RecalcLayout(BOOL bNotify){ if (m_bInRecalcLayout) return; m_bInRecalcLayout = TRUE; // clear idle flags for recalc layout if called elsewhere if (m_nIdleFlags & idleNotify) bNotify = TRUE; m_nIdleFlags &= ~(idleLayout|idleNotify);#ifndef _AFX_NO_OLE_SUPPORT // call the layout hook -- OLE support uses this hook if (bNotify && m_pNotifyHook != NULL) m_pNotifyHook->OnRecalcLayout();#endif // reposition all the child windows (regardless of ID) if (GetStyle() & FWS_SNAPTOBARS) { CRect rect(0, 0, 32767, 32767); RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &rect, &rect, FALSE); RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra, &m_rectBorder, &rect, TRUE); CalcWindowRect(&rect); SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(), SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); } else RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra, &m_rectBorder);////////////// m_bInRecalcLayout = FALSE;}void CWnd::RepositionBars(UINT nIDFirst, UINT nIDLast, UINT nIDLeftOver, UINT nFlags, LPRECT lpRectParam, LPCRECT lpRectClient, BOOL bStretch){ ASSERT(nFlags == 0 || nFlags == reposQuery || nFlags == reposExtra); // walk kids in order, control bars get the resize notification // which allow them to shrink the client area // remaining size goes to the 'nIDLeftOver' pane // NOTE: nIDFirst->nIDLast are usually 0->0xffff AFX_SIZEPARENTPARAMS layout; HWND hWndLeftOver = NULL; layout.bStretch = bStretch; layout.sizeTotal.cx = layout.sizeTotal.cy = 0; if (lpRectClient != NULL) layout.rect = *lpRectClient; // starting rect comes from parameter else GetClientRect(&layout.rect); // starting rect comes from client rect if (nFlags != reposQuery) layout.hDWP = ::BeginDeferWindowPos(8); // reasonable guess else layout.hDWP = NULL; // not actually doing layout for (HWND hWndChild = ::GetTopWindow(m_hWnd); hWndChild != NULL; hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT)) { UINT nIDC = _AfxGetDlgCtrlID(hWndChild); CWnd* pWnd = CWnd::FromHandlePermanent(hWndChild); if (nIDC == nIDLeftOver) hWndLeftOver = hWndChild; else if (nIDC >= nIDFirst && nIDC <= nIDLast && pWnd != NULL) ::SendMessage(hWndChild, WM_SIZEPARENT, 0, (LPARAM)&layout); } // if just getting the available rectangle, return it now... if (nFlags == reposQuery) { ASSERT(lpRectParam != NULL); if (bStretch) ::CopyRect(lpRectParam, &layout.rect); else { lpRectParam->left = lpRectParam->top = 0; lpRectParam->right = layout.sizeTotal.cx; lpRectParam->bottom = layout.sizeTotal.cy; } return; } // the rest is the client size of the left-over pane if (nIDLeftOver != 0 && hWndLeftOver != NULL) { CWnd* pLeftOver = CWnd::FromHandle(hWndLeftOver); // allow extra space as specified by lpRectBorder if (nFlags == reposExtra) { ASSERT(lpRectParam != NULL); layout.rect.left += lpRectParam->left; layout.rect.top += lpRectParam->top; layout.rect.right -= lpRectParam->right; layout.rect.bottom -= lpRectParam->bottom; } // reposition the window pLeftOver->CalcWindowRect(&layout.rect); AfxRepositionWindow(&layout, hWndLeftOver, &layout.rect);/////////// } // move and resize all the windows at once! if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP)) TRACE0("Warning: DeferWindowPos failed - low system resources.\n");}void AFXAPI AfxRepositionWindow(AFX_SIZEPARENTPARAMS* lpLayout, HWND hWnd, LPCRECT lpRect){ ASSERT(hWnd != NULL); ASSERT(lpRect != NULL); HWND hWndParent = ::GetParent(hWnd); ASSERT(hWndParent != NULL); if (lpLayout != NULL && lpLayout->hDWP == NULL) return; // first check if the new rectangle is the same as the current CRect rectOld; ::GetWindowRect(hWnd, rectOld); ::ScreenToClient(hWndParent, &rectOld.TopLeft()); ::ScreenToClient(hWndParent, &rectOld.BottomRight()); if (::EqualRect(rectOld, lpRect)) return; // nothing to do //////////////////////////////////////////////////////////// // try to use DeferWindowPos for speed, otherwise use SetWindowPos if (lpLayout != NULL) { lpLayout->hDWP = ::DeferWindowPos(lpLayout->hDWP, hWnd, NULL, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, SWP_NOACTIVATE|SWP_NOZORDER); } else { ::SetWindowPos(hWnd, NULL, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, SWP_NOACTIVATE|SWP_NOZORDER); }} 求教,如何用代码得到Edit框是否设置只读属性? 求VC数据库方面的入门电子书 什么是DLL映射到进程的地址空间? 如何改变进度条控件的外框??? 请教一个问题,有关软件运行平台的问题! 切分视图 公布VISUAL C/C++6.0编译器的预处理器参考手册(中文)下载邮箱地址[email protected]。 请问如何卸载远程线程插入的DLL? 这个网站太可恶了,不但修改了我的注册表,还每次机器启动的时候又自动到它网站去,高手救我!!! 请问BITMAP和HBITMAP有什么区别? MFC问题 急急急!!!关于数据存储格式
{
CWnd::OnSize(nType, cx, cy); // important for MDI Children
if (nType != SIZE_MINIMIZED)
RecalcLayout();///////////////
}void CFrameWnd::RecalcLayout(BOOL bNotify)
{
if (m_bInRecalcLayout)
return; m_bInRecalcLayout = TRUE;
// clear idle flags for recalc layout if called elsewhere
if (m_nIdleFlags & idleNotify)
bNotify = TRUE;
m_nIdleFlags &= ~(idleLayout|idleNotify);#ifndef _AFX_NO_OLE_SUPPORT
// call the layout hook -- OLE support uses this hook
if (bNotify && m_pNotifyHook != NULL)
m_pNotifyHook->OnRecalcLayout();
#endif // reposition all the child windows (regardless of ID)
if (GetStyle() & FWS_SNAPTOBARS)
{
CRect rect(0, 0, 32767, 32767);
RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery,
&rect, &rect, FALSE);
RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra,
&m_rectBorder, &rect, TRUE);
CalcWindowRect(&rect);
SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
}
else
RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra, &m_rectBorder);//////////////
m_bInRecalcLayout = FALSE;
}void CWnd::RepositionBars(UINT nIDFirst, UINT nIDLast, UINT nIDLeftOver,
UINT nFlags, LPRECT lpRectParam, LPCRECT lpRectClient, BOOL bStretch)
{
ASSERT(nFlags == 0 || nFlags == reposQuery || nFlags == reposExtra); // walk kids in order, control bars get the resize notification
// which allow them to shrink the client area
// remaining size goes to the 'nIDLeftOver' pane
// NOTE: nIDFirst->nIDLast are usually 0->0xffff AFX_SIZEPARENTPARAMS layout;
HWND hWndLeftOver = NULL; layout.bStretch = bStretch;
layout.sizeTotal.cx = layout.sizeTotal.cy = 0;
if (lpRectClient != NULL)
layout.rect = *lpRectClient; // starting rect comes from parameter
else
GetClientRect(&layout.rect); // starting rect comes from client rect if (nFlags != reposQuery)
layout.hDWP = ::BeginDeferWindowPos(8); // reasonable guess
else
layout.hDWP = NULL; // not actually doing layout for (HWND hWndChild = ::GetTopWindow(m_hWnd); hWndChild != NULL;
hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
{
UINT nIDC = _AfxGetDlgCtrlID(hWndChild);
CWnd* pWnd = CWnd::FromHandlePermanent(hWndChild);
if (nIDC == nIDLeftOver)
hWndLeftOver = hWndChild;
else if (nIDC >= nIDFirst && nIDC <= nIDLast && pWnd != NULL)
::SendMessage(hWndChild, WM_SIZEPARENT, 0, (LPARAM)&layout);
} // if just getting the available rectangle, return it now...
if (nFlags == reposQuery)
{
ASSERT(lpRectParam != NULL);
if (bStretch)
::CopyRect(lpRectParam, &layout.rect);
else
{
lpRectParam->left = lpRectParam->top = 0;
lpRectParam->right = layout.sizeTotal.cx;
lpRectParam->bottom = layout.sizeTotal.cy;
}
return;
} // the rest is the client size of the left-over pane
if (nIDLeftOver != 0 && hWndLeftOver != NULL)
{
CWnd* pLeftOver = CWnd::FromHandle(hWndLeftOver);
// allow extra space as specified by lpRectBorder
if (nFlags == reposExtra)
{
ASSERT(lpRectParam != NULL);
layout.rect.left += lpRectParam->left;
layout.rect.top += lpRectParam->top;
layout.rect.right -= lpRectParam->right;
layout.rect.bottom -= lpRectParam->bottom;
}
// reposition the window
pLeftOver->CalcWindowRect(&layout.rect);
AfxRepositionWindow(&layout, hWndLeftOver, &layout.rect);///////////
} // move and resize all the windows at once!
if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP))
TRACE0("Warning: DeferWindowPos failed - low system resources.\n");
}void AFXAPI AfxRepositionWindow(AFX_SIZEPARENTPARAMS* lpLayout,
HWND hWnd, LPCRECT lpRect)
{
ASSERT(hWnd != NULL);
ASSERT(lpRect != NULL);
HWND hWndParent = ::GetParent(hWnd);
ASSERT(hWndParent != NULL); if (lpLayout != NULL && lpLayout->hDWP == NULL)
return; // first check if the new rectangle is the same as the current
CRect rectOld;
::GetWindowRect(hWnd, rectOld);
::ScreenToClient(hWndParent, &rectOld.TopLeft());
::ScreenToClient(hWndParent, &rectOld.BottomRight());
if (::EqualRect(rectOld, lpRect))
return; // nothing to do ////////////////////////////////////////////////////////////
// try to use DeferWindowPos for speed, otherwise use SetWindowPos
if (lpLayout != NULL)
{
lpLayout->hDWP = ::DeferWindowPos(lpLayout->hDWP, hWnd, NULL,
lpRect->left, lpRect->top, lpRect->right - lpRect->left,
lpRect->bottom - lpRect->top, SWP_NOACTIVATE|SWP_NOZORDER);
}
else
{
::SetWindowPos(hWnd, NULL, lpRect->left, lpRect->top,
lpRect->right - lpRect->left, lpRect->bottom - lpRect->top,
SWP_NOACTIVATE|SWP_NOZORDER);
}
}