一个透明的CStatic控件【原创】

一个透明的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;
}

你可能感兴趣的:(一个透明的CStatic控件【原创】)