1.什么是窗口子类化技术?
比喻:在学校的时候,老师在课堂给你上课,老师讲解的东西(这里就是windows的消息),你就是窗口,专门接受老师所讲授的消息,这时候老师讲什么你最清楚,有天,你病,没去上课,你叫同学帮比补课,老师把消息传给同学,同学在给你讲,这时候,同学有可能漏讲一些知识,也可能自己补充一切知识,然后在给你讲。
第一种情况:老师给你讲 (这个就是未窗口子类的时候)
第二种情况:老师给同学讲,同学在给你讲 (窗口子类化的时候)
也就是说: windows响应的消息,全部由你自定义的窗口函数来处理,是忽略某些,还是保留某些都由你说了算了,然后在传回给主窗口处理。
2.如何 实现窗口子类化
参量:你所需要的子窗口的句柄(子窗口可以是控件,或者任意的子窗口),万物皆句柄
LONG SetWindowLong( HWND hWnd, int nIndex, LONG dwNewLong );
- hWnd = 将要实施子类化的窗口的句柄
- nIndex = 函数了功能索引
GWL_EXSTYLE 设置窗口的扩展风格.
GWL_STYLE 设置新的窗口风格
GWL_WNDPROC 设置新的窗口处理函数地址
GWL_HINSTANCE 设置新的应用程序句柄
GWL_ID 设置新的窗口标识
GWL_USERDATA 设置一个与这个窗口相关的给用户使用的32位的数据 - dwNewLong = 用来更新的数据
- 该函数返回以前的窗口过程的地址,要保存下来,用来恢复的
2.一个例子说明:用窗口子类化技术 来选择Edit控件输入的字符
目的:要求编辑框不能输入0~9的数字 。
#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include "MainDlg.h"
#include<Commctrl.h>
#include "windef.h"
WNDPROC OldProc;
HWND hedit;
BOOL WINAPI Edit_Proc(HWND hedit, UINT uMsg, WPARAM wParam, LPARAM lParam)//窗口子类化
{
switch(uMsg)
{
case WM_CHAR: //响应编辑框内输入的字符
{ BYTE inchar=LOBYTE(wParam);
if(inchar>='0'&& inchar<='9')
return CallWindowProc(OldProc,hedit,uMsg,0,lParam);//0~9传回NULL值
break;
}
break;
}
return CallWindowProc(OldProc,hedit,uMsg,wParam,lParam);//负责正常传回去主窗口处理
}
BOOL WINAPI Main_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
hedit=GetDlgItem(hwnd,IDC_EDIT);
OldProc=(WNDPROC)SetWindowLong(hedit,GWL_WNDPROC,(LONG)Edit_Proc);//最重要的一句,这句显示了如何窗口子类 注意各个参数即可
return TRUE;
}
case WM_COMMAND:
{
switch(wParam)
{
case IDC_OK:
{ MessageBox(hwnd,TEXT("确定了"),TEXT(""),MB_OK);
break;
}
}
break;
}
case WM_CLOSE:
EndDialog(hwnd,0);
break;
}
return FALSE;
}