设为首页 收藏本站
查看: 1666|回复: 0

[经验分享] 界面布局动态调整

[复制链接]
发表于 2015-11-24 04:09:02 | 显示全部楼层 |阅读模式
        早在2007年我就写过一篇博客叫可适配控件对话框那个时候一方面是工作需要研究了这个问题,另一方面是发现论坛里有很多人问相关的问题,于是就把自己的研究成果做了一个小例子发了上来,还写了那篇博客。
        说来惭愧,首先那时那个例子其实是我照着网上一个例子改的,而且基本框架也差不多,我简单加了些自己的东西改了改名就发出来了,唉......如今原作者以无法考正了,在此对其表示感谢吧。然后那个例子其实不是很好用,当时并没有发现什么问题,但是随着工作中使用的增多我发现了不少缺陷,也在工作中不断的改进,终于做出了一个自己用的很舒服的版本。如今三年过去了,再看CSDN界面版仍然有很多网友问及此类问题,VisualEleven力推codeproject上的easysize。easysize当初我也简单看过,不过那时我并没看懂,估计我现在也看不懂,呵呵。不过我觉得我用的这个方法也蛮好的,所以决定再写一篇博客把现在的方法介绍一下,同时整理了一个例子供大家研究。
        处理过这个问题的朋友们就应该知道,所谓的控件动态调整就是在主窗口的OnSize消息里处理一下,根据窗口的大小重新布置控件的位置。而解决这个问题的关键在于如何管理界面中的控件信息,从而可以比较方便的实现对控件的重新布局。我的处理方式是这样的,我定义了一个结构tagCONTROL,其内容如下
  
[cpp] view plaincopyprint?

  • /**
  • *  控件随窗口变化的控制单元
  • **/  
  • typedef struct tagCONTROL  
  • {  
  •     CWnd*   m_pWnd;             //指向控件的指针   
  •     CRect   m_rectWnd;          //控件所占区域  
  •     int     m_nMoveXPercent,    //控件沿x轴移动的百分比  
  •             m_nMoveYPercent,    //控件沿y轴移动的百分比  
  •             m_nZoomXPercent,    //控件沿x轴缩放的百分比  
  •             m_nZoomYPercent;    //控件沿y轴缩放的百分比  
  • }ControlInfo, *lpControlInfo;  
