首页 > 代码库 > [ATL/WTL]_[中级]_[原生的复选框(checkbox button)和单选按钮(radio button)实现透明背景效果解决方案]
[ATL/WTL]_[中级]_[原生的复选框(checkbox button)和单选按钮(radio button)实现透明背景效果解决方案]
场景:
1. mfc,wtl的原生控件都是通过父窗口拦截 WM_CTLCOLORSTATIC 事件来修改子控件的颜色和背景色,CStatic可以通过返回HOLLOW_BRUSH来绘制透明背景:
m_HollowBrush = AtlGetStockBrush(HOLLOW_BRUSH);
但是如果使用manifest文件使用最新 外观样式的话,返回HOLLOW_BRUSH对checkbox和radio button没有任何效果,原背景还是存在。虽然通过自绘一个checkbox和radio button 并不是什么难事,但是使用原生的button话在新系统(WIN8)下会得到一致的体验-- 使用最新的windows原生的样式或外观. 其实我的原则就是原生能做到的,就不需要重复造轮子.
” 邓学斌 “ 大牛也做过这方面的解释: http://blog.csdn.net/cometnet/article/details/38080449
最开始学习控件背景透明 参考的是 “吹泡泡的小猫” 的文章 创建有个性的对话框之ATL/WTL篇
但是这个demo也是出现我刚说的问题,就是radio button, checkbox 没效果.
解决方案:
1. 使用这个函数返回一个BITMAP BRUSH来绘制背景,注意并不是透明BRUSH.
CreatePatternBrush
但这样会产生一个问题,每个控件都需要一个特定区域的背景图片作为背景,如果界面上控件多的话为每个控件绘制背景这是一个浩大的工作量。所以这里我写了一个helper类帮我们做这些事情.
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; }
调用方式:
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)实现透明背景效果解决方案]
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。