OnCreate和PreSubclassWindow摘录

1.在对话框模板中添加控件和动态创建控件对PreSubclassWindow和OnCreate调用的不同

通过在对话框模板添加控件不会调用控件的OnCreate函数,程序生成对话框最终是调用windows api的CreateDialog或者DialogBox去创建的,这样在对话框创建的时刻,所有控件都是标准的windows控件,所以那时候的消息WM_CREATE也只会触发默认的窗口回调函数,而不会调用到子类的OnCreate。然后要怎么把这个控件替换成自定义的控件,其实只要SetWindowLong改变一下窗口回调函数就行了,做这个动作的函数就是SubClassWindow,它会在对话框初始化完全完成前被MFC代码自动调用,而此函数会调用PreSubClassWindow来让编写者完成一些初始化动作来代替那一去不复返的WM_CREATE消息。如果自己主动调用Create函数的,那么这个窗口的回调函数在创建之初就会被MFC的WH_CBT钩子替换成子类的回调函数,这样WM_CREATE消息就可以触发子类的OnCreate并完成初始化.

两种添加控件的方式都会调用控件的PreSubclassWindow函数,但两者意义不同。对于使用模板,MFC是调用了父类的Create函数,创建了窗口句柄,然后把这个窗口句柄Attach给子类,所以只会调用PreSubclassWnd(),而不会响应子类的OnCreate函数。而对于动态创建,虽然也会调用PreSubclassWnd(),但此时尚未Create,PreSubClassWindow应该是在控件的窗口创建前调用的,一直到Create之后窗口句柄才被创建,如果在该函数中使用了窗口句柄,肯定会抛出异常。同时注意子窗口应该在父窗口创建之后才能创建。

 

2.使用Create方式创建控件的时候,不可以在PresubClassWindow中嵌套 Create或者是CreateEx,原因是MFC调用Create或者是Ex的时候,创建控件,创建完之后,会又_AfxCbtFilterHook钩子函数处理善后部分,比如在函数返回前会将线程状态中的 m_pWndInit 清空;假若在PresubClassWindow中嵌套Create或者是Ex的话,在AfxCbtFilterHook尚未返回前,又调用了AfxCbtFilterHook一次,并且m_pWndInit值不变,故导致Attach两次异常。这种情况下控件内若有其他嵌套控件需要调用create初始化应放在OnCreate处。

DrawItem函数说明:

DrawItem函数的调用要求控件的属性是" Owner Draw", 我们当然可以在资源对话框的属性里面设置空件为"OwnerDraw"属性,但更好的方法是在PreSubclassWindow()中进行。 注意:不要和PreCreateWindow()函数混了,后者中执行ModifyStyle()函数不起效果。
当CWnd::Create()或DDX_Control被调用后,这两个函数都会调用SubClassWindow(), SubClassWindow()紧接着会调用PreSubclassWindow(),我们可以在该函数内设置控件的属性为"OwnerDraw"

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值