Custom Controls
上一篇 / 下一篇 2007-08-18 11:02:16 / 个人分类:Windows
This section contains information about application-defined or custom controls.
The following topics are discussed.
- Creating Owner-Drawn Controls
- Subclassing the Window Class of an Existing Control
- Implementing an Application-Defined Window Class
- Sending Notifications from a Control
- Accessibility
- Related Topics
Creating Owner-Drawn Controls
Buttons, menus, static text controls, list boxes, and combo boxes can be created with an owner-drawn style flag. When a control has the owner-drawn style, the system handles the user's interaction with the control as usual, performing such tasks as detecting when a user has chosen a button and notifying the button's owner of the event. However, because the control is owner-drawn, the parent window of the control is responsible for the visual appearance of the control. The parent window receives a message whenever the control must be drawn.
For buttons and static text controls, the owner-drawn style affects how the system draws the entire control. For list boxes and combo boxes, the parent window draws the items within the control, and the control draws its own outline. For example, an application can customize a list box so that it displays a small bitmap next to each item in the list.
The following example code shows how to create an owner-drawn static text control. Assume that Unicode is defined.
// g_myStatic is a global HWND variable. g_myStatic = CreateWindowEx(0, L"STATIC", L"Some static text", WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 25, 125, 150, 20, hDlg, 0, 0, 0);
In the following example, from the window procedure for the dialog box that contains the control created in the previous example, theWM_DRAWITEMmessage is handled by displaying the text in a custom color, using the default font. Note that you do not need to callBeginPaintandEndPaintwhen handlingWM_DRAWITEM.
case WM_DRAWITEM: { LPDRAWITEMSTRUCT pDIS = (LPDRAWITEMSTRUCT)lParam; if (pDIS->hwndItem == g_myStatic) { SetTextColor(pDIS->hDC, RGB(100, 0, 100)); WCHAR staticText[99]; int len = SendMessage(myStatic, WM_GETTEXT, ARRAYSIZE(staticText), (LPARAM)staticText); TextOut(pDIS->hDC, pDIS->rcItem.left, pDIS->rcItem.top, staticText, len); } return TRUE; }
For more information about owner-drawn controls, seeUsing Owner Drawn Buttons,Creating an Owner-drawn List Box, andOwner Drawn Combo Boxes.
Subclassing the Window Class of an Existing Control
Subclassing an existing control is another way to create a custom control. The subclass procedure can alter selected behavīors of the control by processing those messages that affect the selected behavīors. All other messages pass to the original window procedure for the control. For example, an application can display a small bitmap next to the text in a read-only, single-line edit control by subclassing the control and processing theWM_PAINTmessage. For more information, seeAbout Window ProceduresandSubclassing Controls.
Implementing an Application-Defined Window Class
To create a control that is not explicitly based on an existing control, the application must create and register a window class. The process for registering an application-defined window class for a custom control is the same as registering a class for an ordinary window. To create a custom control, specify the name of the window class in theCreateWindowExfunction or in a dialog box template. Each class must have a unique name, a corresponding window procedure, and other information.
At a minimum, the window procedure draws the control. If an application uses the control to let the user type information, the window procedure also processes input messages from the keyboard and mouse and sends notification messages to the parent window. In addition, if the control supports control messages, the window procedure processes messages sent to it by the parent window or other windows. For example, controls often process theWM_GETDLGCODEmessage sent by dialog boxes to direct a dialog box to process keyboard input in a given way.
The window procedure for an application-defined control should process any predefined control message in the following table if the message affects the operation of the control.
Message | Recommendation |
---|---|
WM_GETDLGCODE | Process if the control uses the ENTER, ESC, TAB, or arrow keys. TheIsDialogMessagefunction sends this message to controls in a dialog box to determine whether to process the keys or pass them to the control. |
WM_GETFONT | Process if theWM_SETFONTmessage is also processed. |
WM_GETTEXT | Process if the control text is not the same as the title specified by theCreateWindowExfunction. |
WM_GETTEXTLENGTH | Process if the control text is not the same as the title specified by theCreateWindowExfunction. |
WM_KILLFOCUS | Process if the control displays a caret, a focus rectangle, or another item to indicate that it has the input focus. |
WM_SETFOCUS | Process if the control displays a caret, a focus rectangle, or another item to indicate that it has the input focus. |
WM_SETTEXT | Process if the control text is not the same as the title specified by theCreateWindowExfunction. |
WM_SETFONT | Process if the control displays text. The system sends this message when creating a dialog box that has the DS_SETFONT style. |
Application-defined control messages are specific to the given control and must be explicitly sent to the control by using aSendMessageorSendDlgItemMessagefunction. The numeric value for each message must be unique and must not conflict with the values of other window messages. To ensure that application-defined message values do not conflict, an application should create each value by adding a unique number to theWM_USERvalue.
Sending Notifications from a Control
Custom controls might be required to send notifications of events to the parent window so that the host application can respond to these events. For example, a custom list view might send a notification when the user selects an item, and another notification when an item is double-clicked.
Notifications are sent asWM_COMMANDorWM_NOTIFYmessages.WM_NOTIFYmessages carry more information thanWM_COMMANDmessages.
The control identifier is a unique number the application uses to identify the control sending the message. The application sets the identifier for a control when it creates the control. The application specifies the identifier either in thehMenuparameter of theCreateWindowExfunction or in theidmember of theDLGITEMTEMPLATEEXstructure.
Because the control itself does not set the control identifier, the control must retrieve the identifier before it can send notification messages. A control must use theGetDlgCtrlIDfunction to retrieve its own control identifier. Although the control identifier is specified as the menu handle when the control is created, theGetMenufunction cannot be used to retrieve the identifier. Alternatively, a control can retrieve the identifier from thehMenumember in theCREATESTRUCTstructure while processing theWM_CREATEmessage.
The following examples, wherehwndControlis the handle of the control window and CN_VALUECHANGED is a custom notification definition, show the two ways of sending a control-specific notification.
// Send as WM_COMMAND. SendMessage(GetParent(hwndControl), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwndControl), CN_VALUECHANGED), (LPARAM)hwndControl); // Send as WM_NOTIFY. NMHDR nmh; nmh.code = CN_VALUECHANGED; nmh.idFrom = GetDlgCtrlID(hwndControl); nmh.hwndFrom = hwndControl; SendMessage(GetParent(hwndControl), WM_NOTIFY, (WPARAM)hwndControl, (LPARAM)&nmh);
Note that theNMHDRstructure can be part of a larger control-defined structure that contains additional information. In the example, the old and new values of the control might be contained in this structure. (Such extended structures are used with many standard notifications; for example, seeLVN_INSERTITEM, which uses theNMLISTVIEWstructure.)
Accessibility
All the common controls support Microsoft Active Accessibility (MSAA), which enables programmatic access by accessible-technology applications such as screen-readers. MSAA also enables UI Automation, a newer technology, to interact with controls.
Custom controls should implement either theIAccessibleinterface (to support MSAA) or the UI Automation interfaces, or both. Otherwise, accessible-technology products will be able to obtain only very limited information about the control window, will not have access to the control's properties, and will be unable to trigger events in the control.
For more information about making your control accessible, seeAccessibility .
Related Topics
相关阅读:
- 2007-03-07 | windows2000/xp启动过程详解【转】 (caicai1724, 2007-4-27)
- 2007-04-13 | WINDOWS操作系统【转】 (caicai1724, 2007-4-27)
- 电脑蓝屏死机代码大集合(转) (87117899, 2007-5-17)
- 使用WMTF进行Windows Mobile程序的自动化测试 (yuxiao, 2007-8-01)
- Windows SDK:在窗口上建立控件 (davidwang_2004, 2007-8-18)
- Windows Controls (davidwang_2004, 2007-8-18)
TAG: Windows
标题搜索
日历
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
1 | 2 | 3 | 4 | ||||||
5 | 6 | 7 | 8 | 9 | 10 | 11 | |||
12 | 13 | 14 | 15 | 16 | 17 | 18 | |||
19 | 20 | 21 | 22 | 23 | 24 | 25 | |||
26 | 27 | 28 | 29 | 30 | 31 |
我的存档
数据统计
- 访问量: 248923
- 日志数: 137
- 建立时间: 2007-08-14
- 更新时间: 2010-05-25