第六讲子窗口控制_第1页
第六讲子窗口控制_第2页
第六讲子窗口控制_第3页
第六讲子窗口控制_第4页
第六讲子窗口控制_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第六讲:子窗口控制控制(控件)是一种特殊的子窗口,也属于某个窗口类,这个窗口类或者是已经预先定义好的,或者是由拥有者(开发者)定义。窗口类以及对应的窗口过程定义了控制的属性,包括其外观、行为、目的等。应用程序既可以通过在调用CreateWindowEx时指定窗口类的类名来单独创建一个控制,也可以在对话框模板中指定一些控制,然后由系统为其创建。预定义控制:操作系统为一些控制提供了已经定义好的窗口类及对应的窗口过程。属于这些窗口类的控制称为预定义控制。类名说明BUTTON按钮COMBOBOX组合框EDIT编辑框LISTBOX列表框RichEditRichEdit 1.0RICHEDIT_CLASS

2、RichEdit 2.0或3.0SCROLLBAR滚动条STATIC静态控件表一、系统预定义的控制每个预定义控制窗口类都有一组相关的控制样式,使它们在应用程序中展现出不同的外观和行为,例如BUTTON窗口类支持push buttons, radio buttons, check boxes, group boxes等样式;每个预定义控制窗口类同时还有一组相关的通知和控制消息,应用程序通过这些消息确定用户何时及怎样对这些控制进行输入。通知消息:当系统为对话框创建了控制时,这些控制就成为对话框的子窗口;当应用程序创建控制时,这些控制就成为由应用程序指定的某个窗口的子窗口。这些子窗口控制接收到用户的

3、输入时,会向其父窗口发送通知消息。应用程序通过这些消息来确定用户想让它们完成什么工作。例如,当用户点击push button时,按钮会向父窗口发送BN_CLICKED消息。这些通知消息以WM_COMMAND形式出现,消息中包含子窗口控制标识和通知码。参数说明LOWORD(wParam)子窗口ID号HIWORD(wParam)通知码,告诉父窗口到底发生了什么变化,通知码和控件的类型以及事件相关,系统对每一类控件的每个事件的通知码都有明确的定义,用一个系统定义的整常量来表示LParam子窗口句柄表二、WM_COMMAND通知消息子窗口控制标识是一个由应用程序指定的唯一ID,用以代表这个控制,这个标

4、识既可以在CreateWindowEx的hMenu参数中指定,也可以在DLGITEMTEMPLATEEX结构的id成元中指定。由于控制本身并不知道其自身的标识,在向父窗口发送通知消息之前,必须查询其自身标识。以下是经常用到的与子窗口标识相关的API:知道子窗口ID号和父窗口句柄,找子窗口句柄:hwndChild=GetDlgItem(hwndParent,id);知道子窗句柄, 找子窗口ID:id=GetWindowLong(hwndChild,GWL_ID);id=GetDlgCtrlID(hwndChild);知道子窗句柄, 找父窗口句柄:hwndParent =GetParent(hwn

5、dChild);控制消息:应用程序可以利用SendMessage向子控制发送消息,来指导子窗口控制完成特定的任务。每种控制消息的目的和功能是与特定控制的窗口类相关的,并且由窗口类对应的窗口过程定义。控制消息既可以是预先定义好的如WM_GETTEXT和 WM_GETDLGCODE等,也可以由应用程序自定义。通常情况下,对于由应用程序创建的控制,窗口过程应当处理如下消息:消息说明WM_GETDLGCODEProcess if the control uses the ENTER, ESC, TAB, or arrow keys. The IsDialogMessage function sends

6、 this message to controls in a dialog box to determine whether to process the keys or pass them to the control.WM_GETFONTProcess if the WM_SETFONT message is also processed.WM_GETTEXTProcess if the control text is not the same as the title specified by the CreateWindowEx function.WM_GETTEXTLENGTH同上W

