一个透明的CStatic控件

翻译|其它|编辑:郝浩|2005-01-25 10:18:00.000|阅读 3195 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


如果我们自画了一个有背景的对话框,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
// waterpub@mail.csdn.net
//
//=========================================================
#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
// waterpub@mail.csdn.net
//
//=========================================================
// 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' davide_calabro@yahoo.com


//=========================================================//// 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.csdn.net////========================================================= #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.csdn.net////========================================================= #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;
}


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP