解说Win32的窗口子类化

路博环保除甲醛

路博环保除甲醛

2016-01-29 11:59

解说Win32的窗口子类化,解说Win32的窗口子类化

解说Win32的窗口子类化
     
     作者:李马(home.nuc.edu.cn/~titilima)

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/cyuyanjiaocheng/)

下载本文的配套源代码
       
也许你需要一个特殊的Edit来限制浮点数的输入,但是现有的Edit却并不能完成这项工作——因为它只能够单纯的限制大小写或者纯数字。当你在论坛上求救的时候,某个网友告诉你:“用子类化。”你也许会在看到一线曙光的同时多出了一连串的问题:何为子类化?子类化的原理是什么?如何实现子类化?下面就让我从一个简单的C++程序开始,一步步解开你的疑团吧。
 首先,我为你列出以下这个C++程序:

#includeusing namespace std;class Parent{public:  void func(void) { cout << "func of Parent" << endl; }};class Child : public Parent{public:  void func(void) { cout << "func of Child" << endl; }};void main(){  Parent p;  Child c;  p.func();  c.func();}

现在我来解说一下。这段代码中我定义了两个C++类:父类和子类,并且子类是继承自父类的;它们有一个具有相同名称的成员函数func。在main函数中,我分别构造了父类和子类的对象,并调用了它们各自的成员函数func。结果如下:

func of Parentfunc of Child

简单说来,这段代码就是子类根据自己的需要改写了func成员函数。而Win32的子类化的原理也与此类似,只不过子类化实际上并没有像C++一样重载哪个函数,而是靠拦截Windows系统中的某些消息来自己进行处理罢了。举例来说,请大家看以下这段简单的窗口回调过程:

LRESULT CALLBACK ProcMain(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam){  switch (Msg)  {  case WM_CLOSE:    EndDialog(hDlg, 0);    break;  case WM_DESTROY:    PostQuitMessage(0);    break;  }  return 0;}

在这个回调之中,我手动处理了两个消息:在单击了“关闭”按钮(WM_CLOSE)的时候,我将对话框关闭(EndDialog);在对话框销毁(WM_DESTROY)的时候,我向系统消息队列中发送了退出的消息来完成结束工作(PostQuitMessage)。也就是说,如果把WM_CLOSE的响应代码改成:

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/cyuyanjiaocheng/)
case WM_CLOSE:    ShowWindow(hDlg, SW_MINIMIZE);    break;

这样一来,这个对话框就会和MSN一样,在单击了“关闭”之后,就会完成最小化的工作了。那么,对于窗口过程已定义好的系统控件,将如何手动响应它的消息呢?
   我们可以用函数指针的办法,将我们感兴趣的消息拦截下来,处理完之后再让预定义的窗口过程处理。这个过程大致如下:

WNDPROC OldProc;  OldProc = (WNDPROC)SetWindowsLong(hWnd, GWL_WNDPROC, (LONG)NewProc);

当然,这里的新窗口过程NewProc是预先由你实现好的。上述代码执行以后,系统在处理hWnd的窗口消息时,就会先进入你实现的NewProc回调过程,然后在处理过你感兴趣的消息之后,通过CallWindowProc函数和你预先保存的OldProc再次回到原来的回调过程中完成剩余的工作。
   以上就是窗口子类化的原理分析,下面我通过一个实例来实际解说如何对窗口进行子类化。

这个例子的界面如下:



界面上方的编辑框是用来限制浮点输入的,下面则是一个普通的超级链接。
   好了,下面我开始按步骤完成对这两个窗口的子类化:
   第一步,在主窗口对话框初始化的时候,保存原有的窗口过程,并设置新的窗口过程。代码如下:

case WM_INITDIALOG:    EditProc = (WNDPROC)SetWindowLong(GetDlgItem(hDlg, IDC_EDIT), GWL_WNDPROC, (LONG)ProcFloat);    StaticProc = (WNDPROC)SetWindowLong(GetDlgItem(hDlg, IDC_ST_HOMEPAGE), GWL_WNDPROC, (LONG)ProcLink);    break;

第二步,实现浮点编辑框的窗口过程:

LRESULT CALLBACK ProcFloat(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){  if (Msg == WM_CHAR && wParam != ''.'' && (wParam = ''9'') && wParam != VK_BACK)  {    MessageBeep(MB_OK);    return 0;  }  else    return CallWindowProc(EditProc, hWnd, Msg, wParam, lParam);}

这里需要解释的是,由于控件本身的需求,所以只需要拦截一个消息,就是接收字符的WM_CHAR。当用户输入的字符不是小数点、0~9以及退格键(注意不要少了退格键,否则你将会发现你的编辑框无法删除输入错误的数字)的时候,就发出一声声音以提示输入错误。至于其它的消息,则调用原有的回调函数进行处理。
   第三步,实现超级链接的窗口过程:

LRESULT CALLBACK ProcLink(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){  switch (Msg)  {  case WM_SETCURSOR:    SetCursor(LoadCursor(NULL, IDC_HAND));    break;  case WM_LBUT
展开更多 50%)
分享

猜你喜欢

解说Win32的窗口子类化

C语言教程 C语言函数
解说Win32的窗口子类化

利用窗口子类化隐藏系统图标

C语言教程 C语言函数
利用窗口子类化隐藏系统图标

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

获得 Win32 窗口句柄的更好的方法

C语言教程 C语言函数
获得 Win32 窗口句柄的更好的方法

MFC的子类化技术

编程语言 网络编程
MFC的子类化技术

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

如何用 Win32 SDK 编程创建 Tri-pane HTML Help 窗口

Web开发
如何用 Win32 SDK 编程创建 Tri-pane HTML Help 窗口

Win32下的几种串口通信编程

编程语言 网络编程
Win32下的几种串口通信编程

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

其它创建和修改三维实体的方法

其它创建和修改三维实体的方法

KVIP考勤系统

KVIP考勤系统
下拉加载更多内容 ↓