問題解決——MFC SDI程式 CFormView中控制元件隨視窗縮放
從來都是做對話方塊程式,這次想做個SDI的程式,想著用一下帶Robbin介面的office2007風格,就不用使用那些花錢的商業控制元件/UI庫了。
如果你不想看我打的文字,可以直接拷走程式碼,自己宣告上定義再略作修改就可以用了,不需大的修改。
-------------------------------小尾巴首次登場-----------------------------------
SDI程式,是要縮放的,如果是往裡輸入文字的話,這倒沒什麼,但是這次我使用的是CFormView類,裡面加了控制元件。
———————————我才是分割線————————————
大致上有3種方法
方法1:
1.記錄原始的CFormView的RECT,在OnSize中獲得當前Rect,求出放大比例。
2.對每個控制元件,在OnSize中獲取當前RECT,然後乘以放大比例,作為新的RECT大小。
3.對每個控制元件,呼叫MoveWindow函式,完成縮放。
這種方法對每一個控制元件,都編寫程式碼進行操作,必然是縮放效果最好的。但是,當控制元件太多時,真的需要一個好脾氣,而且要細心,善於除錯。(複製貼上,這麼做有時候會讓你編譯連結過,但是就是一直錯。)
方法2:
這是對方法1的改進。需要一定的知識和技巧。
所有控制元件的定義都是在*.rc檔案中,但是這些控制元件的ID宣告卻都在resource.h中。如果你有足夠的耐心和另外一塊顯示屏,那麼你可以:
1.更改這些控制元件的ID值,使它們順序增長(減小),這樣我們就可以在一個迴圈裡完成方法1中對控制元件的操作,只需1套程式碼。(不要害怕改壞了,對於不同的控制元件,只要在resource.h中ID值不重複就行了。)
這種方法看起來是對方法1的優化,但是實際上,對於程式碼的維護以及任務的交接都是不太好的。當控制元件較多時,手工的對ID進行記錄更改排序,你需要比方法1還好的脾氣。
-------------------你不覺得上面的分割線的風格怪怪的嗎-------------------------
方法3:
我採用了這種,主要是不想維護太多的程式碼,也不想在如此眾多的巨集中對ID值進行更改。
先上程式碼吧,無碼無真相。
void CRealTimeFV::OnSize(UINT nType, int cx, int cy)
{
CFormView::OnSize(nType, cx, cy);
// TODO: 在此處新增訊息處理程式程式碼 http://blog.csdn.net/wlsgzl/article/details/34099313
RECT rc;
GetClientRect(&rc);
LPRECT lpClientRect=&rc;
m_dXRate=lpClientRect->right/(double)m_lastRect.right;
m_dYRate=lpClientRect->bottom/(double)m_lastRect.bottom;
if (lpClientRect->right!=0 && lpClientRect->bottom!=0)
{
m_lastRect.bottom=lpClientRect->bottom;
m_lastRect.left=lpClientRect->left;
m_lastRect.right=lpClientRect->right;
m_lastRect.top=lpClientRect->top;
CWnd *pWnd=NULL;
pWnd=GetWindow(GW_CHILD);
while (pWnd)
{
CString strCaption;
pWnd->GetWindowTextW(strCaption);
OutputDebugString(TEXT("Caption:")+strCaption+TEXT("\n"));
CRect childRect;
pWnd->GetWindowRect(&childRect);
ScreenToClient(&childRect);
childRect.left=(LONG)(childRect.left*m_dXRate);
childRect.top=(LONG)(childRect.top*m_dYRate);
childRect.right=(LONG)(childRect.right*m_dXRate);
childRect.bottom=(LONG)(childRect.bottom*m_dYRate);
pWnd->MoveWindow(&childRect,TRUE);
pWnd=pWnd->GetWindow(GW_HWNDNEXT);
}
}
}
程式碼肯定有優化改進的餘地,但這不是本文的主要意圖。
(可用於按鈕、編輯框、GroupBox、ComboBox、靜態文字框、Tab頁,對其他控制元件未作嘗試。)
轉載請註明出處http://blog.csdn.net/wlsgzl/article/details/34099313。
要注意的是:
1.最好先限制下SDI程式介面的最小大小。
2.在呼叫此函式之前,先獲得一次m_lastRect。至於怎麼獲得,如何獲得,便是仁者見仁智者見智的事情了。
3.我添加了if,必然是有原因的,不相信可以自己跟訊息跟便變數。至於原因,這屬於怎樣學好MFC的問題,講不了,我也不敢說自己學好了。
4.定義了rc和lpClientRect,是因為我之前寫錯了位置,又不想改,就做了下小調整。