1. 程式人生 > >VC++ MFC中 使用BMP按鈕

VC++ MFC中 使用BMP按鈕

*********ins-ert***********編譯出錯請去掉“-”


1. 用下面的類CBmpButton
2. 例化一個CBmpButton並將 控制元件對映 到想要顯示為BMP的按鈕上
3. 注意: 要顯示BMP的按鈕的style屬性應選為: owner draw , bitmap
4. 在按鈕所在的類裡的 3處 新增:
在*.H檔案中:
#include "BmpButton.h" //-- 包含標頭檔案

//---------------------------
//-- 新增1
//---------------------------
// Dialog Data
//{{AFX_DATA(CBitmapButtonDlg)
enum { IDD = IDD_BITMAPBUTTON_DIALOG };
CBmpButton m_BmpButton; //-- added here
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA

//---------------------------
//-- 新增1
//---------------------------
// Dialog Data
//{{AFX_DATA(CBitmapButtonDlg)
enum { IDD = IDD_BITMAPBUTTON_DIALOG };
CBmpButton m_BmpButton; //-- added here
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA


//---------------------------
//-- 新增2
//---------------------------
void CBitmapButtonDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CBitmapButtonDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
DDX_Control(pDX, IDOK, m_BmpButton);//-- added here


//}}AFX_DATA_MAP
}
//---------------------------
//-- 新增3
//---------------------------
BOOL CBitmapButtonDlg::OnInitDialog()
{
......系統初始化程式碼

m_BmpButton.SetData( TRUE, IDB_OK );
return TRUE;
}


//---------------------------------------------------------------------------------
//-- 給予CBUTTON的CBmpButton類如下
//-- BmpButton.h
//---------------------------------------------------------------------------------
#if !defined(AFX_BMPBUTTON_H__31EF914C_A839_441A_8FB8_846E71DB1F99__INCLUDED_)
#define AFX_BMPBUTTON_H__31EF914C_A839_441A_8FB8_846E71DB1F99__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// BmpButton.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CBmpButton window

