博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MFC控件随窗口大小变化原理及实现
阅读量:4303 次
发布时间:2019-05-27

本文共 3234 字,大约阅读时间需要 10 分钟。

本文主要针对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 sizevoid 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

你可能感兴趣的文章
Lambda 表达式
查看>>
函数式数据处理(一)--流
查看>>
java 流使用
查看>>
java 用流收集数据
查看>>
java并行流
查看>>
CompletableFuture 组合式异步编程
查看>>
mysql查询某一个字段是否包含中文字符
查看>>
Java中equals和==的区别
查看>>
JVM内存管理及GC机制
查看>>
Java:按值传递还是按引用传递详细解说
查看>>
Java中Synchronized的用法
查看>>
阻塞队列
查看>>
linux的基础知识
查看>>
接口技术原理
查看>>
五大串口的基本原理
查看>>
PCB设计技巧与注意事项
查看>>
linux进程之间通讯常用信号
查看>>
main函数带参数
查看>>
PCB布线技巧
查看>>
关于PCB设计中过孔能否打在焊盘上的两种观点
查看>>