Msdn-Message reflection for Windows controls

Source: Internet
Author: User
Tn062: Message reflection for Windows controls

 

Note

The following technical note has not been updated since it was first defined ded in the online documentation. as a result, some procedures and topics might be out of date or incorrect. for the latest information, it is recommended that you search for the topic of interest in the online documentation index.

This technical note describes message reflection, a new feature in MFC 4.0. It also contains ctions for creating a simple reusable control that uses Message reflection.

This technical note does not discuss message reflection as it applies to ActiveX Controls (formerly called Ole controls). Please see the articleActiveX Controls: subclassing a Windows Control.

What Is Message reflection?

Windows controls frequently send notification messages to their parent windows. For instance, your controls send a control color notification message (Wm_ctlcolorOr one of its variants) to their parent to allow the parent to supply a brush for painting the background of the control.

In Windows and in MFC Before Version 4.0, the parent window, often a dialog box, is responsible for handling these messages. this means that the code for handling the message needs to be in the parent window's class and that it has to be duplicated in every class that needs to handle that message. in the case abve, every dialog box that wanted controls with custom backgrounds wowould have to handle the control color notification message. it wocould be much easier to reuse code if a control class cocould be written that wocould handle its own background color.

In MFC 4.0, the old mechanic still works-parent windows can handle notification messages. in addition, however, MFC 4.0 facilitates reuse by providing a feature called "Message reflection" that allows these notification messages to be handled in either the child control window or the parent window, or in both. in the control background color example, you can now write a control class that sets its own background color by handling the reflectedWm_ctlcolorMessage-all without relying on the parent. (Note that since Message reflection is implemented by MFC, not by windows, the parent window class must be derived fromCwndFor Message reflection to work .)

Older versions of MFC did something similar to message reflection by providing virtual functions for a few messages, such as messages for owner-drawn list boxes (Wm_drawitem, And so on). The new message reflection mechanic is generalized and consistent.

Message reflection is backward compatible with code written for versions of MFC before 4.0.

If you have supplied a handler for a specific message, or for a range of messages, in your parent window's class, it will override reflected message handlers for the same message provided you don't call the base class handler function in your own handler. for example, if you handleWm_ctlcolorIn your dialog box class, your handling will override any reflected message handlers.

if, in your parent window class, you supply a handler for a specific wm_notify message or a range of wm_notify messages, your handler will be called only if the child control sending those messages does not have a reflected message handler through on_policy_reflect () . if you use on_policy_reflect_ex () in your message map, your message handler may or may not allow the parent window to handle the message. if the handler returns false , the message will be handled by the parent as well, while a call that returns true does not allow the parent to handle it. note that the reflected message is handled before the notification message.

when a wm_policy message is sent, the control is offered the first chance to handle it. if any other reflected message is sent, the parent window has the first chance to handle it and the control will receive the reflected message. to do so, it will need a handler function and an appropriate entry in the control's class message map.

The message-map macro for reflected messages is slightly different than for regular notifications: it has_ ReflectAppended to its usual name. For instance, to handleWm_notifyMessage in the parent, you use the macroOn_policyIn the parent's message map. To handle the reflected message in the Child control, useOn_policy_reflectMacro in the Child control's message map. in some cases, the parameters are different, as well. note that classwizard can be usually add the message-map entries for you and provide skeleton function implementations with correct parameters.

SeeTn061: on_policy and wm_policy messagesFor information on the newWm_notifyMessage.

Message-map entries and handler function prototypes for reflected messages

To handle a reflected control notification message, use the message-map macros and function prototypes listed in the table below.

Classwizard can usually add these message-map entries for you and provide skeleton function implementations. SeeDefining a message handler for a reflected messageFor information about how to define handlers for reflected messages.

To convert from the message name to the reflected macro name, prependOn _And append_ Reflect. For example,Wm_ctlcolorBecomesOn_wm_ctlcolor_reflect. (To see which messages can be reflected, do the opposite conversion on the macro entries in the table below .)

The three exceptions to the rule above are as follows:

    • The macroWm_commandCommunications isOn_control_reflect.

    • The macroWm_notifyReflections isOn_policy_reflect.

    • The macroOn_update_command_uiReflections isOn_update_command_ui_reflect.

In each of the above special cases, you must specify the name of the handler member function. In the other cases, you must use the standard name for your handler function.

The meanings of the parameters and return values of the functions are supported ented under either the function name or the function nameOnPrepended. For instance,CtlcolorIs already ented inOnctlcolor. Several reflected message handlers need fewer parameters than the similar handlers in a parent window. Just match the names in the table below with the names of the formal parameters in the documentation.

 
Map entry Function prototype

