1. 程式人生 > >問題解決——MFC SDI程式 CFormView中控制元件隨視窗縮放

問題解決——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,是因為我之前寫錯了位置,又不想改,就做了下小調整。
 

轉:https://blog.csdn.net/wlsgzl/article/details/34099313