7、M_SETTEXT同上WM_SETFOCUSProcess if the control displays a caret, a focus rectangle, or another item to indicate that it has the input focus.WM_KILLFOCUS同上WM_SETFONTProcess if the control displays text. The system sends this message when creating a dialog box that has the DS_SETFONT style.对于由应用程序自定义的控制

8、消息,必须通过调用SendMessage或SendDlgItemMessage来显式发送给控制。每条消息的标识ID必须唯一并且不能与已知的其它窗口消息ID相冲突,自定义消息一般以WM_USER开始加上某个数值。自定义控制:应用程序可以创建自定义控制,以实现预定义控制不支持的功能,Windows提供三种创建自定义控制的方式。1、 利用所有者绘制控制按钮、列表框和组合框都可以采用所有者绘制样式,以使得它们在将要被绘制时,会把消息发送给父窗口,应用程序接收到这些消息时,可以进行自定义绘制,以改变这些控制的外观。例如,在列表框中每个元素之前都显示一个小位图。2、 窗口子类化子类化一个预定义控制是创建自

9、定义控制的另一种方式。子类化窗口过程可以通过处理控制的某些特定消息来改变其行为,而其它未处理的消息仍然转发给原来的窗口过程。例如,应用程序可以处理编辑框的WM_PAINT消息来显示不同的字体和字号。3、 应用程序自定义窗口类自定义控制窗口类与普通窗口类一样,需要指定类名及实现对应的窗口过程,然后可以在CreateWindowEx的参数中指定类名,或者在对话框模板中指定类名。对于这种自定义控制,其对应的窗口过程最少需要对其绘制,如果想接收输入,还需要处理鼠标和键盘消息,并且向父窗口发送通知消息。按钮:按钮的样式包括BS_CHECKBOX、BS_DEFPUSHBUTTON、BS_GROUPBOX、

10、BS_PUSHBUTTON、BS_RADIOBUTTON、BS_AUTOCHECKBOX、BS_3STATE等。按钮接受用户输入或将要进行绘制时向父窗口发送BN_CLICKED、BN_PAINT、BN_DISABLE、BN_PUSHED、BN_UNPUSHED、BN_DBLCLK、BN_SETFOCUS、BN_KILLFOCUS 、WM_CTLCOLORBTN等消息。父窗口向按钮发送BM_GETCHECK、BM_SETCHECK、BM_GETSTATE、BM_SETSTATE、BM_SETSTYLE、BM_CLICK、BM_GETIMAGE、BM_SETIMAGE等消息来改变按钮的外观或行为。

11、所有者绘制按钮:使用BS_OWNERDRAW风格创建的按钮,在需要重新绘制其窗口时会向它的父窗口发送一个WM_DRAWITEM消息,如:当按钮被创建时;当按钮被按下或者被释放时;当按钮被得到或者失去输入焦点时;当按钮的客户区有无效区域时。WM_DRAWITEM消息的第二个参数lParam是一个指向系统定义的DRAWITEMSTRUCT结构的指针,该结构包含的部分成员如下:typedef struct tagDRAWITEMSTRUCT UINT CtlID; /控件的ID号 UINT itemState; /当前窗口的视觉状态 HDC hDC; /控件窗口的设备环境描述表句柄 RECT rcI

12、tem; /控件窗口的绘图区域 DRAWITEMSTRUCT;所有者绘制按钮举例:The parent window of an owner-drawn button typically responds to at least three messages for the button: WM_INITDIALOG WM_COMMAND WM_DRAWITEM When you must paint an owner-drawn button, the system sends the parent window a WM_DRAWITEM message whose lParam para

13、meter is a pointer to a DRAWITEMSTRUCT structure. Use this structure with all owner-drawn controls to provide the application with the information it requires to paint the control. The itemAction and itemState members of the DRAWITEMSTRUCT structure define how to paint an owner-drawn button. The fol