On_control_reflect (Wnotifycode ,Memberfxn )

Afx_msg voidMemberfxn ();

On_policy_reflect (Wnotifycode ,Memberfxn )

Afx_msg voidMemberfxn (Nmhdr *Pnotifystruct , Lresult *Result );

On_update_command_ui_reflect (Memberfxn )

Afx_msg voidMemberfxn (Ccmdui *Pcmdui );

On_wm_ctlcolor_reflect ()

Afx_msg hbrush ctlcolor (CDC *PDC , UintNctlcolor );

On_wm_drawitem_reflect ()

Afx_msg void drawitem (lpdrawitemstructLpdrawitemstruct );

On_wm_measureitem_reflect ()

Afx_msg void measureitem (lpmeasureitemstructLpmeasureitemstruct );

On_wm_deleteitem_reflect ()

Afx_msg void deleteitem (lpdeleteitemstructLpdeleteitemstruct );

On_wm_compareitem_reflect ()

Afx_msg int compareitem (lpcompareitemstructLpcompareitemstruct );

On_wm_chartoitem_reflect ()

Afx_msg int chartoitem (uintNkey , UintNindex );

On_wm_vkeytoitem_reflect ()

Afx_msg int vkeytoitem (uintNkey , UintNindex );

On_wm_hscroll_reflect ()

Afx_msg void hscroll (uintNsbcode , UintNPOs );

On_wm_vscroll_reflect ()

Afx_msg void vscroll (uintNsbcode , UintNPOs );

On_wm_parentpolicy_reflect ()

Afx_msg void parentnotify (uintMessage , LparamLparam );

TheOn_policy_reflectAndOn_control_reflectMacros have variations that allow more than one object (such as the control and its parent) to handle a given message.

 
Map entry Function prototype

On_policy_reflect_ex (Wnotifycode ,Memberfxn )

Afx_msg boolMemberfxn (Nmhdr *Pnotifystruct , Lresult *Result );

On_control_reflect_ex (Wnotifycode ,Memberfxn )

Afx_msg boolMemberfxn ();

Handling reflected messages: An example of a reusable Control

This simple example creates a reusable control calledCyellowedit. The control works the same as a regular edit control doesn't that it displays black text on a yellow background. It wocould be easy to add member functions that wocould allowCyelloweditControl to display different colors.

To try the example that creates a reusable Control
  1. Create a new dialog box in an existing application. For more information, seeDialog EditorTopic.

    You must have an application in which to develop the reusable control. If you don't have an existing application to use, create a dialog-based application using Appwizard.

  2. With your project loaded into visual C ++, use classwizard to create a new class calledCyelloweditBased onCedit.

  3. Add three member variables to yourCyelloweditClass. The first two will beColorrefVariables to hold the text color and the background color. The third will beCbrushObject that will hold the brush for painting the background.CbrushObject allows you to create the brush once, merely referencing it after that, and to destroy the brush automatically whenCyelloweditControl is destroyed.

  4. Initialize the member variables by writing the constructor as follows:

    Copy
    Cyellowedit: cyellowedit () {m_clrtext = RGB (0, 0, 0); m_clrbkgnd = RGB (255,255, 0); m_brbkgnd.createsolidbrush (m_clrbkgnd );}
  5. using classwizard, add a handler for the reflected wm_ctlcolor message to your cyellowedit class. note that the equal sign in front of the message name in the list of messages you can handle indicates that the message is reflected. this is described in defining a message handler for a reflected message .

    classwizard adds the following message-map macro and skeleton function for you:

    copy
     on_wm_ctlcolor_reflect () // Note: Other code will be in .... hbrush cyellowedit: ctlcolor (CDC * PDC, uint nctlcolor) {// todo: change any attributes of the DC here // todo: return a non-null brush if the // parent's handler shocould not be called return NULL;} 
  6. Replace the body of the function with the following code. The Code specifies the text color, the text background color, and the background color for rest of the control.

    Copy
    PDC-> settextcolor (m_clrtext); // text PDC-> setbkcolor (m_clrbkgnd); // text bkgnd return m_brbkgnd; // CTL bkgnd
  7. Create an edit control in your dialog box, then attach it to a member variable by double-clicking the edit control while holding a control key down. in the Add member variable dialog box, finish the variable name and choose "control" for the category, then "cyellowedit" for the variable type. don't forget to set the tab order in the dialog box. also, be sure to include the header file forCyelloweditControl in your dialog box's header file.

  8. Build and run your application. The edit control will have a yellow background.

See also

Other resources

Technical notes by number
Technical notes by category

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.