自己继承的CMiniDockFrame,现在想在标题栏上添加自己的按钮,以实现自动伸缩bar的功能。我映射了WM_NCPAINT和WM_NCACITIVE消息,但是出现几个奇怪的现象,大家给点意见:1.在OnNcPaint里和OnNcActive里注释掉对父类的调用后,整个CMiniDockFrame确实没有重绘(这是应该的)2.注释调OnNcPaint,让它成为一个空函数,但是不修改OnNcActive,运行程序后,caption bar和四边框都没有重绘,这本该是正常的,但奇怪的是,当单击一次caption bar之后,caption bar就能正确重绘了。OnNcActive仅仅是发送一个WM_NCPAINT消息通知重绘NC而已,既然我已经注释掉了OnNcPaint里所有的代码,实在想不通为什么四个边框都没有被重绘,单单caption bar可以画出来。3.在OnNcPaint里设断点,F5运行后居然无法进入该函数。
其一,既然NcPaint是绘制NC,那么为什么注释掉该函数后,四个边框不能重绘,单单caption bar依然可以正确绘制,这是谁在绘制?
其二,为什么在NcPaint中下断点,无法跟进?如果该函数根本没有被调用,那么注释掉它就应该是可以的,为何注释掉之后,四个边框又不能正确绘制了?
其三,MiniFrame右上角的关闭按钮,到底是谁在绘制?
注释掉OnNcPaint的动作之前,你已经在OnNcPaint里和OnNcActive里注释掉对父类的调用吗?
你的主框架窗体创建时的参数如何?这里面有文章.注意窗口类是存在于C++类之外的类.窗口类的作用就像一个模板,可以由此创建其他窗口,并可共享某些特征,包括"类风格".选择不同的.有否关闭按钮,是可以由"类风格"决定的--按程序员的理解,实际就是那一堆参数!关闭按钮的绘制,自然是框架窗体的任务.
BOOL CMiniFrameWnd::OnNcActivate(BOOL bActive)
{
if((GetStyle() & MFS_SYNCACTIVE) == 0)
{
if (afxData.bSmCaption)
return Default(); if (m_bActive != bActive) //״̬¸Ä±ä(¼¤»î<=>δ¼¤»î),֪ͨÖØ»æ·Ç¿Í»§Çø
{
m_bActive = bActive;
SendMessage(WM_NCPAINT);
}
}
else if(m_nFlags & WF_KEEPMINIACTIVE)
{
return FALSE;
}
return TRUE;
}
#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_TOPMOST)我把NcPaint里头画的动作全部注释掉,居然还能画:
void CResizableMiniDockFrameWnd::OnNcPaint()
{
if(afxData.bSmCaption) //TRUE if WS_EX_SMCAPTION is supported
{
Default();
return;
}
}
没有一点异常。也就是说,MFC自己的源码里面,下面的那一大串绘画动作,都是无效的。
现在我根本找不到这个关闭按钮是在哪个函数里头画的。
------------------------------------
体验速度,体验CSDN新版论坛助手:http://community.csdn.net/Expert/TopicView.asp?id=3108679
caption被重画,一种可能是在WM_NCPAINT里做这个动作,另一种便是WM_NCLBUTTONDOWN里Windows自己直接绘制,意思是
case WM_NCLBUTTONDOWN:
// draw caption
为什么要这样而不是统一由WM_NCPAINT来画呢,我猜想可能是考虑到实时性,比如有时窗口处于后台,这时用户直接点击caption,此时windows直接绘制的效果就是给用户的感觉没有延迟,否则点一下过一会才由灰色变成蓝色,会影响些视觉效果
当然不止是caption是这样,combobox也是这样,比如hook了它的windowproc,自己处理WM_PAINT,发送CB_SETCURSEL,此时会发现没有调用WM_PAINT,因为combobox是直接在CB_SETCURSEL消息里绘制文本,即体现一种效率