一个透明的CStatic控件【原创】 如果我们自画了一个有背景的对话框,static控件在上面不透明是很不爽的。 改进方法很简单,从MFC的CStatic派生一个类,下面是相应的代码: (使用的时候修改控件ID为其他值,不要是IDC_STATIC,否则不能添加用于ddx的变量)
//========================================================= // // Copyright (c) 2000-2004 iWise Technologies,Co. Ltd. // All Rights Reserved. // // Class: CTransparentStatic // // Product: iW988 // File : TransparentStatic.h // Author : 天衣有缝 // Created: 2004.12.29 23:40 // // Description: // ValueAdded main program for iW988. // Contact:ShenZhen @ GuangDong // [email protected] // //========================================================= #pragma once // CTransparentStatic
class CTransparentStatic : public CStatic { DECLARE_DYNAMIC(CTransparentStatic)
public: CTransparentStatic(); virtual ~CTransparentStatic();
protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnPaint(); };
//========================================================= // // Copyright (c) 2000-2004 iWise Technologies,Co. Ltd. // All Rights Reserved. // // Class: CTransparentStatic // // Product: iW988 // File : TransparentStatic.cpp // Author : 天衣有缝 // Created: 2004.12.29 23:40 // // Description: // ValueAdded main program for iW988. // Contact:ShenZhen @ GuangDong // [email protected] // //========================================================= // TransparentStatic.cpp : implementation file //
#include "stdafx.h" #include "TransparentStatic.h"
// CTransparentStatic
IMPLEMENT_DYNAMIC(CTransparentStatic, CStatic) CTransparentStatic::CTransparentStatic() { }
CTransparentStatic::~CTransparentStatic() { }
BEGIN_MESSAGE_MAP(CTransparentStatic, CStatic) ON_WM_PAINT() END_MESSAGE_MAP()
// CTransparentStatic message handlers
void CTransparentStatic::OnPaint() { CPaintDC dc(this); // 控件的设备文件
// 取得位置 CRect client_rect; GetClientRect(client_rect);
// 取得文本 CString szText; GetWindowText(szText);
// 取得字体,并选入设备文件 CFont *pFont, *pOldFont; pFont = GetFont(); pOldFont = dc.SelectObject(pFont);
// 用透明背景填充设备文件 dc.SetBkMode(TRANSPARENT);
// 显示文字 dc.DrawText(szText, client_rect, 0);
// 清除字体 dc.SelectObject(pOldFont);
} 转载请注意: 下面的背景对话框是从CButtonST整理二来,版权属于:Davide Calabro' [email protected]
//=========================================================//// Copyright (c) 2000-2004 iWise Technologies,Co. Ltd.// All Rights Reserved.//// Class: CBkDialogST//// Product: iW988// File : BkDialogST.h// Author : 天衣有缝// Created: 2004.12.29 23:50// // Description:// ValueAdded main program for iW988.// Contact:ShenZhen @ GuangDong// [email protected]////========================================================= #pragma once
class CBkDialogST : public CDialog { public: CBkDialogST(CWnd* pParent = NULL); // 标准构造函数 CBkDialogST(UINT uResourceID, CWnd* pParent = NULL); CBkDialogST(LPCTSTR pszResourceID, CWnd* pParent = NULL); virtual ~CBkDialogST(); // 析构
DWORD SetMode(BYTE byMode, BOOL bRepaint = TRUE); // 设置背景位图显示模式
DWORD SetBitmap(HBITMAP hBitmap); // 设置背景位图 DWORD SetBitmap(int nBitmap); // 设置背景位图
DWORD ActivateEasyMoveMode(BOOL bActivate); // 客户区可以随意拖动 DWORD ShrinkToFit(BOOL bRepaint = TRUE); // 使对话框只显示一个背景位图大小,左上角位置不变
enum { // 背景位图显示模式 BKDLGST_MODE_TILE , // 平铺 BKDLGST_MODE_CENTER , // 居中 BKDLGST_MODE_STRETCH , // 拉伸 BKDLGST_MODE_TILETOP , // 只平铺一行,top BKDLGST_MODE_TILEBOTTOM , // 只平铺一行,bottom BKDLGST_MODE_TILELEFT , // 只平铺一列,left BKDLGST_MODE_TILERIGHT , // 只平铺一列,right BKDLGST_MODE_TOPLEFT , // 只显示一图:top left BKDLGST_MODE_TOPRIGHT , // 只显示一图:top right BKDLGST_MODE_TOPCENTER , // 只显示一图:top center BKDLGST_MODE_BOTTOMLEFT , // 只显示一图:bottom left BKDLGST_MODE_BOTTOMRIGHT, // 只显示一图:bottom right BKDLGST_MODE_BOTTOMCENTER, // 只显示一图:bottom center
BKDLGST_MAX_MODES };
enum { BKDLGST_OK , // 函数设置成功 BKDLGST_INVALIDRESOURCE , // 无效的位图资源 BKDLGST_INVALIDMODE // 无效的显示模式 };
protected: //{{AFX_MSG(CBkDialogST) afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnSize(UINT nType, int cx, int cy); //}}AFX_MSG virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 virtual void OnPostEraseBkgnd(CDC* pDC); // 扩展功能 afx_msg void OnLButtonDown(UINT nFlags, CPoint point); // 支持鼠标拖动对话框
static short GetVersionI() {return 11;} // 程序版本 static LPCTSTR GetVersionC() {return (LPCTSTR)_T("1.1");}// 程序版本
private: void Init(); void FreeResources(BOOL bCheckForNULL = TRUE);
HBITMAP m_hBitmap ; // 位图句柄Handle to bitmap DWORD m_dwWidth ; // 位图宽度 DWORD m_dwHeight ; // 位图高度 BYTE m_byMode ; // 当前显示模式 BOOL m_bEasyMoveMode ; // 是否可用鼠标拖动对话框
DECLARE_MESSAGE_MAP() }; //=========================================================//// Copyright (c) 2000-2004 iWise Technologies,Co. Ltd.// All Rights Reserved.//// Class: CBkDialogST//// Product: iW988// File : BkDialogST.cpp// Author : 天衣有缝// Created: 2004.12.29 23:50// // Description:// ValueAdded main program for iW988.// Contact:ShenZhen @ GuangDong// [email protected]////========================================================= #include "stdafx.h" #include "BkDialogST.h"
CBkDialogST::CBkDialogST(CWnd* pParent /*=NULL*/) { Init(); }
CBkDialogST::CBkDialogST(UINT uResourceID, CWnd* pParent) : CDialog(uResourceID, pParent) { Init(); }
CBkDialogST::CBkDialogST(LPCTSTR pszResourceID, CWnd* pParent) : CDialog(pszResourceID, pParent) { Init(); }
CBkDialogST::~CBkDialogST() { FreeResources(); }
void CBkDialogST::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); }
BEGIN_MESSAGE_MAP(CBkDialogST, CDialog) ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_LBUTTONDOWN() END_MESSAGE_MAP()
void CBkDialogST::Init() { FreeResources(FALSE);
// 默认的位图显示模式 m_byMode = BKDLGST_MODE_TILE;
// 客户区可以随意拖动窗口 m_bEasyMoveMode = TRUE; }
void CBkDialogST::FreeResources(BOOL bCheckForNULL) { // 卸载资源 if (bCheckForNULL == TRUE) { if (m_hBitmap) ::DeleteObject(m_hBitmap); }
m_hBitmap = NULL; m_dwWidth = 0; m_dwHeight = 0; }
void CBkDialogST::OnLButtonDown(UINT nFlags, CPoint point) { // 客户区可以随意拖动窗口 if (m_bEasyMoveMode == TRUE) PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y)); CDialog::OnLButtonDown(nFlags, point); }
DWORD CBkDialogST::ActivateEasyMoveMode(BOOL bActivate) { // 设置是否可以随意拖动窗口 m_bEasyMoveMode = bActivate; return BKDLGST_OK; }
DWORD CBkDialogST::SetBitmap(int nBitmap) { HBITMAP hBitmap = NULL; HINSTANCE hInstResource = NULL;
// 找到位图资源的句柄 hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmap), RT_BITMAP);
// 加载位图 hBitmap = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmap), IMAGE_BITMAP, 0, 0, 0);
return SetBitmap(hBitmap); // 调用下面的函数 }
DWORD CBkDialogST::SetBitmap(HBITMAP hBitmap) { int nRetValue; BITMAP csBitmapSize;
// 卸载资源 FreeResources();
if (hBitmap) { m_hBitmap = hBitmap;
// 取得位图信息 nRetValue = ::GetObject(hBitmap, sizeof(csBitmapSize), &csBitmapSize); if (nRetValue == 0) { // 无效的位图句柄 FreeResources(); return BKDLGST_INVALIDRESOURCE; } m_dwWidth = (DWORD)csBitmapSize.bmWidth; // 位图宽度 m_dwHeight = (DWORD)csBitmapSize.bmHeight; // 位图高度 }
Invalidate();
return BKDLGST_OK; }
DWORD CBkDialogST::SetMode(BYTE byMode, BOOL bRepaint) { if (byMode >= BKDLGST_MAX_MODES) return BKDLGST_INVALIDMODE;
// 设置位图显示模式 m_byMode = byMode;
if (bRepaint == TRUE) Invalidate();
return BKDLGST_OK; }
DWORD CBkDialogST::ShrinkToFit(BOOL bRepaint) { // 使对话框只显示一个背景位图大小,左上角位置不变 CRect rWnd; CRect rClient; DWORD dwDiffCX; DWORD dwDiffCY;
::GetWindowRect(m_hWnd, &rWnd); // 相对于屏幕的位置 ::GetClientRect(m_hWnd, &rClient); // 客户区相对于对话框左上角的位置
dwDiffCX = rWnd.Width() - rClient.Width(); // 左右边框线宽度之和 dwDiffCY = rWnd.Height() - rClient.Height(); // 对话框标题兰和下边框宽度之和
m_byMode = BKDLGST_MODE_CENTER; // 显示模式为居中一副图
// 计算边框大小,再移动之,使客户区只显示一个位图大小 MoveWindow(rWnd.left, rWnd.top, dwDiffCX + m_dwWidth, dwDiffCY + m_dwHeight, bRepaint);
return BKDLGST_OK; }
void CBkDialogST::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy);
// 如果有位图资源则重画 if (m_hBitmap != NULL) { Invalidate(); } }
void CBkDialogST::OnPostEraseBkgnd(CDC* pDC) { // 留作扩展用 }
BOOL CBkDialogST::OnEraseBkgnd(CDC* pDC) { CRect rWnd; int nX = 0; int nY = 0;
BOOL bRetValue = CDialog::OnEraseBkgnd(pDC);
// 位图加载时才执行重画背景 if (m_hBitmap) { GetClientRect(rWnd); // 客户区位置,相对于对话框左上角
CDC dcMemoryDC; // 目标图形设备 CBitmap bmpMemoryBitmap; // 上面设备的位图 CBitmap* pbmpOldMemoryBitmap = NULL;
dcMemoryDC.CreateCompatibleDC(pDC); // 创建与设备文件兼容的内存图形设备 bmpMemoryBitmap.CreateCompatibleBitmap(pDC, rWnd.Width(), rWnd.Height()); // 用内存图形设备初始化这个内存位图 pbmpOldMemoryBitmap = (CBitmap*)dcMemoryDC.SelectObject(&bmpMemoryBitmap); // 内存图形设备中选入这个位图 dcMemoryDC.FillSolidRect(rWnd, pDC->GetBkColor()); // 填充背景色
CDC dcTempDC; // 源图形设备,位图先选入之 HBITMAP hbmpOldTempBitmap = NULL; dcTempDC.CreateCompatibleDC(pDC); hbmpOldTempBitmap = (HBITMAP)::SelectObject(dcTempDC.m_hDC, m_hBitmap);
switch (m_byMode) { case BKDLGST_MODE_TILE: // 平铺位图 while (nY < rWnd.Height()) { while(nX < rWnd.Width()) { dcMemoryDC.BitBlt(nX, nY, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); nX += m_dwWidth; } nX = 0; nY += m_dwHeight; } break; case BKDLGST_MODE_CENTER: nX = ((rWnd.Width() - m_dwWidth)/2); nY = ((rWnd.Height() - m_dwHeight)/2); dcMemoryDC.BitBlt(nX, nY, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); break; case BKDLGST_MODE_STRETCH: // 拉伸位图 dcMemoryDC.StretchBlt(0, 0, rWnd.Width(), rWnd.Height(), &dcTempDC, 0, 0, m_dwWidth, m_dwHeight, SRCCOPY); break; case BKDLGST_MODE_TILETOP: while(nX < rWnd.Width()) { dcMemoryDC.BitBlt(nX, 0, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); nX += m_dwWidth; } break; case BKDLGST_MODE_TILEBOTTOM: while(nX < rWnd.Width()) { dcMemoryDC.BitBlt(nX, rWnd.bottom - m_dwHeight, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); nX += m_dwWidth; } break; case BKDLGST_MODE_TILELEFT: while (nY < rWnd.Height()) { dcMemoryDC.BitBlt(0, nY, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); nY += m_dwHeight; } break; case BKDLGST_MODE_TILERIGHT: while (nY < rWnd.Height()) { dcMemoryDC.BitBlt(rWnd.right - m_dwWidth, nY, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); nY += m_dwHeight; } break; case BKDLGST_MODE_TOPLEFT: dcMemoryDC.BitBlt(0, 0, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); break; case BKDLGST_MODE_TOPRIGHT: dcMemoryDC.BitBlt(rWnd.right - m_dwWidth, 0, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); break; case BKDLGST_MODE_TOPCENTER: nX = ((rWnd.Width() - m_dwWidth)/2); dcMemoryDC.BitBlt(nX, 0, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); break; case BKDLGST_MODE_BOTTOMLEFT: dcMemoryDC.BitBlt(0, rWnd.bottom - m_dwHeight, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); break; case BKDLGST_MODE_BOTTOMRIGHT: dcMemoryDC.BitBlt(rWnd.right - m_dwWidth, rWnd.bottom - m_dwHeight, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); break; case BKDLGST_MODE_BOTTOMCENTER: nX = ((rWnd.Width() - m_dwWidth)/2); dcMemoryDC.BitBlt(nX, rWnd.bottom - m_dwHeight, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY); break; }
pDC->BitBlt(0, 0, rWnd.Width(), rWnd.Height(), &dcMemoryDC, 0, 0, SRCCOPY);
OnPostEraseBkgnd(&dcMemoryDC);
::SelectObject(dcTempDC.m_hDC, hbmpOldTempBitmap); dcMemoryDC.SelectObject(pbmpOldMemoryBitmap); }
return bRetValue; } 
|