最近做了一个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
这个示例有很多不足,后来改进过,不过也不实用。