子窗口控件
1 创建子窗口控件
子窗口控件类似windows的窗口,不过可以利用windows中已经有的,来直接CreateWindow,CreateWindow中的函数参数如下所示:
Class name(类别名称)
Window text(窗口文字)
Window style(窗口样式)
x position(x位置)
y position(y位置)
Width(宽度)
Height(高度)
Parent window(父窗口)
Child window ID(子窗口ID)
Instance handle(执行实体句柄)
Extra parameters(附加参数)
其中要注意的是子窗口ID,我们可以随意的指定子窗口ID,但是一定要使用强制类型转换把他(HMENU)。
2 WM_CREATE消息
wParam //notused
lParam //pointerto CREATESTRUCT structure
3 CREATESTRUCT
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;
4 子窗口向父窗口发送消息
当点击子窗口的时候,子窗口会向父窗口发送WM_COMMAND消息。
LOWORD(wParam) //子窗口ID
HIWIRD(wParam) //通知码
lParam //子窗口句柄
5 常见的按钮类型
按钮风格 按钮名字
BS_PUSHBUTTON, TEXT("PUSHBUTTON"),
BS_DEFPUSHBUTTON, TEXT("DEFPUSHBUTTON"),
BS_CHECKBOX, TEXT("CHECKBOX"),
BS_AUTOCHECKBOX, TEXT("AUTOCHECKBOX"),
BS_RADIOBUTTON, TEXT("RADIOBUTTON"),
BS_3STATE, TEXT("3STATE"),
BS_AUTO3STATE, TEXT("AUTO3STATE"),
BS_GROUPBOX, TEXT("GROUPBOX"),
BS_AUTORADIOBUTTON, TEXT ("AUTORADIO"),
BS_OWNERDRAW, TEXT("OWNERDRAW")
其中的BS_3STATE根BS_CHECKBOX基本一样,不过相比之多了一种状态,就是BS_3STATE可以变暗。
(1)BS_CHECKBOX,BS_AUTOCHECKBOX,BS_3STATE,BS_AUTO3STATE
他们这些都是一个风格的,按键左边(默认)有一个小方框,当点击按键的时候,小方框显示“勾”表示被选中或者没被选中。
其中的BS_3STATE根BS_CHECKBOX基本一样,不过相比之多了一种状态,就是BS_3STATE可以变暗。
BS_AUTOCHECKBOX,BS_AUTO3STATE是在单击的时候可以自动的改变状态标记的按键,但是BS_CHECKBOX,BS_3STATE需要向该空间发送消息来改变标记状态。
SendMessage(hwndButton, BM_SETCHECK, 1, 0) ; //设置标记状态 iCheck= (int) SendMessage (hwndButton, BM_GETCHECK, 0, 0) ; //获取标记状态 SendMessage(hwndButton,BM_SETCHECK,(WPARAM)(!SendMessage(hwndButton,BM_GETCHECK,0,0)),0); //用此来翻转标记状态
(2)BS_RADIOBUTTON,BS_AUTORADIOBUTTON
这两个风格的按键跟CheckBox很类似,不过跟checkBox不同的是,我们可以同时让多个CheckBox处于选中状态,但是只能让一个RadioButton处于选中状态,简而言之:CheckBox是多选的,RadioButton是单选的。如下图所示:
(3)BS_GROUPBOX
感觉除了样式外,没什么用处
(4)PUSHBUTTON
当按下的时候会发送通知吗是BN_CLICKED的WM_COMMAND消息。
(5)按键消息
用户操作按键的时候,按键会向父窗口发送WM_COMMAND消息,其中wParam的高字节代表的是通知码。具体如下所示:
Notification code |
Description |
BCN_HOTITEMCHANGE |
Windows XP: The mouse entered or left the client area of a button. |
BN_CLICKED |
The user clicked a button. |
BN_DBLCLK or BN_DOUBLECLICKED |
The user double-clicked a button. |
BN_DISABLE |
A button is disabled. |
BN_PUSHED or BN_HILITE |
The user pushed a button. |
BN_KILLFOCUS |
The button lost the keyboard focus. |
BN_PAINT |
The button should be painted. |
BN_SETFOCUS |
The button gained the keyboard focus. |
BN_UNPUSHED or BN_UNHILITE |
The button is no longer pushed. |
(6)查找和设置按键信息
Windows的默认窗口函数函数能够处理系统按键中不能处理的按键消息,通过这些消息可以查找和改变按键的信息。例如:
SendMessage(hwndSon,BM_SETCHECK,1,0);//设置按键为选中状态
按键消息表(常用的)
显示和隐藏子窗口
ShowWindow(hwndChild,SW_SHOWNORMAL) ShowWindow(hwndChild,SW_HIDE);
启用和禁用子窗口
EnableWindow (hwndChild, FALSE); EnableWindow (hwndChild, TRUE);
(7)按键的颜色
系统为按键的各个部分(表面,边框,阴影,文字,背景等)都提供了默认的颜色,可以通过GetSysColor函数来获取这些值,也可以通过SetSysColor来重新设置这些值。但是SetSysColor会影响所有的应用程序,所以建议最好不好这样搞。
在绘制按键之前,系统会发送一个WM_CTLCOLORBTN给父窗口。这个消息包含按键的设备句柄,窗口句柄。父窗口可以使用这些句柄来改变按键的文本以及背景颜色。但是只有owner_drawn 按键才会响应父窗口对这些消息的处理。
(8)WM_DRAWITEM
当自绘的按钮,下拉框(combo box),列表框(list box)菜单(Menu)创建或者发生改变的时候发送到父窗口。
wParam :控件ID
lParam:指向DRAWITEMSTRUCT
实例代码:
case WM_DRAWITEM : pdis = (LPDRAWITEMSTRUCT)lParam ; // Fill area withwhite and frame it black FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH) GetStockObject (WHITE_BRUSH)) ; FrameRect(pdis->hDC,&pdis->rcItem,(HBRUSH) GetStockObject (BLACK_BRUSH)) ; //Drawinward and outward black triangles cx = pdis->rcItem.right - pdis->rcItem.left ; cy = pdis->rcItem.bottom -pdis->rcItem.top ; switch(pdis->CtlID) { case ID_SMALLER : pt[0].x = 3 * cx / 8; pt[0].y = 1 * cy / 8 ; pt[1].x = 5 * cx / 8; pt[1].y = 1 * cy / 8 ; pt[2].x = 4 * cx / 8; pt[2].y = 3 * cy / 8 ; Triangle (pdis->hDC, pt) ; pt[0].x= 7 * cx / 8 ; pt[0].y = 3 * cy / 8 ; pt[1].x= 7 * cx / 8 ; pt[1].y = 5 * cy / 8 ; pt[2].x= 5 * cx / 8 ; pt[2].y = 4 * cy / 8 ; Triangle(pdis->hDC, pt) ; pt[0].x= 5 * cx / 8 ; pt[0].y = 7 * cy / 8 ; pt[1].x= 3 * cx / 8 ; pt[1].y = 7 * cy / 8 ; pt[2].x= 4 * cx / 8 ; pt[2].y = 5 * cy / 8 ; Triangle(pdis->hDC, pt) ; pt[0].x= 1 * cx / 8 ; pt[0].y = 5 * cy / 8 ; pt[1].x= 1 * cx / 8 ; pt[1].y = 3 * cy / 8 ; pt[2].x= 3 * cx / 8 ; pt[2].y = 4 * cy / 8 ; Triangle(pdis->hDC, pt) ; break ; case ID_LARGER : pt[0].x = 5 * cx / 8; pt[0].y = 3 * cy / 8 ; pt[1].x = 3 * cx / 8; pt[1].y = 3 * cy / 8 ; pt[2].x = 4 * cx / 8; pt[2].y = 1 * cy / 8 ; Triangle (pdis->hDC,pt) ; pt[0].x = 5 * cx / 8; pt[0].y = 5 * cy / 8 ; pt[1].x = 5 * cx / 8; pt[1].y = 3 * cy / 8 ; pt[2].x = 7 * cx / 8; pt[2].y = 4 * cy / 8 ; Triangle (pdis->hDC,pt) ; pt[0].x = 3 * cx / 8; pt[0].y = 5 * cy / 8 ; pt[1].x = 5 * cx / 8; pt[1].y = 5 * cy / 8 ; pt[2].x = 4 * cx / 8; pt[2].y = 7 * cy / 8 ; Triangle (pdis->hDC,pt) ; pt[0].x = 3 * cx / 8 ; pt[0].y = 3 * cy / 8 ; pt[1].x = 3 * cx / 8; pt[1].y = 5 * cy / 8 ; pt[2].x = 1 * cx / 8; pt[2].y = 4 * cy / 8 ; Triangle (pdis->hDC,pt) ; break; } //Invert the rectangle if the button is selected if(pdis->itemState & ODS_SELECTED) InvertRect(pdis->hDC,&pdis->rcItem); //Draw a focus rectangle if the button has the focus if(pdis->itemState & ODS_FOCUS) { pdis->rcItem.left += cx / 16 ; pdis->rcItem.top += cy / 16 ; pdis->rcItem.right -= cx / 16 ; pdis->rcItem.bottom-= cy / 16 ; DrawFocusRect(pdis->hDC, &pdis->rcItem); } return0 ;
(9)ListBox
<1>添加资源
SendMessage (hwndList, LB_ADDSTRING, 0, (LPARAM) szString) ;
<2>插入资源
SendMessage (hwndList, LB_INSERTSTRING, iIndex, (LPARAM) szString) ;
<3>删除资源
SendMessage (hwndList, LB_DELETESTRING, iIndex, 0)
<4>清除Box内内容
SendMessage (hwndList, LB_RESETCONTENT, 0, 0) ;
<5>关闭重画
SendMessage (hwndList, WM_SETREDRAW, FALSE, 0) ;
<6>打开重画
SendMessage (hwndList, WM_SETREDRAW, TRUE,0) ;
<7>获取项目数
iCount = SendMessage (hwndList, LB_GETCOUNT, 0, 0) ;
<8>加亮显示选定项
SendMessage (hwndList, LB_SETCURSEL, iIndex, 0) ;
<9>查找匹配项
iIndex = SendMessage (hwndList, LB_SELECTSTRING, iIndex, (LPARAM) szSearchString) ;
<10>查找当前选定项
iIndex = SendMessage (hwndList, LB_GETCURSEL, 0, 0) ;
<11>获取指定项的字符串内容
iLength = SendMessage (hwndList, LB_GETTEXT, iIndex, (LPARAM) szBuffer) ;