14、lowing example shows how to process WM_INITDIALOG, WM_DRAWITEM, and WM_COMMAND messages for owner-drawn buttons. This example demonstrates how to draw one of two bitmaps for a control, depending on whether the control is selected. You would typically use the wParam parameter of the WM_DRAWITEM messa

15、ge to identify the control; in this example, only one control is assumed. BOOL CALLBACK OwnDrawProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) HDC hdcMem; LPDRAWITEMSTRUCT lpdis; switch (message) case WM_INITDIALOG: / hinst, hbm1 and hbm2 are defined globally. hbm1 = LoadBitmap(HANDLE) h

16、inst, OwnBit1); hbm2 = LoadBitmap(HANDLE) hinst, OwnBit2); return TRUE; case WM_DRAWITEM: lpdis = (LPDRAWITEMSTRUCT) lParam; hdcMem = CreateCompatibleDC(lpdis-hDC); if (lpdis-itemState & ODS_SELECTED) / if selected SelectObject(hdcMem, hbm2); else SelectObject(hdcMem, hbm1); / Destination StretchBlt

17、( lpdis-hDC, / destination DC lpdis-rcItem.left, / x upper left lpdis-rcItem.top, / y upper left / The next two lines specify the width and / height. lpdis-rcItem.right - lpdis-rcItem.left, lpdis-rcItem.bottom - lpdis-rcItem.top, hdcMem, / source device context 0, 0, / x and y upper left 32, / sourc

18、e bitmap width 32, / source bitmap height SRCCOPY); / raster operation DeleteDC(hdcMem); return TRUE; case WM_COMMAND: if (wParam = IDOK | wParam = IDCANCEL) EndDialog(hDlg, TRUE); return TRUE; if (HIWORD(wParam) = BN_CLICKED) switch (LOWORD(wParam) case IDC_OWNERDRAW: / application-defined processi

19、ng break; break; case WM_DESTROY: DeleteObject(hbm1); / delete bitmaps DeleteObject(hbm2); break; return FALSE; UNREFERENCED_PARAMETER(lParam); 静态类控件:静态类控件主要用于显示静态文字串和图形,该类控件既不鼠标和键盘输入,也不向父窗口发送WM_COMMAND消息。只捕获WM_NCHITTEST消息,并向下(父窗口)传递HTTRANSPARENT值。如果对其进行绘制,需要处理WM_CTLCOLORSTATIC消息。静态类控件窗口背景涂色消息WM_CTL

20、COLORSTATIC:每当静态类控件窗口需要被重画时,静态类控件就向父窗口发送WM_CTLCOLORSTATIC消息。若在编程时处理此消息,一定用如下三条语句设置在静态控件窗口输出文本的前景色和背景色、以及系统用于涂静态控件窗口客户区的刷子。SetTextColor (HDC) wParam, crPrimi % 3) ; SetBkColor(HDC)wParam,GetSysColor(COLOR_BTNHIGHLIGHT); return (LRESULT) hBrushStatic ;消息参数wParam: 静态类控件窗口的设备环境描述表句柄;lParam: 静态类控件窗口的窗口句柄

21、。静态类控件风格包括SS_BLACKRECT、SS_GRAYRECT、SS_WHITERECT、SS_BLACKFRAME、SS_GRAYFRAME SS_WHITEFRAME、SS_CENTER、SS_LEFT、SS_RIGHT等。滚动条类控件: 滚动条类控件风格包括SBS_VERT和SBS_HORZ。当对在父窗口的客户区创建的滚动条控件进行操作时,滚动条控件不向父窗口发送WM_COMMAND消息,而是发送WM_HSCROLL消息或WM_VSCROLL消息。WM_HSCROLL消息或WM_VSCROLL消息参数:窗口滚动条:lParam=0;滚动条控件:lparam=滚动条控件窗口句柄Ctr

