MFC窗体的控件的自适应缩放早期VS开发环境是不支持的,后来VS开发环境提供了支持但也简单,或者固定的缩放比例不符合要求。我一向坚持一个理念:“不支持缩放的窗口不是好窗口”,所以需要有一个自定义的缩放处理。机制不复杂,就是重载OnSize处理窗口大小变化。
这是对话框的OnSize,MFC会自动生成这个函数的框架:
- void CMyDlg::OnSize(UINT nType, int cx, int cy)
- {
- CDialog::OnSize(nType, cx, cy);
-
- // TODO: Add your message handler code here
- switch(nType)
- {
- case SIZE_MAXIMIZED:
- break;
- case SIZE_RESTORED:
- break;
- case SIZE_MINIMIZED:
- ShowWindow(SW_HIDE);
- break;
- default:
- return;
- }
-
- MoveCtrl(cx,cy);//这个函数是自己写的,重新设定控件位置
- }
MoveCtrl是自己定义的函数,在里面重新计算布局,设置空间位置即可。之所以要写成个函数,是因为这个函数在OnInitDialog里也需要执行一次,以便完成初始布局,这样设计对话框的时候就不用那么精确了,控件随便摆一下就行了。
OnInitDialog的处理:
- RECT rect;
-
- //初始化控件
- GetClientRect(&rect);
- MoveCtrl(rect.right, rect.bottom);
因为子控件都是基于父窗口的客户区的,所以用对话框的客户区的大小为基准来设置子控件。
这是MoveCtrl的一个示例:
- int CProxyDlg::MoveCtrl(int cx, int cy)
- {
- RECT rect;
-
- //工具栏,顶
- if(IsWindow(m_MainToolBar))
- {
- m_MainToolBar.MoveWindow(0,0,cx,toolbarhigh);
- }
- //系统,中,左
- if(IsWindow(m_Tab_Sys.m_hWnd) && IsWindow(m_Tree_Sys.m_hWnd) && IsWindow(m_Tree_User.m_hWnd))
- {
- rect.left=bdry;
- rect.right=bdry+tabsyswide;
- rect.top=toolbarhigh;
- rect.bottom=cy-statehigh;
- m_Tab_Sys.MoveWindow(&rect);
-
- m_Tab_Sys.GetWindowRect(&rect);
- m_Tab_Sys.SendMessage(TCM_ADJUSTRECT,(WPARAM)FALSE,(LPARAM)&rect);
- ScreenToClient(&rect);
- m_Tree_Sys.MoveWindow(&rect);
- m_Tree_User.MoveWindow(&rect);
- }
- //当前连接,中,右
- if(IsWindow(m_Tree.m_hWnd))
- {
- rect.left=bdry+tabsyswide+sepwide;
- rect.right=cx-bdry;
- rect.top=toolbarhigh;
- rect.bottom=cy-statehigh;
- m_Tree.MoveWindow(&rect);
- }
- //状态栏,底
- if(IsWindow(m_Static_State.m_hWnd))
- {
- rect.left=0;
- rect.right=cx;
- rect.top=cy-statehigh;
- rect.bottom=cy;
- m_Static_State.MoveWindow(&rect);
- }
-
- return 1;
- }
主要用到IsWindow来判断控件是否已经创建、MoveWindow来移动控件,其余就是各种布局计算。
有兴趣可以自己写一套布局类,不过真正理想的界面除了自适应缩放,还应该能拉伸调整,这就困难些了,别的高级语言或类库,直接提供了split面板,不用自己写。
(这里是结束)