用的VC2010进行代码编译。
先聊下对话框
1、对话框里面一大堆命令WM_SIZE,WM_MOVE,WM_CTLCOLOR.....让人眼花缭乱
我设置断点看了一下这些函数,虚拟函数的顺序,大概是这样的
PreSubClassWindow -> Onsize ->OnMove-> PreInitDialog -> OnInit Dialog->OnMove
->OnEraseBkgnd->OnPaint->OnEraseBkgnd(然后连续出了好几次,应该是在画控件背景)
有一些消息没列全,大概是这样。移动对话框的时候,先是到OnMove,然后OnEraseBkgnd,如果对话框被拖拽到屏幕边缘,有部分被遮挡(然后从遮挡位置拉出),才会再次调用OnPaint。平时都是定期调用OnEraseBkgnd。所以,OnEraseBkgnd很关键。
2、对话框里面,控件背景,颜色,文字颜色的设置
大部分的控件(除了Button),颜色和背景可以再WM_CtlColor里面写,返回自己定义的画刷就行。
但是Button好像必须跟一个CButton类(或者其继承类)关联上,用DrawItem()(或者类似的函数)画才行,记得调用Invalidate()才能把Button的修改内容显示。真变态!!!!
3、有些对话框或者控件的属性既可以在代码里面写,又可以在资源里面手动设置,本意是让人用着方便,但是让新手很不爽啊。比如Dialog的Style,可以选Child/popup/Overlapped。在孙鑫的VC++详解,侯老师的深入浅出MFC里面,创建的过程都是能看见。但是现在都被封装起来了。要修改的话,还得在WM_CREATE里面慢慢跟踪。所以索性不管了,直接手动去资源属性里面改好了。
4、OnPaint和OnEraseBackGnd
可以把图片背景什么的都放在OnEraseBackGnd里面。虽然两个都可以,但是用法上稍微有点差别。OnPaint是没有参数的,OnEraseBackGnd里面就带参数。如果要把背景设置为Bitmap图。可以这样写:
在EraseBackGnd里面//如果是在OnPaint里面,写法有细微差别,需要自己写CPaintDC dc(this);然后把下面的pDC替换成&dc,最后一个pDC->改成dc.
//下面的函数是看别人写,然后自己理解了一下
CImage image;//要在stdafx.h里面加上atlimage.h
HRESULT ret = image.load(_T(" res/****.png"));
HBITMAP hbitmap = image.Detach();//image分离出来。至于为什么?资源load一次就可以了
//如果是BITMAP图,就更简单啦
把下面第三行换成bmpbackgnd.LoadBitmap(IDB_BITMAP1);//写你自己的资源号,其余的都一样
CBitmap bmpbackgnd;
BITMAP bitmap;
bmpbackgnd.Attach(hbitmap);//和CBITMAP关联起来
bmpbackgnd.GetBitmap(&bitmap);//把png图像给bitmap
CDC memdc;//创建一个想适应的环境设备
memdc.CreateCompatibleDC(pDC);
CBitmap *pOldbitmap = memdc.SelectObject(hbitmap);//这里写memdc.SelectObject(&bmpbackgnd)也可以,一样的效果
pDC->Stretchblt(0,0,rect.width(),rect.Height(),&memdc, 0, 0, bitmap.bmwidth, bitmap.bmheight, SRCCOPPY);
//本来这里有CDialog::OnEraseBacknd,要注释掉,不然效果无效;
return true;//其实这里最好判断下画成功没有,本人懒,就不写了