如果我们自画了一个有背景的对话框,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 : 天衣有缝
// Product: iW988
// File : TransparentStatic.h
// Author : 天衣有缝

// Created: 2004.12.29 23:40
//
// Description:
// ValueAdded main program for iW988.
// Contact:ShenZhen @ GuangDong
// waterpub@mail.youkuaiyun.com
//
//=========================================================
#pragma once
// CTransparentStatic
class CTransparentStatic : public CStatic
{
DECLARE_DYNAMIC(CTransparentStatic)
public:
CTransparentStatic();
virtual ~CTransparentStatic();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
};
//
// Description:
// ValueAdded main program for iW988.
// Contact:ShenZhen @ GuangDong
// waterpub@mail.youkuaiyun.com
//
//=========================================================
#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 : 天衣有缝
// Product: iW988
// File : TransparentStatic.cpp
// Author : 天衣有缝
// Created: 2004.12.29 23:40
//
// Description:
// ValueAdded main program for iW988.
// Contact:ShenZhen @ GuangDong
// waterpub@mail.youkuaiyun.com
//
//=========================================================
//
// Description:
// ValueAdded main program for iW988.
// Contact:ShenZhen @ GuangDong
// waterpub@mail.youkuaiyun.com
//
//=========================================================
// 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整理二来,
//=========================================================
//
// 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
// waterpub@mail.youkuaiyun.com
//
//=========================================================#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
// waterpub@mail.youkuaiyun.com
//
//=========================================================#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; }