22、lhwnd;wParam参数的解释对窗口滚动条和滚动条类控件都相同。设置滚动条类控件的范围和滚动框的位置函数包括:SetScrollRange (hwndScroll, SB_CTL, iMin, iMax, bRedraw) ;SetScrollPos (hwndScroll, SB_CTL, iPos, bRedraw) ;SetScrollInfo (hwndScroll, SB_CTL, &si, bRedraw) ;当使用鼠标点击滚动条控件时,如果想使滚动条控件能获得输入焦点,必须把窗口风格WS_TABSTOP包含在CreateWindow()函数的窗口风格中。滚动条控件窗口背景涂色

23、消息WM_CTLCOLORSCROLLBAR:每当滚动条控件窗口需要被重画时,滚动条控件就向父窗口发送WM_CTLCOLORSCROLLBAR消息。若在编程时处理此消息,一定用return语句返回一个刷子,系统用这个刷子涂滚动条控件窗口。消息参数wParam: 滚动条控件窗口的设备环境描述表句柄;lParam: 滚动条控件窗口的窗口句柄。窗口子类化技术(subclassing):当应用程序创建了一个窗口,系统为其分配一块内存,用来存储特定的窗口信息,包括处理消息的窗口过程。当系统需要向窗口传递消息时,会在这块内存中搜索对应的窗口过程地址,然后进行消息投递。窗口子类化技术允许应用程序对将要发送到

24、特定窗口的消息,提前进行解释或处理,以达到修改或监视窗口行为的目的。例如,可以通过这一技术阻止某个编辑框控件接受特定的字符。窗口子类化用自己定义的窗口过程函数去取代控件原有的窗口过程函数,因此自定义的窗口过程可以接收属于控件的全部消息。对于某个特定的消息,自定义窗口过程既可以将其直接传递给原来的窗口过程,也可以对消息进行修改,然后再将其直接传递给原来的窗口过程,还可以自己对消息进行处理,而不再继续向下传递。函数SetWindowLong(hwnd,GWL_WNDPROC, (LONG) WndProc)可用于为窗口hwnd设置新的窗口过程函数WndProc,其中GWL_WNDPROC是系统定义

25、的整型常数,WNDPROC是系统定义的数据类型,用于定义指向窗口过程函数的指针,该函数的返回值是指向窗口hwnd原来窗口过程函数的指针。窗口超类化技术(superclassing):窗口超类化与窗口子类化相似,都是用一个新的窗口过程来取代原有的窗口过程,以改变窗口的行为。窗口超类化根据已有的标准控件的窗口类信息(GetClassInfo),进行修改,包括类名、窗口过程地址、实例句柄,保留其它部分不变,然后重新注册一个窗口类,并用于创建后续的子窗口。为了实现只接受特定字符的多个编辑框控件,既可以为每个编辑框进行子类化,也可以使用超类化一次性完成。子类化超类化只有少数窗口需要修改时才使用此一技术需

26、要改变同类别的多个窗口行为时不需注册新类别必须注册新的窗口类别在subclassing 之前必须先产生窗口superclassing 之前不需先产生窗口Subclassed 窗口无法拦截窗口初始化消息(WM_NCCREATE 和WM_CREATE)Superclassed 窗口可以拦截窗口初始化消息(WM_NCCREATE 和WM_CREATE窗口子类化与超类化的区别滚动条举例:/*- COLORS1.C - Colors Using Scroll Bars (c) Charles Petzold, 1998 -*/#include LRESULT CALLBACK WndProc (HWND

27、, UINT, WPARAM, LPARAM) ;LRESULT CALLBACK ScrollProc (HWND, UINT, WPARAM, LPARAM) ;int idFocus ;WNDPROC OldScroll3 ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) static TCHAR szAppName = TEXT (Colors1) ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndc

28、lass.style = CS_HREDRAW | CS_VREDRAW ; 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 = CreateSolidBrush

29、 (0) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass) MessageBox (NULL, TEXT (This program requires Windows NT!), szAppName, MB_ICONERROR) ; return 0 ; hwnd = CreateWindow (szAppName, TEXT (Color Scroll), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USED

30、EFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0) TranslateMessage (&msg) ; DispatchMessage (&msg) ; return msg.wParam ;LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM

