[ATL/WTL] _ [intermediate] _ [Native check box button and single-choice button to achieve transparent background effect solution], atlwtl
Scenario:
1. Native controls of mfc and wtl use the parent window to intercept the WM_CTLCOLORSTATIC event to modify the color and background color of the Child control. CStatic can draw a transparent background by returning HOLLOW_BRUSH:
m_HollowBrush = AtlGetStockBrush(HOLLOW_BRUSH);
However, if the manifest file is used to use the latest appearance style, the returned HOLLOW_BRUSH has no effect on the checkbox and radio buttons, and the original background still exists. Although it is not difficult to customize a checkbox and radio button, the native button is used in the new system (WIN8) you will get a consistent experience-use the latest windows native style or appearance. in fact, my principle is what native can do, and there is no need to duplicate the wheel.
"Deng xuebin" Daniel has done this interpretation: http://blog.csdn.net/cometnet/article/details/38080449
When I first learned the background transparency of the control, refer to the article "the kitten blowing bubbles" to create a personalized dialog box-ATL/WTL.
However, this demo is also a problem I just mentioned, that is, the radio button and checkbox are ineffective.
Solution:
1. Use this function to return a bitmap brush to draw the background. Note that it is not a transparent BRUSH.
CreatePatternBrush
However, this may cause a problem. Each control requires a background image of a specific area as the background. If there are many controls on the interface, it is a huge workload to draw a background for each control. So here I wrote a helper class to help us do these things.
Dh_window_bg_brush_helper.h
#ifndef __DH_WINDOW_BG_BRUSH_HELPER#define __DH_WINDOW_BG_BRUSH_HELPER#include <Windows.h>#include <map>class DhWindowBgBrushHelper{public:DhWindowBgBrushHelper();~DhWindowBgBrushHelper();void AddSubWindow(HWND hwnd,HBITMAP parent_background);HBRUSH GetHBRUSH(HWND hwnd);private:std::map<HWND,HBRUSH> hbrush;};#endif
Dh_window_bg_brush_helper.cpp
#include "stdafx.h"#include "dh_window_bg_brush_helper.h"DhWindowBgBrushHelper::DhWindowBgBrushHelper(){}DhWindowBgBrushHelper::~DhWindowBgBrushHelper(){std::map<HWND,HBRUSH>::iterator ite = hbrush.begin();for(; ite != hbrush.end(); ++ite) {ATLASSERT(ite->second != NULL);::DeleteObject(ite->second);}hbrush.clear();}void DhWindowBgBrushHelper::AddSubWindow(HWND hwnd,HBITMAP parent_background){CWindow child(hwnd);CWindow parent = child.GetParent();RECT rect;RECT parent_window_rect;RECT parent_client_rect;parent.GetWindowRect(&parent_window_rect);parent.GetClientRect(&parent_client_rect);child.GetWindowRect(&rect);parent.ScreenToClient(&rect);long width = rect.right - rect.left;long height = rect.bottom - rect.top;CDC sdc; CDC ddc;sdc.CreateCompatibleDC(NULL);ddc.CreateCompatibleDC(NULL);CBitmap destBmp;destBmp.CreateCompatibleBitmap(CClientDC(NULL),width,height);sdc.SelectBitmap(parent_background);ddc.SelectBitmap(destBmp);ddc.BitBlt(0, 0, width, height, sdc, rect.left, rect.top, SRCCOPY );CBrush bs ;bs.CreatePatternBrush(destBmp);hbrush[hwnd] = bs;bs.Detach();}HBRUSH DhWindowBgBrushHelper::GetHBRUSH(HWND hwnd){ATLASSERT(hwnd);if(hbrush.find(hwnd) != hbrush.end()){return hbrush[hwnd];}return NULL;}
Call method:
1. Define a member function in the parent control Dialog:
DhWindowBgBrushHelper brush_helper_;
2. Call helper in OnInitDialog initialization.
brush_helper_.AddSubWindow(GetDlgItem(1014),m_Bitmap);brush_helper_.AddSubWindow(GetDlgItem(1015),m_Bitmap);
3. Similarly, in the onCtlColor processing function, obtain the corresponding BRUSH Based on hWnd to draw the background.
LRESULT CBmpDlg::OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){HDC hDC = (HDC)wParam;HWND hWnd = (HWND)lParam;int style = GetStyle();if(uMsg == WM_CTLCOLORSTATIC){SetTextColor(hDC,t_crTextColor);SetBkMode(hDC,TRANSPARENT);bHandled = TRUE;HBRUSH brush = brush_helper_.GetHBRUSH(hWnd);if(brush){return (LRESULT)brush;}return (LRESULT)m_HollowBrush;}SetTextColor(hDC,t_crTextColor);SetBkMode(hDC,TRANSPARENT);return 0;}
Here is the effect changed in the original program of "the kitten blowing bubbles:
Program:
Http://download.csdn.net/detail/infoworld/7952165
Differences between the CheckBox control and the Radio Button control
Radio buttons are single-choice buttons (generally, only Radio buttons are used for men and women, such as gender), and CheckBox is multiple-choice Button (for example, you can have multiple interests and use CheckBox)
What is the difference between C # RadioButton and CheckBox?
The method you use is unreasonable. If 1st and 2nd are selected at the same time, the Code will only execute
If (this. checkBox1.Checked)
{
MessageBox. Show ("select one or two ");
This. checkBox2.CheckState = CheckState. Checked;
Return;
}
This is why the third option is not selected no matter how you click it.
Changed:
Private void button2_Click (object sender, System. EventArgs e)
{
If (this. checkBox1.Checked &&(! This. checkBox2.Checked ))
{
MessageBox. Show ("select one or two ");
This. checkBox2.CheckState = CheckState. Checked;
Return;
}
If (this. checkBox2.Checked (! This. checkBox3.Checked ))
// Else
{
MessageBox. Show ("select two, select three ");
This. checkBox3.CheckState = CheckState. Checked;
Return;
}
If (this. checkBox3.Checked)
{
MessageBox. Show ("Three select four ");
This. checkBox4.CheckState = CheckState. Checked;
Return;
}
This. checkBox1.CheckState = CheckState. Checked;
}