我想设计这样一个类:当接受一个控件的句柄时,更改该控件的默认消息处理函数,即在默认消息处理函数前加一个自定的函数先行处理消息。这个自定函数处理一些特定消息,余下的还是传给默认消息处理函数。
这个类可以有多个实例,即程序能同时子类化多个控件。我按着这个要求试着写了下代码,结果发现这个设计我根本无法办到……下面我逐步说明:1. 获取默认消息处理函数、并用自定函数替换是用的SetWindowLong或者SetWindowLongPtr。由于该自定函数是非静态的类成员函数,它隐含一个this指针参数,而SetWindowLong要求传入的窗口过程函数是不带this指针的,所以编译器不让通过;(具体讨论: http://topic.csdn.net/t/20050129/17/3762958.html)2. 如果把该自定函数定义为静态的或者拿到类外面,它就不带this指针参数了。可它又无法访问类的非静态成员——传入的控件的默认消息处理函数地址了。该自定函数必须访问这个非静态成员,因为还有很多消息要让默认消息处理函数处理;3. 要让静态成员函数访问非静态成员:1. 可以用实例化的类成员代替未实例化的在函数中使用;2. 可以把类成员都改成静态的;3. 可以在该函数的参数中加上一个位置,接受该非静态成员。(具体方法:http://www.builder.com.cn/2003/1110/101002.shtml)
经分析以上三个办法对这个设计都无效:1. 这样做就要为每个该类的实例创建一个函数,相当于把子类化功能拿到了类外,那这个类也就没有任何意义了;2. 这样该类就只能有一个实例了,不符合要求;3. 这个静态成员函数是消息处理函数,其参数是固定的,不能更改。4. 把“传入的控件的默认消息处理函数地址”改成静态成员。可以在类中定义N个静态的“默认消息处理函数地址”以及与之对应的N个静态的“自定消息处理函数”(每个函数内部使用一个静态“默认消息处理函数地址”)。再加一个非静态成员,指示当前实例的序号。最后规定该类最多只能有N个实例。
在运行时,每实例化一次,就根据当前的“默认消息处理函数地址”组的状态确定当前实例的序号,用SetWindowLong设置对应的“自定消息处理函数”,用返回的“默认消息处理函数地址”给对应的“默认消息处理函数地址”赋值。
这样表面问题是解决了,可由于多了N个静态的“默认消息处理函数地址”成员和N个静态的“自定消息处理函数”,类变得非常庞大,几乎没有实用价值。
我的问题是:是否有更好的解决方法?或者我的设计思路本身就错了,只要纠正了思路,就不会遇到这么变态的问题了?
这个类可以有多个实例,即程序能同时子类化多个控件。我按着这个要求试着写了下代码,结果发现这个设计我根本无法办到……下面我逐步说明:1. 获取默认消息处理函数、并用自定函数替换是用的SetWindowLong或者SetWindowLongPtr。由于该自定函数是非静态的类成员函数,它隐含一个this指针参数,而SetWindowLong要求传入的窗口过程函数是不带this指针的,所以编译器不让通过;(具体讨论: http://topic.csdn.net/t/20050129/17/3762958.html)2. 如果把该自定函数定义为静态的或者拿到类外面,它就不带this指针参数了。可它又无法访问类的非静态成员——传入的控件的默认消息处理函数地址了。该自定函数必须访问这个非静态成员,因为还有很多消息要让默认消息处理函数处理;3. 要让静态成员函数访问非静态成员:1. 可以用实例化的类成员代替未实例化的在函数中使用;2. 可以把类成员都改成静态的;3. 可以在该函数的参数中加上一个位置,接受该非静态成员。(具体方法:http://www.builder.com.cn/2003/1110/101002.shtml)
经分析以上三个办法对这个设计都无效:1. 这样做就要为每个该类的实例创建一个函数,相当于把子类化功能拿到了类外,那这个类也就没有任何意义了;2. 这样该类就只能有一个实例了,不符合要求;3. 这个静态成员函数是消息处理函数,其参数是固定的,不能更改。4. 把“传入的控件的默认消息处理函数地址”改成静态成员。可以在类中定义N个静态的“默认消息处理函数地址”以及与之对应的N个静态的“自定消息处理函数”(每个函数内部使用一个静态“默认消息处理函数地址”)。再加一个非静态成员,指示当前实例的序号。最后规定该类最多只能有N个实例。
在运行时,每实例化一次,就根据当前的“默认消息处理函数地址”组的状态确定当前实例的序号,用SetWindowLong设置对应的“自定消息处理函数”,用返回的“默认消息处理函数地址”给对应的“默认消息处理函数地址”赋值。
这样表面问题是解决了,可由于多了N个静态的“默认消息处理函数地址”成员和N个静态的“自定消息处理函数”,类变得非常庞大,几乎没有实用价值。
我的问题是:是否有更好的解决方法?或者我的设计思路本身就错了,只要纠正了思路,就不会遇到这么变态的问题了?
解决方案 »
- ATL 开发ActiveX控件 注册问题
- 自建控件上添加TOOLTIP
- 谁有计算机专业优秀论文啊?
- #####关于CMap 拷贝的问题
- Combo Box使用DropDown属性的问题?
- 如何实现在CTreeCtrl控件上,出现像CListCtrl在report模式下的column?
- 如何编程获得远程计算机某一文件的信息,如:版本,大小等等!
- 请教:我的ODBC 出了问题,请问怎么重新安装??急急急!谢谢~
- listbox控件如何选择删除?为什么我不能删除第一个?
- 多文档中,如果应用程序名为qqq,当前活动文档名为111,则主窗口标题栏内显示qqq-[1],谁知道
- 这里有没有南宁的程序员或者软件公司老板,打听下南宁的IT情况
- 请教一个重载问题
都是用了同一种方法来完成这个效果
就是将成员函数 做成回调函数.
将hwnd和具体对象的this指针对应起来
MFC是这样做的
这个有些不解,“自定消息处理函数”本身就是CALLBACK类型
关于窗口那一章有详细解释,这种方法怎么做.