class CBmpButton : public CButton
{
// Construction
public:
CBmpButton();



// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBmpButton)
//}}AFX_VIRTUAL


// Implementation
public:
BOOL SetData( BOOL ImageOnLeft, UINT IDUp, UINT IDDown=0, UINT IDFocus=0, UINT IDDisabled=0);
void DrawTransparent(CDC* pDC, int x, int y, CBitmap* hbmImage, BOOL LowerLeft=TRUE, COLORREF crColor=0);
void Emboss( CBitmap& Dest, CBitmap& bmSource );
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

// Bitmaps for image display
CBitmap m_Up, m_Down, m_Focus, m_Disabled;
// Bitmap height and width information
int m_ImageWidth, m_ImageHeight;
// Flag for image on left or right
BOOL m_ImageOnLeft;



virtual ~CBmpButton();

// Generated message map functions
protected:
//{{AFX_MSG(CBmpButton)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INS-ERT_LOCATION}}
// Microsoft Visual C++ will ins-ert additional declarations immediately before the previous line.

#endif // !defined(AFX_BMPBUTTON_H__31EF914C_A839_441A_8FB8_846E71DB1F99__INCLUDED_)



//---------------------------------------------------------------------------------
//-- 給予CBUTTON的CBmpButton類如下
//-- BmpButton.c
//---------------------------------------------------------------------------------
// BmpButton.cpp : implementation file
//

#include "stdafx.h"
#include "bitmapButton.h"
#include "BmpButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBmpButton

CBmpButton::CBmpButton()
{
}

CBmpButton::~CBmpButton()
{
}


BEGIN_MESSAGE_MAP(CBmpButton, CButton)
//{{AFX_MSG_MAP(CBmpButton)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBmpButton message handlers



/////////////////////////////////////////////////////////////////////////////
// CBmpButton message handlers

void CBmpButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CRect Rect = lpDrawItemStruct->rcItem;
SIZE DrawArea;
int XOffset, YOffset, YTextOffset=0, YImageOffset=0;
UINT nOffset = 0;
UINT nFrameStyle=0;
int nStateFlag;
CBitmap* pImage;

CString Text;

CDC DestDC;
DestDC.Attach( lpDrawItemStruct->hDC );

// Based on the size of the button text, and the images, determine drawing
// positions of each.
GetWindowText( Text );
DrawArea = DestDC.GetTextExtent(Text);
DrawArea.cx += (m_ImageWidth+4);
if( DrawArea.cy > m_ImageHeight )
YTextOffset = ( m_ImageHeight - DrawArea.cy ) /2;
else
{
YImageOffset = (DrawArea.cy - m_ImageHeight) /2;
DrawArea.cy = m_ImageHeight;
}
if( Text.Find( "&" ) >= 0 )
{
CSize Tmp;
Tmp = DestDC.GetTextExtent( "&" );
DrawArea.cx -= Tmp.cx;
}
XOffset = (Rect.right - DrawArea.cx)/2;
YOffset = (Rect.bottom - DrawArea.cy)/2;

// Determine if button is in the selected state
if ( lpDrawItemStruct->itemState & ODS_SELECTED)
{
nFrameStyle = DFCS_PUSHED;
pImage = m_Down.GetSafeHandle() ? &m_Down : &m_Up;
nOffset += 1;
}

// Determine if button is disabled
if( lpDrawItemStruct->itemState & ODS_DISABLED )
{
nStateFlag = DSS_DISABLED;
pImage = m_Disabled.GetSafeHandle() ? &m_Disabled : &m_Up;
}
else
{
nStateFlag = DSS_NORMAL;
pImage = &m_Up;
}

// Determine if button has the focus state
if ( lpDrawItemStruct->itemState & ODS_FOCUS )
pImage = m_Focus.GetSafeHandle() ? &m_Focus : &m_Up;

// If button is selected, the use DrawFrameControl to display its frame
if( ! (lpDrawItemStruct->itemState & ODS_SELECTED) )
{
// If the button is focused, then we need to draw the black rectangle,
// and shrink the button a tiny bit (visual appearance of all buttons)
if( lpDrawItemStruct->itemState & ODS_FOCUS )
{
DestDC.Rectangle(Rect.left, Rect.top, Rect.right, Rect.bottom );
Rect.DeflateRect(1,1);
}
DestDC.DrawFrameControl( &Rect, DFC_BUTTON, DFCS_BUTTONPUSH | nFrameStyle);
}
else
{
// If it's not selected, then drawing is more complex
// Create out pens and brushes for drawing, and draw a rectangle.
CBrush NewBrush;
NewBrush.CreateSolidBrush( ::GetSysColor( COLOR_3DFACE ) );
CBrush* pOldBrush = (CBrush*)DestDC.SelectObject( &NewBrush );
DestDC.Rectangle(Rect.left, Rect.top, Rect.right, Rect.bottom );
CPen NewPen;
NewPen.CreatePen( PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW) );
CPen* pOldPen = (CPen*)DestDC.SelectObject( &NewPen );

// Then, shrink the rectangle a tiny bit, and draw the inner rectangle
Rect.left++;
Rect.top++;
Rect.bottom--;
Rect.right--;
DestDC.Rectangle( Rect.left, Rect.top, Rect.right, Rect.bottom );
DestDC.SelectObject( pOldPen );
DestDC.SelectObject( pOldBrush );

}

if( m_ImageOnLeft )
{
// Draw the bitmap image, transparently, and then the text
DrawTransparent( &DestDC, XOffset+nOffset, YOffset+nOffset+YImageOffset, pImage );
DestDC.DrawState( CPoint(XOffset+m_ImageWidth+4+nOffset, YOffset+nOffset+YTextOffset),
DrawArea, Text, DST_PREFIXTEXT|nStateFlag, TRUE, 0, (HBRUSH)0 );
}
else
{
// Draw the text, and then the bitmap image transparently
DestDC.DrawState( CPoint(XOffset+nOffset, YOffset+nOffset+YTextOffset), DrawArea,
Text, DST_PREFIXTEXT|nStateFlag, TRUE, 0, (HBRUSH)0 );
DrawTransparent( &DestDC, XOffset+nOffset+DrawArea.cx+m_ImageWidth, YOffset+nOffset+YImageOffset, pImage );
}

// Draw the focus rectangle for the button
if( ( lpDrawItemStruct->itemState & ODS_FOCUS ) )
{
RECT Rect2;
Rect2 = Rect;
Rect2.left += 3;
Rect2.right -= 3;
Rect2.top += 3;
Rect2.bottom -= 3;
DestDC.DrawFocusRect( &Rect2 );
}

DestDC.Detach();


// CButton::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

