控件是子窗口,它们是系统已经定义好的窗口类,因此不需要注册、 也不需要写消息处理函数。 在主窗口得到WM_CREATE消息时,建立子窗口即可。
二、实例
//参数:窗口句柄,消息,消息参数,消息参数 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { //处理感兴趣的消息 switch (message) { case WM_CREATE: CreateWindow(TEXT("BUTTON"), //控件"类名称" TEXT("按钮(&A)"), WS_CHILD | WS_VISIBLE |BS_PUSHBUTTON, 10, 10, 100, 100, hwnd, (HMENU)1000, //控件ID ((LPCREATESTRUCT) lParam)->hInstance, //实例句柄 NULL); return 0; case WM_DESTROY: //当用户关闭窗口,窗口销毁,程序需结束,发退出消息,以退出消息循环 PostQuitMessage (0) ; return 0 ; } //其他消息交给由系统提供的缺省处理函数 return ::DefWindowProc (hwnd, message, wParam, lParam) ; }
三、关于WM_CREATE消息 WM_CREATE 的lParam参数将会传入一个建立时信息结构指针(LPCREATESTRUCT)。 结构中包含了一些有用信息(窗口建立时的参数)。
typedef struct tagCREATESTRUCT { LPVOID lpCreateParams; HINSTANCE hInstance; //实例句柄 HMENU hMenu; HWND hwndParent; int cy; int cx; int y; int x; LONG style; LPCTSTR lpszName; LPCTSTR lpszClass; DWORD dwExStyle; } CREATESTRUCT, *LPCREATESTRUCT;
四、控件与父窗口的协作 1.控件上发生动作时,将向父窗口发送通知消息WM_COMMAND。 WM_COMMAND: HIWORD(wParam):通知码(notification code) LOWORD(wParam):控件ID (HWND)lParam: 控件句柄
除了WM_COMMAND外,每种控件还有可能有其他的通知消息(如WM_DRAWITEM)。
2.父窗口需要控制控件时,向控件发控件消息。 事先应记录下控件句柄,或由ID获取控件句柄
3.备注: 各种控件的通知消码和控制消息可由 MSDN-> Platform SDK-> User Interface Services->Windows User Interface->Controls 查得。
五、控件"类名称" 1.标准控件 BUTTON :按钮 COMBOBOX :复合框 EDIT :编辑 LISTBOX :列表 RichEdit :Rich Edit version 1.0 RICHEDIT_CLASS :Rich Edit version 2.0 SCROLLBAR :滚动条 STATIC :静态
2.外壳附带的公用控件 注:建立前需要用InitCommonControlsEx进行初始化
INITCOMMONCONTROLSEX icex;// Ensure that the common control DLL is loaded. icex.dwSize = sizeof(INITCOMMONCONTROLSEX); icex.dwICC = ICC_LISTVIEW_CLASSES; InitCommonControlsEx(&icex); HWND hWndListView =CreateWindowEx(0,WC_LISTVIEW, //WC_LISTVIEW不需要加引号 TEXT(""), WS_CHILD | WS_VISIBLE|WS_BORDER | LVS_ICON | LVS_EDITLABELS | WS_EX_CLIENTEDGE , 10, 10, 100, 100, hwnd, (HMENU)1000, //控件ID ((LPCREATESTRUCT) lParam)->hInstance, //实例句柄 NULL); }
ANIMATE_CLASS DATETIMEPICK_CLASS HOTKEY_CLASS MONTHCAL_CLASS PROGRESS_CLASS REBARCLASSNAME STATUSCLASSNAME TOOLBARCLASSNAME TOOLTIPS_CLASS TRACKBAR_CLASS UPDOWN_CLASS WC_COMBOBOXEX WC_HEADER WC_IPADDRESS WC_LISTVIEW WC_PAGESCROLLER WC_TABCONTROL WC_TREEVIEW
3.特殊窗口 MDIClient :MDI客户区窗口 ComboLBox :The class for the list box contained in a combo box. DDEMLEvent :Windows NT/2000: The class for DDEML events. Message :Windows 2000: The class for a message-only window. #32768 :The class for a menu. #32769 :The class for the desktop window. #32770 :The class for a dialog box. #32771 :The class for the task switch window. #32772 :Windows NT/2000: The class for icon titles.
一、概述
控件的消息处理 函数 是由系统定义好了的,通常情况下,不需要自己提供。
但当需要对控件进行特殊控制时,可以提供一个消息处理函数,替换原来的消息处理函数。
自己的处理完成后,再调用控件的缺省消息处理。
二、相关函数
1.窗口类的属性可以通过GetWindowLong和SetWindowLong进行读取和设置
LONG GetWindowLong( HWND hWnd, // handle to window int nIndex // offset of value to retrieve ); LONG SetWindowLong( HWND hWnd, // handle to window int nIndex, // offset of value to set LONG dwNewLong // new value );
可以返回或设置以下内容:
nIndex值 意义
GWL_EXSTYLE 扩展风格
GWL_STYLE 风格
GWL_WNDPROC 消息处理函数
GWL_HINSTANCE 实例
GWL_ID 窗口ID
GWL_USERDATA 用户数据
DWL_DLGPROC 对话框消息处理函数
DWL_MSGRESULT
DWL_USER
所以使用
OldMsgProc = (WNDPROC)SetWindowLong (hControlWnd, GWL_WNDPROC, (LONG)MyMsgProc);
将控件消息处理函数替换成MyMsgProc,原处理函数被OldMsgProc记录。
2.调用消息处理函数
LRESULT CallWindowProc( WNDPROC lpPrevWndFunc, // pointer to previous procedure HWND hWnd, // handle to window UINT Msg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter );
三、示例
1.提供新处理函数
//记录原来处理函数的全局变量 WNDPROC OldMsgProc; //新消息处理函数 LRESULT MyMsgProc(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: ::MessageBox(NULL,"click!","",MB_OK); } //调用控件原来的消息处理函数 return CallWindowProc(OldMsgProc,hwnd,message,wParam,lParam); }
2.建立窗口后,更改消息处理函数
case WM_CREATE: { HWND hControlWnd = CreateWindowEx(0,"BUTTON", TEXT("按钮(&A)"), WS_CHILD | WS_VISIBLE|BS_PUSHBUTTON, 10, 10, 100, 100, hwnd, (HMENU)1000, //控件ID ((LPCREATESTRUCT) lParam)->hInstance, //实例句柄 NULL); //嵌入新的消息处理函数 OldMsgProc = (WNDPROC) SetWindowLong (hControlWnd, GWL_WNDPROC, (LONG)MyMsgProc); } return 0;