31、 lParam) static COLORREF crPrim3 = RGB (255, 0, 0), RGB (0, 255, 0), RGB (0, 0, 255) ; static HBRUSH hBrush3, hBrushStatic ; static HWND hwndScroll3, hwndLabel3, hwndValue3, hwndRect ; static int color3, cyChar ; static RECT rcColor ; static TCHAR * szColorLabel = TEXT (Red), TEXT (Green), TEXT (Blu

32、e) ; HINSTANCE hInstance ; int i, cxClient, cyClient ; TCHAR szBuffer10 ; switch (message) case WM_CREATE : hInstance = (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE) ; / Create the white-rectangle window against which the / scroll bars will be positioned. The child window ID is 9. hwndRect = Creat

33、eWindow (TEXT (static), NULL, WS_CHILD | WS_VISIBLE | SS_WHITERECT, 0, 0, 0, 0, hwnd, (HMENU) 9, hInstance, NULL) ; for (i = 0 ; i 3 ; i+) / The three scroll bars have IDs 0, 1, and 2, with / scroll bar ranges from 0 through 255. hwndScrolli = CreateWindow (TEXT (scrollbar), NULL, WS_CHILD | WS_VISI

34、BLE | WS_TABSTOP | SBS_VERT, 0, 0, 0, 0, hwnd, (HMENU) i, hInstance, NULL) ; SetScrollRange (hwndScrolli, SB_CTL, 0, 255, FALSE) ; SetScrollPos (hwndScrolli, SB_CTL, 0, FALSE) ; / The three color-name labels have IDs 3, 4, and 5, / and text strings Red, Green, and Blue. hwndLabel i = CreateWindow (T

35、EXT (static), szColorLabeli, WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0, hwnd, (HMENU) (i + 3), hInstance, NULL) ; / The three color-value text fields have IDs 6, 7, / and 8, and initial text strings of 0. hwndValue i = CreateWindow (TEXT (static), TEXT (0), WS_CHILD | WS_VISIBLE | SS_CENTER, 0,

36、0, 0, 0, hwnd, (HMENU) (i + 6), hInstance, NULL) ; OldScrolli = (WNDPROC) SetWindowLong (hwndScrolli, GWL_WNDPROC, (LONG) ScrollProc) ; hBrushi = CreateSolidBrush (crPrimi) ; hBrushStatic = CreateSolidBrush ( GetSysColor (COLOR_BTNHIGHLIGHT) ; cyChar = HIWORD (GetDialogBaseUnits () ; return 0 ; case

37、 WM_SIZE : cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; SetRect (&rcColor, cxClient / 2, 0, cxClient, cyClient) ; MoveWindow (hwndRect, 0, 0, cxClient / 2, cyClient, TRUE) ; for (i = 0 ; i = 3 & i = 8) / static text controls SetTextColor (HDC) wParam, crPrimi % 3) ; SetBkColor (HDC) wPa

38、ram, GetSysColor (COLOR_BTNHIGHLIGHT); return (LRESULT) hBrushStatic ; break ; case WM_SYSCOLORCHANGE : DeleteObject (hBrushStatic) ; hBrushStatic = CreateSolidBrush (GetSysColor (COLOR_BTNHIGHLIGHT) ; return 0 ; case WM_DESTROY : DeleteObject (HBRUSH) SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG) G

39、etStockObject (WHITE_BRUSH) ; for (i = 0 ; i 3 ; i+) DeleteObject (hBrushi) ; DeleteObject (hBrushStatic) ; PostQuitMessage (0) ; return 0 ; return DefWindowProc (hwnd, message, wParam, lParam) ; LRESULT CALLBACK ScrollProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) int id = GetWindowLong (hwnd, GWL_ID) ; switch (message) case WM_KEYDOWN : if (wParam = VK_TAB) SetFocus (GetDlgItem (GetParent (hwnd), (id + (

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论