本文主要針對MFC的dialog,實現控件隨窗口大小變化。
原理:首先獲取dialog的初始大小,當窗口發送變動時,調用OnSize事件和方法,計算縮放比例,然后對界面中的所有控件進行縮放和布局。
實現:
創建一個CMFCDemoDlg的dialog對話框;
// CMFCDemoDlg 對話框 class CMFCDemoDlg : public CDialogEx { // 構造 public: CMFCDemoDlg(CWnd* pParent = NULL); // 標准構造函數 // 對話框數據 enum { IDD = IDD_MFCDEMO_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 protected: CRect m_rect; void ChangeSize(UINT nID,int x,int y); void ReSize(void); POINT old; protected: // 生成的消息映射函數 virtual BOOL OnInitDialog(); afx_msg void OnSize(UINT nType, int cx, int cy); DECLARE_MESSAGE_MAP() };
在OnInitDialog方法中獲取dialog的初始大小,記錄到old變量中;
注冊OnSize事件處理方法(ON_WM_SIZE(), OnSize()函數),設置控件大小
CMFCDemoDlg::CMFCDemoDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CMFCDemoDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CMFCDemoDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CMFCDemoDlg, CDialogEx) ON_WM_SIZE() END_MESSAGE_MAP() // CMFCDemoDlg 消息處理程序 BOOL CMFCDemoDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 獲取對話框初始大小 GetClientRect(&m_rect); //獲取對話框的大小 old.x=m_rect.right-m_rect.left; old.y=m_rect.bottom-m_rect.top; return TRUE; } void CMFCDemoDlg::ReSize(void) { float fsp[2]; POINT Newp; //獲取現在對話框的大小 CRect recta; GetClientRect(&recta); //取客戶區大小 Newp.x=recta.right-recta.left; Newp.y=recta.bottom-recta.top; fsp[0]=(float)Newp.x/old.x; fsp[1]=(float)Newp.y/old.y; CRect Rect; int woc; CPoint OldTLPoint,TLPoint; //左上角 CPoint OldBRPoint,BRPoint; //右下角 HWND hwndChild=::GetWindow(m_hWnd,GW_CHILD); //列出所有控件 while(hwndChild){ woc=::GetDlgCtrlID(hwndChild);//取得ID GetDlgItem(woc)->GetWindowRect(Rect); ScreenToClient(Rect); OldTLPoint = Rect.TopLeft(); TLPoint.x = long(OldTLPoint.x*fsp[0]); TLPoint.y = long(OldTLPoint.y*fsp[1]); OldBRPoint = Rect.BottomRight(); BRPoint.x = long(OldBRPoint.x *fsp[0]); BRPoint.y = long(OldBRPoint.y *fsp[1]); Rect.SetRect(TLPoint,BRPoint); GetDlgItem(woc)->MoveWindow(Rect,TRUE); hwndChild=::GetWindow(hwndChild, GW_HWNDNEXT); } old=Newp; } void CMFCDemoDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType,cx,cy); if(nType!=SIZE_MINIMIZED ) //判斷窗口是不是最小化了,因為窗口最小化之后 ,窗口的長和寬會變成0,當前一次變化的時就會出現除以0的錯誤操作 { ReSize(); } }
通過hwndChild=::GetWindow(m_hWnd,GW_CHILD);和::GetWindow(hwndChild, GW_HWNDNEXT); 列出所有控件
也可針對特定控件設置其大小,如:
//change control size void CMFCDemoDlg::ChangeSize(UINT nID,int x,int y) { CWnd *pWnd = GetDlgItem(nID); if(pWnd!=NULL) { CRect rec; pWnd->GetWindowRect(&rec);//獲取控件變化前的大小 ScreenToClient(rec); //將控件大小裝換位在對話框中的區域坐標 // x / m_rect.Width(); 伸縮rate rec.left = rec.left * x / m_rect.Width(); rec.top = rec.top * y / m_rect.Height(); rec.bottom = rec.bottom * y / m_rect.Height(); rec.right = rec.right * x / m_rect.Width(); pWnd->MoveWindow(rec);//伸縮控件 } }
參考:http://blog.csdn.net/lujianfeiccie2009/article/details/5485602