场景:
1. mfc,wtl的原生控件都是通过父窗口拦截 WM_CTLCOLORSTATIC 事件来修改子控件的颜色和背景色,CStatic可以通过返回HOLLOW_BRUSH来绘制透明背景:
m_HollowBrush = AtlGetStockBrush(HOLLOW_BRUSH);
” 邓学斌 “ 大牛也做过这方面的解释: http://blog.csdn.net/cometnet/article/details/38080449
最开始学习控件背景透明 参考的是 “吹泡泡的小猫” 的文章 创建有个性的对话框之ATL/WTL篇
但是这个demo也是出现我刚说的问题,就是radio button, checkbox 没效果.
解决方案:
1. 使用这个函数返回一个BITMAP BRUSH来绘制背景,注意并不是透明BRUSH.
CreatePatternBrush
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
#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; }
调用方式:
1.在父控件Dialog里定义一个成员函数:
DhWindowBgBrushHelper brush_helper_;2. 在 初始化 OnInitDialog 里调用helper.
brush_helper_.AddSubWindow(GetDlgItem(1014),m_Bitmap); brush_helper_.AddSubWindow(GetDlgItem(1015),m_Bitmap);
3.同样的在onCtlColor处理函数里根据hWnd获取对应的BRUSH来绘制背景.
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; }
效果图, 这里是在“吹泡泡的小猫” 的原程序上改的效果:
程序下载地址:
http://download.csdn.net/detail/infoworld/7952165
[ATL/WTL]_[中级]_[原生的复选框(checkbox button)和单选按钮(radio button)实现透明背景效果解决方案]
原文地址:http://blog.csdn.net/infoworld/article/details/39451125