nIDFirst //要重新定位並改變大小的控制條範圍中的第一個控制條的ID
nIDLast //要重新定位並改變大小的控制條範圍中的最後一個控制條的ID
nIDLeftOver //指定了填充客戶區其餘部分的ID
nFlag //佈局客戶區域的標記
lpRectParam //指向一個RECT結構,其用法依賴於nFlag的取值
lpRectClient //指向一個RECT結構,其中包含了可用的客戶區,如果爲NULL,則窗口的客戶區將被使用
bStretch //指明控制條是否被縮放到框架的大小
如果一個子窗口的id值大於等於nIDFirst並且小於等於nIDLast,在這個函數中才會給這個子窗口發送 WM_SIZEPARENT消息,這個子窗口才能參與父窗口客戶區的分配。
有一個特定的子窗口,它不響應WM_SIZEPARENT消息。只有當其它的子窗口都分配完了,它纔來撿取父窗口客戶區裏剩下的那塊。 nIDLeftOver正是這個子窗口的id。它也必須大於等於nIDFirst並且小於等於nIDLast。
nFlag是該函數的功能標誌,它可以有三個值:reposDefault,reposQuery 和reposExtra。
當nFlag等於reposDefault時,RepositionBars函數的功能是這樣的:依次給id介於nIDFirst和nIDLast之間並且不等於nIDLeftOver的子窗口發送WM_SIZEPARENT消息,每個響應這個消息的子窗口從lpRectClient所指的結構裏切去自己所佔據的部分,並且將自己的大小和位置調整到自己所佔據的區域的大小,最後RepositionBars函數還將id爲nIDLeftOver的子窗口的大小和位置調整到被其他子窗口切剩的可用區域內,使這個子窗口正好完全覆蓋最後的可用區域。這種情況下lpRectParam不用,可以爲NULL。
當nFlag等於reposQuery 時,RepositionBars函數的功能是這樣的:依次給id介於nIDFirst和nIDLast之間並且不等於nIDLeftOver的子窗口發送WM_SIZEPARENT消息,每個響應這個消息的子窗口從lpRectClient所指的結構裏切去自己所佔據的部分,但是他們並不調整自己的大小和位置,最後RepositionBars函數並不調整將id爲nIDLeftOver的子窗口的大小和位置,而是根據bStretch的值來做動作:如果bStretch爲TRUE,那麼 RepositionBars函數把最後剩下的可用區域拷貝到lpRectParam指向的RECT結構裏;如果bStretch爲FALSE,那麼RepositionBars函數把剩餘區域的大小拷貝到lpRectParam指向的RECT結構的bottom 和right成員裏,其top和left成員被置零。使用這個nFlag值來調用RepositionBars的目的不是要重排子窗口,而是要看看,假如重排子窗口的話,這些子窗口將佔去多大一塊,最後剩下的可用區域在什麼位置等等信息。
當nFlag等於reposExtra時,該函數的功能和nFlag等於reposDefault時差不多,有點小小的區別。此時需要用到lpRectParam。前面說過,當 nFlag等於reposDefault時,RepositionBars函數將在最後把id爲nIDLeftOver的子窗口的大小和位置調整到被其他子窗口切剩的可用區域內,使這個子窗口正好完全覆蓋最後的可用區域。而當nFlag等於reposExtra時,RepositionBars在調整id爲nIDLeftOver的子窗口的大小和位置前,還要用 lpRectParam來對最後剩下的可用區域做修正。假設lpRect指向的是最後的可用區域,那麼這個修正是這樣進行的:
lpRect->top+=lpRectParam->top;
lprect->left+=lpRectParam->left;
lpRect->right-=lpRectParam->right;
lpRect->bottom-=lpRectParam->bottom;
通過這樣的修正,可以使最後剩下的可用區域不被id爲nIDLeftOver的子窗口占滿,而是空出一些地方來留作他用。
AFX_IDW_PANE_FIRST MDI中的客戶區窗口ID
void CMainFrame::FullScreen()
{
GetWindowPlacement(&m_wndPlaceOld);
CRect wndRect, clientRect;
GetWindowRect(&wndRect);
RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST, reposQuery, &clientRect);
ClientToScreen(&clientRect);
DWORD dwFullWidth = GetSystemMetrics(SM_CXSCREEN);
DWORD dwFullHeight = GetSystemMetrics(SM_CYSCREEN);
m_rectFullScreen.left = wndRect.left - clientRect.left;
m_rectFullScreen.top = wndRect.top - clientRect.top;
m_rectFullScreen.right = wndRect.right - clientRect.right + dwFullWidth;
m_rectFullScreen.bottom = wndRect.bottom - clientRect.bottom + dwFullHeight;
m_bFullScreenFlag = TRUE;
WINDOWPLACEMENT wndPlace;
wndPlace.length = sizeof(WINDOWPLACEMENT);
wndPlace.flags = 0;
wndPlace.showCmd = SW_SHOWNORMAL;
wndPlace.rcNormalPosition = m_rectFullScreen;
SetWindowPlacement(&wndPlace);
}
void CMainFrame::EndFullScreen()
{
if (m_bFullScreenFlag)
{
m_bFullScreenFlag = FALSE;
SetWindowPlacement(&m_wndPlaceOld);
}
}
BOOL CMainFrame::GetScreenState()
{
return m_bFullScreenFlag;
}
當窗口發生變化時,會發送WM_GETMINMAXINFO消息
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
// TODO: Add your message handler code here and/or call default
if (m_bFullScreenFlag)
{
lpMMI->ptMaxTrackSize.x = m_rectFullScreen.Width();
lpMMI->ptMaxTrackSize.y = m_rectFullScreen.Height();
}
CMDIFrameWnd::OnGetMinMaxInfo(lpMMI);
}