PreSubclassWindow的作用

   要了解PreSubclassWindow的作用,首先应了解什么是“子类化控件”。“子类化控件”或称“接管控件”,它是将对话框上子窗口(控件)的消息处理函数(窗口过程函数)替换成对应的C++对象的消息处理函数的动作。

   举个例子了来阐明一下:例如你需要一个只接受数字输入的文本编辑框,如果使用对话框资源工具箱上的Edit控件,当用户输入数字以外的字符时,你既不知道也无计可施。也就是说,当用户在编辑框中输入字符串 "zbc*" 时,如果除了拒绝接受整个字符串以外几乎什么也不能做,这显得特别不专业。重要的是,你应该具有输入检测的能力,即每当用户输入一个字符到编辑框中时要能检测这个字符。

   现在来说明实现细节:当用户往编辑框中输入字符时,Windows 会给Edit控件的窗口过程函数发送 WM_CHAR 消息。这个窗口过程本身寄生于 Windows 中,因此不能直接修改它。但是我们可以重定向这个消息使之发送到我们自己编写的窗口处理函数。如果自定义窗口处理程序需要处理这个消息那就处理它,如果不需处理就可以把这个消息转发到它原来窗口过程函数。通过这种方式,自定义的窗口处理函数就把它自己插入到 Windows 系统和 Edit 控件之间。

  看下面的流程:
   窗口子类化之前:Windows ==>Edit 控件的窗口处理函数。
   窗口子类化之后:Windows ==>自定义的窗口处理函数==> Edit 控件的窗口处理函数。
   注意子类化并不局限于控件,可以子类化任何窗口,现在我们要把精力集中到怎样实现子类化一个窗口上。让我们想想Windows 怎样知道 Edit 控件的窗口处理函数放在什么地方。原来 WNDCLASSEX 结构的成员 lpfnWndProc 指出了窗口函数地址。如果能用自己编写的窗口函数的地址来替换这个成员变量,那 Windows 不就把消息发到自定义的窗口函数了。我们可以通过调用函数SetWindowLong 来实现这个任务。
   SetWindowLong如果调用成功那么返回值是先前为窗口指定的32位值,在这里是原先窗口函数的地址。我们要保存这个值以便以后使用。 例如:一些我们不关心的消息,需要把它们派遣给原来的窗口函数来处理,这就用到另外一个函数 CallWindowProc() ,CallWindowProc()将消息传送给指定的窗口过程,所以将原先窗口函数的地址传给CallWindowProc的第一个参数,剩下的四个参数就是发给自定义函数的参数,直接把它们传给函数 CallWindowProc 就行了。

    窗口的子类化过程通过调用CWnd::SubclassWindow()这个函数来实现。MFC提供了一个虚函数CWnd::PreSubclassWindow(), 供用户在子类化控件之前执行其它自定义的子类化动作 。
    如果你定义了一个子窗口(如CButton派生类CMyButton),然后使用对话框数据交换将一个按钮与自己的派生类对象关联,这时候,一些"建立前"的子类化处理就应该写在"PreSubclassWindow()"中。如果你用的不是"对话框数据关联",而是在OnInitDialg()或OnCreate()中自己创建的Button:m_mybtn.Create(...) ,这时候,一些"建立前"的相关处理就应该写在 PreInitDialog()或PreCreateWindow()中。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值