Colorbutton Based on cmfccolorbutton

Source: Internet
Author: User

BCG is a very good interface library, the best choice for the traditional interface of MFC. Most of his controls are quite good, but in some details, it seems that xtremetoolkit is a little better, such as the color selection button, directory selection button...

The color button, which is named cmfccolorbutton after being absorbed by Microsoft, maintains the style of the previous drop-down list. I personally do not like it. I still think that the xtremetoolkit is more similar to the button to make it more suitable for me. However, xtremetoolkit has to pay for it. Since cmfccolorbutton exists, let's extend it to meet our requirements.

Let's take a look:

 

This is the normal result:

 

When you click

 

On the left is the standard cmfccolorbutton, and on the right is the new class that I expanded myself.

 

Let's talk about the implementation method and discuss it with you:

1. By default, cmfccolorbutton reloads the ondraw and ondrawborder of the base class cmfcbutton:

Virtual void ondraw (CDC * PDC, const crect & rect, uint uistate); </P> <p> virtual void ondrawborder (CDC * PDC, crect & rectclient, uint uistate ); <br/>

The pop-up Color panel is cmfccolorpopupmenu, Which is dynamically created whenever triggered.

The main draw code is implemented in ondraw. ondrawborder is only responsible for drawing the focus area, that is, the dotted box when the focus is obtained.

The key thing is to draw the arrow and vertical line:

 

Crect rectarrow = rect; <br/> rectarrow. left = rectcolor. right + nimagehorzmargin/2; </P> <p> // ------------ <br/> // draw Arrow: <br/> // ------------ <br/> cmenuimages :: draw (PDC, m_blargearrow? Cmenuimages: idarrowdownlarge: cmenuimages: idarrowdown, rectarrow, (uistate & ods_disabled )? Cmenuimages: imagegray: cmenuimages: imageblack); </P> <p> // -------------- <br/> // draw separator: <br/> // ---------------- <br/> crect rectseparator = rectarrow; <br/> rectseparator. right = rectseparator. left + 2; <br/> rectseparator. deflaterect (0, 2); </P> <p> If (! M_bwinxptheme | m_bdontusewinxptheme) <br/>{< br/> rectseparator. left + = m_sizepushoffset.cx; <br/> rectseparator. top + = m_sizepushoffset.cy; <br/>}</P> <p> PDC-> draw3drect (rectseparator, afxglobaldata. clrbtndkshadow, afxglobaldata. clrbtnhilite); </P> <p>

 

2. After this change, it looks good if you do not click the button. However, when you click the button, the default button is not pressed, both cbutton and cmfcbutton have this effect. Therefore, the onlbuttondown response calls cmfcbutton before the base-class cmfccolorbutton responds, so that the button is pressed down.

 

3. The pressure-down effect is met, but the problem arises. When the button is clicked, the color panel pops up smoothly. At this time, the button remains pressed, when we choose to move the mouse to another place without selecting any color, we only close the Color panel. The press status does not return to normal. What should I do? As mentioned above, cmfccolorpopupmenu is dynamically created. When it is disabled, the pointer of this object is destroyed. In the pop-up, the virtual function onshowcolorpopup will be called. Unfortunately, when it is closed, it does not send any messages to our parent window, that is, the base class cmfccolorbutton here, so what we need to do is reload him.

Virtual void onshowcolorpopup ();

What is heavy load? Hook him! The wm_close message is intercepted and a wm_lbuttonup message is sent to the derived button. In this way, the button pops up and the problem is solved.

 

4. The last question is that it is okay to click the button. The press and restore statuses are also quite good. But what about the shortcut keys? Cmfccolorbutton of the base class only supports space keys and downward arrow keys to open the Color Selection Panel. We can add an upward arrow key to close the Color panel. If the panel is displayed at this time. The code here is simple:

Void cxcolorbutton: onkeydown (uint nchar, uint nrepcnt, uint nflags) <br/>{< br/> switch (nchar) <br/>{< br/> case vk_space: <br/> case vk_down: <br/> postmessage (wm_lbuttondown); <br/> return; <br/> case vk_up: <br/> If (m_ppopup! = NULL & m_ppopup-> getsafehwnd ()! = NULL) <br/>{< br/> m_ppopup-> sendmessage (wm_close); <br/> m_ppopup = NULL; <br/>}< br/> return; <br/> default: <br/> break; <br/>}</P> <p> cmfcbutton: onkeydown (nchar, nrepcnt, nflags ); <br/>}< br/>

Here m_ppopup is the pointer of the Color Selection Panel cmfccolorpopupmenu.

 

So far, all problems have been solved, and the results are almost perfect.

 

Note: When it comes to hook messages, we have to thank PJ naughter. His chookwnd frees programer from the tedious getwindowlong and setwindowlong, just subclass hookwnd. Of course, this is not to say that it applies well. I have extended it myself. The core idea is to access different classes through a cobject pointer. If we declare cxxxhooker as a friend class, for example, in this example, we declare cxxxhooker as the friend class of the cxcolorbutton that we subclass, then we will be more comfortable with whatever we want.

 

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.