/***  控件随窗口变化的控制单元**/typedef struct tagCONTROL{CWnd*m_pWnd;//指向控件的指针CRectm_rectWnd;//控件所占区域intm_nMoveXPercent,//控件沿x轴移动的百分比m_nMoveYPercent,//控件沿y轴移动的百分比m_nZoomXPercent,//控件沿x轴缩放的百分比m_nZoomYPercent;//控件沿y轴缩放的百分比}ControlInfo, *lpControlInfo;  
  
  
  从这个定义中我们可以看出tagCONTROL里保存了丰富的对于控件布局的控制信息,这里m_pWnd是指向被控控件的指针,他可以是一个控件也可以是一个窗口,这样就把界面布局的控制元素全都囊括进来了。而移动、缩放的百分比控制使界面布局的控制更加灵活,更加方便。每一个需要调整布局的界面元素都会通过这个结构来保存其信息,而在界面主窗口中维护一个这种结构的列表即可在OnSize函数中方便的实现控件布局的自动调整。
        所谓界面动态调整布局实际上应该有一个参照,也就是说我们应该记录初始显示时界面的大小和此时界面中控件的位置。以后的调整都是基于这些信息的,也就是说tagCONTROL中保存的信息都是通过初始的基本数据起作用的。按着这个思路,在OnSize函数中我是这样实现的
  
[cpp] view plaincopyprint?

  • void CAutoFitDlg::OnSize(UINT nType, int cx, int cy)  
  • {  
  •     //计算窗口宽度和高度的改变量   
  •     int nIncrementX = cx - m_nWinWidth;  
  •     int nIncrementY = cy - m_nWinHeight;  
  •   
  •     INT_PTR nCount  = m_listCtrlTag.GetSize();  
  •   
  •     for (int i=0; i<nCount; i&#43;&#43;)  
  •     {  
  •         //获取变化控制系数   
  •         int nMoveXPercent   = m_listCtrlTag->m_nMoveXPercent;  
  •         int nMoveYPercent   = m_listCtrlTag->m_nMoveYPercent;  
  •         int nZoomXPercent   = m_listCtrlTag->m_nZoomXPercent;  
  •         int nZoomYPercent   = m_listCtrlTag->m_nZoomYPercent;  
  •   
  •         CWnd*   pWndCtrl;  
  •         //获取控件指针   
  •         pWndCtrl = m_listCtrlTag->m_pWnd;  
  •   
  •         if(IsWindow(pWndCtrl->GetSafeHwnd()))  
  •         {  
  •             int nLeft   = m_listCtrlTag->m_rectWnd.left;  
  •             int nTop    = m_listCtrlTag->m_rectWnd.top;  
  •             int nWidth  = m_listCtrlTag->m_rectWnd.Width();  
  •             int nHeight = m_listCtrlTag->m_rectWnd.Height();  
  •   
  •             //设置新的位置参数   
  •             nLeft   &#43;= (nIncrementX*nMoveXPercent/100);  
  •             nTop    &#43;= (nIncrementY*nMoveYPercent/100);  
  •             nWidth  &#43;= (nIncrementX*nZoomXPercent/100);  
  •             nHeight &#43;= (nIncrementY*nZoomYPercent/100);  
  •   
  •             //  把控件移动到新位置   
  •             pWndCtrl->MoveWindow(nLeft, nTop, nWidth, nHeight);  
  •         }  
  •     }  
  •   
  •     CDialog::OnSize(nType, cx, cy);  
  • }  
void CAutoFitDlg::OnSize(UINT nType, int cx, int cy){//计算窗口宽度和高度的改变量int nIncrementX = cx - m_nWinWidth;int nIncrementY = cy - m_nWinHeight;INT_PTRnCount= m_listCtrlTag.GetSize();for (int i=0; i<nCount; i++){//获取变化控制系数intnMoveXPercent= m_listCtrlTag->m_nMoveXPercent;intnMoveYPercent= m_listCtrlTag->m_nMoveYPercent;intnZoomXPercent= m_listCtrlTag->m_nZoomXPercent;intnZoomYPercent= m_listCtrlTag->m_nZoomYPercent;CWnd*pWndCtrl;//获取控件指针pWndCtrl = m_listCtrlTag->m_pWnd;if(IsWindow(pWndCtrl->GetSafeHwnd())){int nLeft= m_listCtrlTag->m_rectWnd.left;int nTop= m_listCtrlTag->m_rectWnd.top;int nWidth= m_listCtrlTag->m_rectWnd.Width();int nHeight= m_listCtrlTag->m_rectWnd.Height();//设置新的位置参数nLeft+= (nIncrementX*nMoveXPercent/100);nTop+= (nIncrementY*nMoveYPercent/100);nWidth+= (nIncrementX*nZoomXPercent/100);nHeight+= (nIncrementY*nZoomYPercent/100);//  把控件移动到新位置pWndCtrl->MoveWindow(nLeft, nTop, nWidth, nHeight);}}CDialog::OnSize(nType, cx, cy);}  
  
  
        同时,一个设计良好的界面的一般会有一个最小大小,在这个范围内安排界面布局。通常情况下我们不希望界面小于这个最小大小,这个需求可以通过重载WM_GETMINMAXINFO消息来实现
  
[cpp] view plaincopyprint?

  • void CAutoFitDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)  
  • {  
  •     //设置窗口的最小大小   
  •     lpMMI->ptMinTrackSize = m_ptMinTrackSize;  
  •   
  •     CDialog::OnGetMinMaxInfo(lpMMI);  
  • }  
void CAutoFitDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI){//设置窗口的最小大小lpMMI->ptMinTrackSize = m_ptMinTrackSize;CDialog::OnGetMinMaxInfo(lpMMI);}  
  
  
        这样一来,只要我们设计好控制信息,我们设计的界面即使被用户缩放和拖拽也可以体现出良好的布局。这个方案是我这些年来一直在项目中采用的,我不敢说它是完美的,但是却是能够满足一般的需求。如果大家在对这个方案的研究和使用中发现什么问题或是可以改进的地方还希望可以告诉我,我会加以改进再和朋友们分享。
  本文章来自于【http://blog.csdn.net/xianglitian/article/details/5667015】(未验证)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-142790-1-1.html 上篇帖子: CF E. Vanya and Brackets(添加一对括号使得表达式的值最大) 下篇帖子: inet_ntoa在64位机器上出错
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表