当前位置: 代码迷 >> VC/MFC >> 怎么实现MFC窗口的最大化以及控件随最大化发生位置变动原因
  详细解决方案

怎么实现MFC窗口的最大化以及控件随最大化发生位置变动原因

热度:511   发布时间:2016-05-02 03:32:18.0
如何实现MFC窗口的最大化以及控件随最大化发生位置变动原因
最近做了一个MFC的程序,需求方让实现最大化,于是我在网上找了一大堆资料,对于我这一个初学者来说,发现要么就是没有代码只有文字,要么就是只有文字没有代码,要么就是说的不清楚。因此自己整理并总结了一下网上的资料形成了本文,非常适合初学者。其中的代码都是从网上拷贝的,所以请不要追究我的剽窃罪,毕竟好东西共享吗!!!!^_^
好了,长话短说,进入正题。
一、创建一个MFC类,输入名称,我这里输入的是ManMinText点击“确定”,然后选择想要的MFC应用类型,我这里选择的是基于对话框点击“完成”
二、删除“确定”“取消”和静态文本框,然后拖入一些自己需要的控件,我这里拖了CheckBox,Edit  Control,Group Box和Button控件,其中Group Box为啥拖俩,请听后面分解。编译运行一下这时候你会发现右上角根本没有最大化最小化按钮,,别急,右击窗口的空白处(不要在我们拖的控件出右击),将Maximize Box和Minimize Box修改为TRUE就出来了,这时候你可以在编译运行下。
三、好,现在到了关键的添加代码的时候了,看官可要仔细了。
        右击窗口的空白处(不要在我们拖的控件出右击),选择类向导,英文版本的按Ctrl+shift+X快捷键就出来了(因为QQ截图不能截,就不放图了)点击“消息”选项卡,找到WM_SIZE并选中,然后单击右侧“添加处理程序”,这时候“添加处理程序”按钮会变暗,“编辑代码”按钮会凸显,这时候点击“编辑代码”按钮,进入代码进行编辑代码
四、点击编辑界面左侧“类视图”选项卡,双击CManMinTextDlg,进入CManMinTextDlg类,加入如下代码

POINT Old;
void resize();

具体添加处看图O(∩_∩)O哈哈~

五、点击编辑界面左侧“类视图”选项卡,双击OnInitDialog(),进入OnInitDialog()函数,在此函数下端添加如下代码
CRect rect;    
GetClientRect(&rect);     //取客户区大小  
Old.x=rect.right-rect.left;
Old.y=rect.bottom-rect.top;
具体不懂的还是看图^_^

好,下面就是具体的WM_SIZE响应函数实现了
六、进入第三步时添加的响应函数CManMinTextDlg::OnSize(UINT nType, int cx, int cy)内部(如果你工程名字和我起的不一样,CManMinTextDlg就应该不是一样的,不要那么死板哦^_^),添加如下代码

       if(nType==SIZE_RESTORED||nType==SIZE_MAXIMIZED)
{
resize();
}
具体添加位置不多说,直接上图
好,如果这时候你编译的时候你会通不过的,因为你类里面的resize函数没有实现,好,在OnSize()函数下面添加如下代码进行实现

void CManMinTextDlg::resize()
{
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;

}
(其实并不一定就是这个函数下面,只要在这个文件里就可以了)

由于屏幕小,不能截全屏,凑合着吧。好,编译(F7)运行(F5),点击窗口最大化,这时候你会发现按钮按照比例变化了,但是Group Box位置却变化了
这是为啥呢?
七、窗口控件随最大化发生位置变动原因
大家可以分别右击两个Group控件,点击属性,看一下ID,知道原因了吧,它们的ID都是一样的,都叫IDC_STATIC。程序有唯一性这个特性,当两个控件叫相同的名字的时候,程序就不会分辨出来谁是谁了,所以把控件名字改掉,一个叫IDC_STATIC1,一个叫IDC_STATIC2,在编译运行下看看

金星看了之后说“完美”^_^
------解决思路----------------------
最好使用
HDWP hdwp = BeginDeferWindowPos(2);
// First, "Please Input :"
DeferWindowPos(hdwp, m_Dlg1Sta1, NULL,
(cx-rcs.Width()-rce.Width())/2,(cy-rcs.Height())/2-20, 
rcs.Width(), rcs.Height(),
SWP_NOZORDER);
// Next, Cedit.
DeferWindowPos(hdwp,m_Dlg1Edit1, NULL,
(cx-rcs.Width()-rce.Width())/2+rcs.Width()+2,(cy-rce.Height())/2-20,
rce.Width(), rce.Height(),
SWP_NOZORDER);
// redraw all the windows
EndDeferWindowPos(hdwp);

------解决思路----------------------
程序启动时enum一下所有的窗口,存储成double位置,对于combobox之类的做特殊处理即可

自动缩放看起来很好,实际用起来效果不好,实际需要不是等比例缩放,一般还是在onsize里用代码控制。

http://download.csdn.net/detail/jennyvenus/1683779

这个示例有很多不足,后来改进过,不过也不实用。
  相关解决方案