// CBmpButton::SetData - Sets image information for the CBmpButton class
// ImageOnLeft - If TRUE then image appears to left of text, otherwise image appears to the right
// IDUp - Must specified the ID for the bitmap to display when in the normal, 'Up' state.
// IDDown - Specifies the image to use for the down state of the button. May be zero.
// IDFocus - Specifies the image to use for the focus state of the button. May be zero.
// IDDisabled - Specifies the image to use for the disabled state of the button. May be zero.
// Returns: TRUE if succesful, FALSE if not
// Comments: If IDDown or IDFocus are zero, then the Up image is used for those states. If the
// IDDisabled value is zero, then an embossed version of the up image is created and used.
BOOL CBmpButton::SetData(BOOL ImageOnLeft, UINT IDUp, UINT IDDown, UINT IDFocus, UINT IDDisabled)
{
// If button already has data loaded, then delete the bitmaps
if( m_Up.GetSafeHandle() )
m_Up.DeleteObject();
if( m_Down.GetSafeHandle() )
m_Down.DeleteObject();
if( m_Focus.GetSafeHandle() )
m_Focus.DeleteObject();
if( m_Disabled.GetSafeHandle() )
m_Disabled.DeleteObject();

// Load the 'Up' state bitmap (required). Use it to specify height and width of all images
m_Up.LoadBitmap( IDUp );
BITMAP BM;
m_Up.GetObject( sizeof(BM), &BM );
m_ImageHeight = BM.bmHeight;
m_ImageWidth = BM.bmWidth;

// Store the ImageOnLeft value
m_ImageOnLeft = ImageOnLeft;

// Load other bitmaps as needed
if( IDDown )
m_Down.LoadBitmap( IDDown );
if( IDFocus )
m_Focus.LoadBitmap( IDFocus );

// If a disabled image was specified, then load it, otherwise create an embossed version
// of the 'Up' image.
if( IDDisabled )
m_Disabled.LoadBitmap( IDDisabled );
else
Emboss( m_Disabled, m_Up );

return(TRUE);

}


// DrawTransparent - Draws a bitmap with transparency
// Parameters:
// DC - HDC to draw bitmap on
// x - X coordinate on DC to draw bitmap at
// y - Y coordinate on DC to draw bitmap at
// hbmImage - Handle to bitmap to display
// LowerLeft - If True, then transparency color is taken from lower left of bitmap
// crColor - If LowerLeft is false, then this must specify transparent color for bitmap
void CBmpButton::DrawTransparent(CDC* pDC, int x, int y, CBitmap* hbmImage, BOOL LowerLeft, COLORREF crColor)
{
CDC hdcImage;
CDC hdcTrans;
CBitmap hbmTrans;
BITMAP bmBitmap;

hbmImage->GetObject( sizeof(bmBitmap), &bmBitmap );
// Change Background and text color, saving values for end
COLORREF crOldBack = pDC->SetBkColor(RGB(255,255,255));
COLORREF crOldText = pDC->SetTextColor(RGB(0,0,0) );

// Create Memory DCs to do our work in
hdcImage.CreateCompatibleDC(pDC);
hdcTrans.CreateCompatibleDC(pDC);

// Select passed Image bitmap into Image memory DC
hdcImage.SelectObject(hbmImage);

// Create transparent bitmap, and select into transparent DC
hbmTrans.CreateBitmap( bmBitmap.bmWidth, bmBitmap.bmHeight, 1, 1, NULL);
hdcTrans.SelectObject( hbmTrans);

// If LowerLeft is true, then determine transparent color from bitmap passed
if( LowerLeft )
crColor = hdcImage.GetPixel( 0, bmBitmap.bmHeight-1 );

// Select background color (transparent color) for our image memory DC
hdcImage.SetBkColor(crColor);

hdcTrans.BitBlt( 0, 0, bmBitmap.bmWidth, bmBitmap.bmHeight, &hdcImage, 0, 0, SRCCOPY);

// Perform BitBlt operations (this is where the Masking occurs)
pDC->BitBlt( x, y, bmBitmap.bmWidth, bmBitmap.bmHeight, &hdcImage, 0, 0, SRCINVERT);
pDC->BitBlt( x, y, bmBitmap.bmWidth, bmBitmap.bmHeight, &hdcTrans, 0, 0, SRCAND);
pDC->BitBlt( x, y, bmBitmap.bmWidth, bmBitmap.bmHeight, &hdcImage, 0, 0, SRCINVERT);

// Retore original background and text colors for the passed DC
pDC->SetBkColor(crOldBack);
pDC->SetTextColor(crOldText);

}

