2008年5月23日 星期五

在MFC裡讓元件隨著視窗改變大小

使用視窗的時候, 我們常常會去改變視窗的大小. 而應用程式在視窗改變大小的同時, 也會把顯示在視窗的元件隨著視窗而改變. 在wxWidget裡面, 我們可以把元件加入Sizer來達到這樣的效果. 可是在MFC中就沒這樣的預設元件可以使用, 我們必須在視窗改變大小的時候(WM_SIZE)去自行重繪.

下面介紹如何簡單的讓一個List Control不論視窗如何改變都能和視窗保持伊個邊界的方法.

  1. 在你主要視窗的Class裡面加入一個WM_SIZE觸發時可以執行的function OnSize (名稱可以自訂, 但是這樣的名子比較具有可讀性)
  2. 在視窗改變大小時就會去呼叫OnSize, 這時候會先取得視窗目前的大小 (GetClientRect)
  3. 取得要變更大小的元件 (GetDlgItem), 並且檢查是否取得成功
  4. 計算新位置
  5. 移動視窗到新位置並且重繪 (MoveWindow, RedrawWindow)

void CServerMonitorView::OnSize(UINT nType, int cx, int cy)
{

CFormView::OnSize(nType, cx, cy);

int TopLeft_x = 10;
int TopLeft_y = 25;
// Declare a CRect to get the co-ordinates
CRect l_formRect;

GetClientRect(&l_formRect);

// get pointer to the control to be resized dynamically
CListCtrl* pListCtrl;
pListCtrl = (CListCtrl *)GetDlgItem(IDC_LIST1);
if(!pListCtrl)
return ;

//Calculate the Width and TopLeft position of the control to be resized
long newX = l_formRect.TopLeft().x + TopLeft_x;
long newY = l_formRect.TopLeft().y + TopLeft_y;
long newWidth = l_formRect.Width() - 10 - TopLeft_x;
long newHeight = l_formRect.Height() - 10 - TopLeft_y;

// Now resize the control dynamically by calling MoveWindow
pListCtrl->MoveWindow((long)newX, (long)newY, (long)newWidth, (long)newHeight, TRUE);

// repaint control
pListCtrl->RedrawWindow();
}

TopLeft_x和TopLeft_y是設定List Control元件的top left位置.
這只是簡單的Resize設定, 在有多個元件的時候重新設定位置會比較複雜. 不過好處是你可以決定要怎麼改變你的元件, 比較有彈性 (麻煩?).

參考資料 :
http://www.codersource.net/mfc_resize_controls.html

沒有留言: