Pay attention to cbutton during re-painting)

Source: Internet
Author: User

Recently, when I made a checkbox transparent, I encountered a cbutton re-painting. There were many posts on the Internet about this problem and there were many implementation methods.

Here we will only talk about some problems and solutions I have encountered in actual operations.

1. When the wm_ctlcolor is reloaded in the form to achieve transparency, in some systems that use the XP style, the checkbox has a dark background color and does not really achieve the transparency effect, the specific reason is unclear. The Code is as follows:

Hbrush ctestdlg: onctlcolor (CDC * PDC, cwnd * pwnd, uint nctlcolor)
{
Hbrush HBr = cdialog: onctlcolor (PDC, pwnd, nctlcolor );
// Todo: change any attributes of the DC here
Switch (pwnd-> getdlgctrlid ()){
Case idc_check1:
PDC-> setbkmode (transparent );
PDC-> settextcolor (RGB (0, 0, 0 ));
HBr = (hbrush) getstockobject (null_brush );
Default:
Break;
}
// Todo: return a different brush if the default is not desired
Return HBr;
}

2. Use the subclass method to customize a class ccheckboxtrans and inherit from cbutton, and directly reload the wm_paint message processing function, in the dialog usage section, define the MFC member cbutton m_ocheck and replace it with ccheckboxtrans m_ocheck. The specific code is as follows:

Class ctestdlg: Public cdialog
{
Public:
Ctestdlg (cwnd * pparent = NULL );

// Dialog data
// {Afx_data (ctestdlg)
Enum {IDD = idd_test_dialog };
Ccheckboxtrans m_ocheck;
//} Afx_data

.....

Declare_message_map ()
};

Void ccheckboxtrans: onpaint ()
{
Cpaintdc DC (this); // device context for painting

// Todo: add your message handler code here

Crect rect;
Getclientrect (& rect );

Crect boxrect;
Boxrect = rect;
Boxrect. Right = boxrect. Left + 13;
DC. drawframecontrol (boxrect, dfc_button, dfcs_buttoncheck | (getcheck ()? Dfcs_checked: 0 ));
Cfont ofont;
Ofont. createfontindirect (& m_sfont );
Cbrush * poldbrush = (cbrush *) DC. SelectObject (hbrush) getstockobject (null_brush ));
Cfont * poldfont = (cfont *) DC. SelectObject (& ofont );
DC. setbkmode (transparent );

Cstring strwndtext;
Getwindowtext (strwndtext );

Rect. offsetrect (17, 0 );
DC. drawtext (strwndtext, & rect, dt_left | dt_vcenter | dt_singleline );

// Rect. offsetrect (-3, 0 );
// Rect. Right = 3 + strwndtext. getlength () * (getdevicecaps (DC. getsafehdc (), logpixelsy) * ABS (m_sfont.lfheight)/72 );
// If (getfocus ())
// Dc. drawfocusrect (& rect );

DC. SelectObject (poldfont );
// Dc. SelectObject (poldbrush );
Ofont. deleteobject ();
// Do not call cbutton: onpaint () for painting messages
}

This method basically meets the requirements, but I still found two problems:. when the checkbox is not focused, the highlighted dotted box is sometimes displayed. B. sometimes influenced by the style of the XP style, the font size will become much larger. It is different from other controls, and there will be text overlapping display. The specific reason is unclear. I hope you can give some advice.

3. Using the button of ownerdraw also inherits the cbutton class. However, this time, the onpaint function is not reloaded, but the virtual void drawitem (lpdrawitemstruct) that inherits the wm_drawitem message ); // note that it is not ondrawitem. Do not directly use the Class Wizard to reload wm_drawitem. These two functions are not one function. In addition, you need to reload virtual void presubclasswindow (). The specific code is as follows:

Class ccheckboxtrans: Public cbutton
{
// Construction
Public:
Ccheckboxtrans ();

// Attributes
Public:

// Operations
Public:

// Overrides
// Classwizard generated virtual function overrides
// {Afx_virtual (ccheckboxtrans)
Public:
Virtual void drawitem (lpdrawitemstruct );
Protected:
Virtual void presubclasswindow ();
//} Afx_virtual
......
Declare_message_map ()
};
Void ccheckboxtrans: presubclasswindow ()
{
// Todo: add your specialized code here and/or call the base class
Setbuttonstyle (getbuttonstyle () | bs_ownerdraw );
Cbutton: presubclasswindow ();
}
Void cxpbutton: drawitem (lpdrawitemstruct)
{
// Obtain control information from lpdrawitemstruct
Crect rect = lpdrawitemstruct-> rcitem;
CDC * PDC = CDC: fromhandle (lpdrawitemstruct-> HDC );
Int nsavedc = PDC-> savedc ();
Uint state = lpdrawitemstruct-> itemstate;
Point pt;
Tchar strtext [max_path + 1];
: Getwindowtext (m_hwnd, strtext, max_path );

// Obtain the button status
If (State & ods_focus ){
} Else {
}
If (State & ods_selected | State & ods_default ){
}


...... // Draw other widgets (omitted)

// Display the text of the button

If (strtext! = NULL)
{
Cfont * hfont = getfont ();
Cfont * holdfont = PDC-> SelectObject (hfont );
Csize szextent = PDC-> gettextextent (strtext, lstrlen (strtext ));
Cpoint Pt (rect. centerpoint (). X-szextent. CX/2, rect. centerpoint (). Y-szextent. cy/2 );
If (State & ods_selected)
PT. offset (1, 1 );
Int nmode = PDC-> setbkmode (transparent );
If (State & ods_disabled)
PDC-> drawstate (PT, szextent, strtext, dss_disabled, true, 0, (hbrush) null );
Else
PDC-> drawstate (PT, szextent, strtext, dss_normal, true, 0, (hbrush) null );
PDC-> SelectObject (holdfont );
PDC-> setbkmode (nmode );
}

PDC-> restoredc (nsavedc );
}

In addition, you also need to reload the mouse and keyboard-related messages. Otherwise, the control is drawn and the result cannot be used: (, pay attention to it.

Therefore, the subclass-based self-painting method can solve this problem, but it is better to directly set the image in cmfcbutton to save time and effort.

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.