// Emboss - Basic embossing ability
// Parameters:
// bmDest - Destination bitmap
// bmSource - Source bitmap to be embossed
// Comments: Uses brute force so we can maintain 3 colors on a disabled bitmap:
// the highlight, dark, and transparent colors
void CBmpButton::Emboss( CBitmap& Dest, CBitmap& bmSource )
{
CDC memDC, memDCEmbossed;
CBitmap hbmOldBM, hbmOldBMEmbossed;
BITMAP bmInfo;
COLORREF crTransparent, crLo = ::GetSysColor(COLOR_3DHILIGHT),crHi=::GetSysColor(COLOR_3DSHADOW);
COLORREF crCur, crNewTransparent = ::GetSysColor( COLOR_3DFACE );
int Row, Col, ColorAvg=0, Total=0;

// Determine information for the bitmap passed
bmSource.GetObject( sizeof(bmInfo), &bmInfo );

// Create memory DCs, and the return bitmap, for drawing and creation
memDC.CreateCompatibleDC(NULL);
memDCEmbossed.CreateCompatibleDC(NULL);
memDC.SelectObject(&bmSource );
Dest.CreateCompatibleBitmap( &memDC, bmInfo.bmWidth, bmInfo.bmHeight );

// Select the new bitmap into the memory DC. Now, when we draw on the memory DC, it
// will manipulate the bitmap that is selected into it.
memDCEmbossed.SelectObject( Dest );

// Perform some basic color analisys, to determine what colors to use
crTransparent = memDC.GetPixel( 0, bmInfo.bmHeight-1 );
for( Row=0; Row < bmInfo.bmHeight; Row++ )
for( Col=0; Col < bmInfo.bmWidth; Col++ )
{
crCur = memDC.GetPixel( Row, Col );
if( crCur != crTransparent )
{
ColorAvg+=(GetGValue(crCur)+GetBValue(crCur)+GetRValue(crCur));
Total++;
}
}
ColorAvg /= Total;

// Draw the original bitmap into the memory DC, which will set the color depth and
// dimensions of the new bitmap.
memDCEmbossed.BitBlt( 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, &memDC, 0, 0, SRCCOPY);

// Now, go through each pixel, and make it one of 3 colors: Dark, light, and transparent
for( Row=0; Row < bmInfo.bmHeight; Row++ )
for( Col=0; Col < bmInfo.bmWidth; Col++ )
{
crCur = memDC.GetPixel( Col, Row );
if( crCur != crTransparent )
{
if( (GetGValue(crCur)+GetBValue(crCur)+GetRValue(crCur)) > ColorAvg )
memDCEmbossed.SetPixel( Col, Row, crHi);
else
memDCEmbossed.SetPixel( Col, Row, crLo);
}
else
memDCEmbossed.SetPixel( Col, Row, crNewTransparent );
}
// Destructors clean up for us.
}

 

相關推薦

VC++ MFC 使用BMP按鈕

*********ins-ert***********編譯出錯請去掉“-”1. 用下面的類CBmpButton2. 例化一個CBmpButton並將 控制元件對映 到想要顯示為BMP的按鈕上3. 注意: 要顯示BMP的按鈕的style屬性應選為: owner draw , b

[轉]關於VC++ MFC的空閑Idle處理機制!

normal 函數 系統 true check track cor idle 行處理 關鍵詞:   先根據空閑標誌以及消息隊列是否為空這兩個條件判斷當前線程是否處於空閑狀態(這個“空閑”的含義同操作系統的含義不同,是MFC自己所謂的“空閑”),如果是,就調用CW

VC/MFC的CComboBox控件使用詳解

