David的测试技术空间,收藏好文档和分享我的技术理解。5年的数通产品测试和安全产品测试经验,3年Web产品测试和多年测试管理和测试工具开发经验。目前关注性能分析调优、Jmeter和TestNG+WebDriver+Hamcrest的培训推广。Welcome沟通交流,请留言或者发邮件到daviwang_2004 at soguo.com。

Custom Controls

上一篇 / 下一篇  2007-08-18 11:02:16 / 个人分类:Windows

转贴:http://msdn2.microsoft.com/en-us/library/ms672580.aspx
 
Custom Controls

This section contains information about application-defined or custom controls.

The following topics are discussed.

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.

MessageRecommendation
WM_GETDLGCODEProcess 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_GETFONTProcess if theWM_SETFONTmessage is also processed.
WM_GETTEXTProcess if the control text is not the same as the title specified by theCreateWindowExfunction.
WM_GETTEXTLENGTHProcess if the control text is not the same as the title specified by theCreateWindowExfunction.
WM_KILLFOCUSProcess if the control displays a caret, a focus rectangle, or another item to indicate that it has the input focus.
WM_SETFOCUSProcess if the control displays a caret, a focus rectangle, or another item to indicate that it has the input focus.
WM_SETTEXTProcess if the control text is not the same as the title specified by theCreateWindowExfunction.
WM_SETFONTProcess 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 World Wide Web link.

Related Topics


TAG: Windows

 

评分:0

我来说两句

Open Toolbar