请教一个关于NcPaint的问题。

会思考的草 2004-06-22 11:36:31
自己继承的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运行后居然无法进入该函数。
...全文
469 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
豆腐 2004-07-02
  • 打赏
  • 举报
回复
关注
------------------------------------
体验速度,体验CSDN新版论坛助手:http://community.csdn.net/Expert/TopicView.asp?id=3108679
会思考的草 2004-07-02
  • 打赏
  • 举报
回复
??
roger_ding 2004-07-02
  • 打赏
  • 举报
回复
“四个边框不能重绘”是因为WM_LBUTTONDOWN里不能处理太多,否则也会影响速度,因为视觉效果最直接的就是caption,所以是直接画,其他不重要的四个边框倒是统一由WM_NCPAINT来画的!
roger_ding 2004-07-02
  • 打赏
  • 举报
回复
下面是我自己的理解,不代表是正确的!
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消息里绘制文本,即体现一种效率
xzqchat 2004-07-02
  • 打赏
  • 举报
回复
这个问题我也迷糊着呢。。。。
GZ..
CsdnRob 2004-07-02
  • 打赏
  • 举报
回复
应该说底下的那一堆绘画的动作是针对win3.1的,画出来都是平面的……
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
anybody here?
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
不明白的地方有三:
其一,既然NcPaint是绘制NC,那么为什么注释掉该函数后,四个边框不能重绘,单单caption bar依然可以正确绘制,这是谁在绘制?
其二,为什么在NcPaint中下断点,无法跟进?如果该函数根本没有被调用,那么注释掉它就应该是可以的,为何注释掉之后,四个边框又不能正确绘制了?
其三,MiniFrame右上角的关闭按钮,到底是谁在绘制?
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
应该说底下的那一堆绘画的动作是针对win3.1的,画出来都是平面的……
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
唔……找到症结了,MFC在Default里头包办了NcPaint的动作,给处的绘制代码都是骗人的……
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
我这边是这样定义的:
#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自己的源码里面,下面的那一大串绘画动作,都是无效的。
现在我根本找不到这个关闭按钮是在哪个函数里头画的。
zhangcrony 2004-06-22
  • 打赏
  • 举报
回复
事实上,你只要保证窗体有WS_EX_PALETTEWINDOW风格就行了,因为WS_EX_PALETTEWINDOW实际上就是WS_EX_WINDOWEDGE, WS_EX_SMCAPTION, WS_EX_TOPMOST 这三种风格的组合.
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
今天人好少阿……
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
跟踪了一下,发现令我不解的是,原来OnNcPaint每次都调用Default(),而不往下进行画的动作,原因是afxData.bSmCaption为TRUE,MFC的解释是:afxData.bSmCaption:TRUE if WS_EX_SMCAPTION is supported。查了半天也没有关于这个风格的解释,不知道这是什么风格?
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
MFC的CMiniFrameWnd类在OnNcActive里头并没有调用父类的消息处理函数,它仅仅是发送了一次WM_NCPAINT消息。这是它的源代码:
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;
}
zhangcrony 2004-06-22
  • 打赏
  • 举报
回复
"在标题栏上添加自己的按钮"?这句是什么意思啊?
注释掉OnNcPaint的动作之前,你已经在OnNcPaint里和OnNcActive里注释掉对父类的调用吗?
你的主框架窗体创建时的参数如何?这里面有文章.注意窗口类是存在于C++类之外的类.窗口类的作用就像一个模板,可以由此创建其他窗口,并可共享某些特征,包括"类风格".选择不同的.有否关闭按钮,是可以由"类风格"决定的--按程序员的理解,实际就是那一堆参数!关闭按钮的绘制,自然是框架窗体的任务.
会思考的草 2004-06-22
  • 打赏
  • 举报
回复
够ft……
Kudeet 2004-06-22
  • 打赏
  • 举报
回复
mark

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