作用 沒有 opp com 開始 getc 其他 index ear CComboBox控件詳解 CComboBox控件又稱作組合框控件,其有三種形態可供選擇,1.簡單組合框(Simple)2.下拉組合框(Drop-down)3.下拉列表式組合框(Drop-down lis

VC++ MFCCString類完美總結(整理)

CString位於標頭檔案afx.h中。①、CString 類物件的初始化:CString str;CString str1(_T("abc"));CString str2 = _T("defg");TCHAR szBuf[] = _T("kkk");CString str3(szBuf);CString s

VC/MFC如何替換自帶滾動條控制元件的圖片

Introduction This is my first article. At first, I must express my thanks to CodeProject and all the selfless people. I have tried to look for a sample to

MFC按鈕新增圖示

 在MFC中的按鈕,本身只有文字,比較簡單,現在想實現在按鈕上新增圖示(.ico格式)的效果。如果想改變窗體的Icon利用的是SetIcon函式,而SetIcon函式其實是CWnd的成員函式。而CButton也是一種視窗,即繼承自CWnd,所以Button也可以利用這個

VC MFCCList成員的使用

Adds an element (or all the elements in another list) to the head of the list (makes a new head).在連結串列頭處插入新資料,連結串列資料個數加1,返回新的連結串列頭位置(POSITION);例子:CList<

MFCBMP圖片放入失敗問題解決辦法

  之前寫的一個MFC小專案在最後想插入圖片總是報錯,後來查了各種資料終於解決了,圖片放入失敗的錯誤和解決辦法如下。 1:找不到rc.exe,原因是圖片路徑   專案名是中文名字的時候總是會報錯:“找

mfc新增按鈕對應的處理函式四種方法

方法一:雙擊按鈕自動新增處理函式,自動以OnBnClicked開頭,ID結尾命名,這種方法最簡單,但無法修改函式名稱,只能生成預設的按鈕按下訊息的函式。                           方法二:類嚮導(Ctrl+p+z),對按鈕右鍵選擇“類嚮導”,在訊

VC/MFC讀取BMP檔案並顯示

自己寫過的程式碼,留作儲存,以後不會忘了 先宣告幾個變數 BYTE * pBMPDataBuf;//BMP資料buf BITMAPFILEHEADER BmpHeader;//BMP影象檔案頭 BITMAPINFO BmpInfo;//BMP影象資訊結構 RGBQU

VC++ MFC工程如何將一個工程的資源(如對話框)復制到另外一個工程

sta 發現 targe 文件復制 如果 csdn static 備份 完成 問題的提出:在工程1中用到的資源,在工程2中已有現成的。即工程1中要用到的對話框和工程2的完全相同,而工程2中對該對話框的布局已設計好、控件變量都綁定好了。但由於該對話框的控件特別多,

VC++6.0 MFCCString與int、double、float等資料互相轉化

C++中doulbe/float/int轉為CString的方法 在MFC程式中,可以使用Format方法方便的實現int、float和double等數字型別轉換為CString字串。以下是CString的Format支援的格式說明: C++表達方式 資

VC++6.0 MFC獲取編輯框內容

1、方法一:設定編輯框變數 在MFC的基本對話方塊中,建立一個編輯框控制元件,為控制元件新增一個型別為CEdit的變數 m_Edit 。 CString str; m_Edit.GetWindowText(str); 2、方法二:通過ID獲取 CString

VC/MFC 在對話方塊建立檢視並在檢視區新增ListCtrl控制元件

自定義的view類用於顯示在對話方塊上 class CGroupMenuView : public CScrollView { protected:  CGroupMenuView(); ……………… ………… };   class CWorkView :

MFC動態獲取/設定按鈕的文字

(1) 獲取按鈕控制元件的文字:  CString tempstr; // 獲取ID為ID_BUTTON_1按鈕的文字內容 GetDlgItem(ID_BUTTON_1)->GetWindowText(tempstr); (2) 設定按鈕控制元件的文字: GetD

MFC PreTranslateMessage(MSG* pMsg)截獲按鈕和編輯框的訊息進行預處理

在類嚮導自動為對話方塊新增PreTranslateMessage(MSG* pMsg)函式; BOOL CjilutestDlg::PreTranslateMessage(MSG* pMsg) {     // TODO:  在此新增專用程式碼和/或呼叫基類     if

vc++6生成mfc.bsc檔案和使用方法

 MFC.bsc檔案的生成方法  首先進入DOS命令模式:  C:/Program Files/Microsoft Visual Studio/VC98/bin目錄下執行VCVARS32.BAT, 然後再進入C:/Program&n

MFC視窗隨最小化最大化按鈕最大最小化

轉載於:https://blog.csdn.net/Bettyshasha/article/details/51603752  1.選中對話方塊,右鍵-》屬性-》訊息,新增WM_SIZE函式。 2.在對話方塊類標頭檔案.h裡面新增: void ReSize(); POINT o

VC MFC開發】Dll 對話方塊的控制元件無法接受到按鍵訊息的解決辦法

使用DLL注入到 別的程式中時,發現DLL的視窗過程無法響應WM_CHAR事件,摸索了很久,才找到原因,給碰到同樣問題的人蔘考。 WNDPROC OldComboEditProc = NULL; LRESULT CALLBACK ComboEditProc(   HW

VC/MFC 從WebBrower 獲取 HTML 和文字

本文部分轉載於 http://blog.chinaunix.net/uid-2516614-id-2496197.html 用於參考 /////////////////////////////////////////////////////////////// 外部視窗介