深入解析C++的WNDCLASS结构体及其在Windows中的应用
WNDCLASS是一个由系统支持的结构,用来储存某一类窗口的信息,如ClassStyle,消息处理函数,Icon,Cursor,背景Brush等。也就是说,CreateWindow只是将某个WNDCLASS定义的窗体变成实例。要得到某一窗口的WNDCLASS数据,可以用GetClassLong(); typedef struct _WNDCLASS { UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; } WNDCLASS,*PWNDCLASS; 举例说明 long CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//声明 //WinMain函数是所有Windows应用程序的入口,类似c语言中的main函数其功能是完成//一系列的定义和初始化,并产生消息循环。函数说明: int WINAPI WinMain(HINSTANCE hInstance,// handle to current instance HINSTANCE hPrevInstance,// handle to previous instance LPSTR lpCmdLine,// command line int nCmdShow // show state ) { //初始化,初始化包括窗口类的定义、注册、创建窗口实例和显示窗口四部分 HWND hwnd; MSG Msg; WNDCLASS wndclass; char lpszClassName[]="窗口"; //窗口类名 char lpszTitle[]="测试窗口"; //窗口标题名 //窗口类定义,窗口类定义了窗口的形式与功能,窗口类定义通过给窗口类数据结构WNDCLASS赋值完成 //该数据结构中包含窗口类的各种属性 wndclass.style =0; // 窗口类型为缺省类型CS_ Class Style wndclass.lpfnWndProc=WndProc; //定义窗口处理函数 wndclass.cbClsExtra=0; //窗口类无扩展 wndclass.cbWndExtra=0; //窗口实例无扩展 wndclass.hInstance=hInstance; //当前实例句柄 wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); //窗口的最小化图标为缺省图标 wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); // 窗口采用箭头光标 wndclass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH)); //窗口背景为白色 wndclass.lpszMenuName=NULL; //窗口无菜单 wndclass.lpszClassName=lpszClassName; //窗口类名为“窗口” //以下是窗口类的注册-----------Windows系统本身提供部分预定义的窗口类,程序员也可以自定义窗口类,窗口类必须先注册后使用。 if(!RegisterClass(&wndclass)) //如果注册失败 发出警告 {MessageBeep(0); return FALSE;} //创建窗口创建一个窗口的实例由函数CreateWindow()实现 hwnd=CreateWindow( lpszClassName,//窗口类名,创建窗口时一定要基于我们已经注册过的窗口类名,即"窗口"。 lpszTitle,//窗口标题名 WS_OVERLAPPEDWINDOW,//窗口的风格 WS_ Windows Style CW_USEDEFAULT,//窗口左上角坐标值为缺省值 CW_ Create Wndow CW_USEDEFAULT, CW_USEDEFAULT,//窗口的高和宽为缺省值 CW_USEDEFAULT, NULL,//此窗口无父窗口 NULL,//此窗口无子菜单 hInstance,//创建此窗口的应用程序的当前句柄 NULL //不使用该值 ); //显示窗口 ShowWindow(hwnd,nCmdShow); //绘制用户区 UpdateWindow(hwnd); //消息循环 while(GetMessage(&Msg,NULL,0)) //GetMessage()函数是从调用线程的消息队列中取出一条消息;对于每一个应用程序窗口线程,操作系统都会为其建立一个消息队列,当我们的窗口有消息时(即所有与这个窗口线程相关的消息),操纵系统会把这个消息放到该线程的消息队列当中,我们的窗口程序就通过这个GetMessage()函数从自己的消息队列中取出一条一条具体的消息并进行响应操作。 { TranslateMessage(&Msg);//对"消息对"的转化,如对键盘的WM_KEYDOWN和WM_KEYUP消息对转化为WM_CHAR消息,并且将转换后的新消息投递到我们的消息队列中去,这个转化操作不会影响原来的消息,只会产生一个新的消息。 DispatchMessage(&Msg);//DispatchMessage()函数是将我们取出的消息传到窗口的回调函数去处理;可以理解为该函数将取出的消息路由给操作系统,然后操作系统去调用我们的窗口回调函数对这个消息进行处理。 } return Msg.wParam; //消息循环结束 即程序结束时 将信息返回系统 } //窗口函数,窗口函数定义了应用程序对接收到的不同消息的响应,其中包含了应用程序对各种可能接受到的消息的处理过程,时消息处理分支控制语句的集合 long CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { switch(message) { case WM_DESTROY: PostQuitMessage(0); default: //缺省时采用系统消息缺省处理函数 return DefWindowProc(hwnd,message,wParam,lParam); } return (0); } 注:窗口回调函数的函数指针定义typedef LRESULT CALLBACK (* WNDPROC)(HWND,LPARAM); WNDPROC OldWndProc; LRESULT CALLBACK NewWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam){ switch (Msg) { ...... } return CallWindowProc(OldWndProc,g_Wnd,Msg,lParam); } OldWndProc = (WNDPROC)GetWindowLong(g_Wnd,GWL_WNDPROC); SetWindowLong(hwnd,GWL_WNDPROC,(LPARAM)(WNDPROC)NewWndProc); 通过调用SetWindowLong函数可以修改该窗体类的回调函数。 function MouseHookProc(nCode: Integer; wPar: WPARAM; lPar: LPARAM): lResult; stdcall; 如果我要判断鼠标左键是否按下,用wParam==WM_LBUTTONDOWN判断. PMouseHookStruct = ^TMouseHookStruct; tagMOUSEHOOKSTRUCT = packed record pt: TPoint; hwnd: HWND; wHitTestCode: UINT; dwExtraInfo: DWORD; end; TMouseHookStruct = tagMOUSEHOOKSTRUCT; 例如:
function GetMsgProc(nCode: Integer; wPara: WPARAM; lPara: LPARAM) : lResult; stdcall; var hGetMsgHook:HHOOK; Msg: TMsg; begin if (nCode >= 0) then begin FillChar(pMsgData^,Sizeof(TMessageRecord),#0); Msg := TMsg(Pointer(lPara)^); end; Result := CallNextHookEx(hGetMsgHook,nCode,wPara,lPara); end; typedef struct _WNDCLASS{ UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HANDLE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; }WNDCLASS; 结构说明
cbClsExtra: 指定紧随在 WNDCLASS 数据结构后分配的字节数。系统将其初始化为零。
lpszMenuName:指向NULL结束的字符串,该字符串描述菜单的资源名,如同在资源文件里显示的名字一样。若使用一个整数标识菜单,可以使用MAKEINTRESOURCE宏。如果lpszMenuName为NULL, (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 如何使用Cmake为IOS生成静态库的xcode项目?
- Quick-Cocos2d-x的热更新机制实现
- React-Native学习笔记(一)--HelloWorld
- ruby-on-rails – 将几个像素的前置输入标签(simple_form b
- 单一路线在Laravel 4中给出403 Forbidden错误
- AJAX实例:用AJAX从ASP 文件返回数据
- [cocos2dx笔记017]cocos2dx 2.2.6 lua的类型转换
- oracle 11gR2 linux下命令行安装
- Swift入门(四)——可选类型(Optionals)与断言(Assert)
- [转帖]超详细的Oracle数据库在不同损坏级别的恢复总结