1. 程式人生 > >載入png圖片按鈕GdipButton按鈕類

載入png圖片按鈕GdipButton按鈕類

介紹

這個網站上有幾個自繪按鈕,但是我找不到一個容易支援PNG檔案透明度的按鈕,所以我建立了這個類。由於這個類使用GDI +,它實際上支援許多影象格式,但是現在更好的質量按鈕現在是PNG而不是ICO,所以這裡就是一個。

更新:我的樣式工具包譯者:這篇文章有翻譯,請點選中有這個類的擴充套件版本如果你想要的是使用按鈕上的影象,這個類可能更簡單的使用。

背景

GDI +是Microsoft Windows SDK的一部分,需要在應用程式啟動時進行初始化。如果您以前沒有使用GDI +,請檢視演示專案的原始碼並閱讀本文:

特徵

  • 灰度影象
    • 該類將自動從載入的資源建立一個灰度影象。當按鈕設定為禁用狀態時,將顯示灰度影象。
  • 突出顯示影象
    • 該類將自動從載入的資源建立一個突出顯示的影象。當滑鼠懸停在按鈕邊界上時,顯示突出顯示的影象。
  • 替代影象
    • 您可以選擇新增備用影象。當通過功能呼叫設定時,或者單擊按鈕並啟用切換模式時,將顯示備用影象。
  • 切換模式
    • 啟用時,按鈕會在標準影象和備用影象每次按下之間切換。
  • 按鈕狀態
    • 當按下按鈕時,影象向下移動1畫素。
  • 工具提示
    • 可以選擇新增工具提示。

頁面頂部的影象顯示三種不同狀態的播放按鈕。從左到右,它們是:正常,突出顯示和禁用。另外兩個按鈕就是更酷的例子。

從圖片可能不太明顯,第二個按鈕處於突出顯示狀態。這是按設計,我不想大幅改變形象。高亮狀態只是增加了亮度和對比度。當您將滑鼠移動到其上時,顯然是足夠的。

這個類別優先考慮影象質量,所以它永遠不會拉伸或縮小通常降低質量的影象,它將只是繪製適合的部分。如果您需要調整影象大小,請使用Photoshop等影象編輯器。

下圖顯示了切換狀態下的播放按鈕,應該很明顯,為什麼會想要這樣的功能。退出按鈕處於突出顯示狀態,工具提示顯示在此影象中。

GdipButton2.PNG

使用GDI +僅在初始化期間被使用,所以沒有效能損失。在建立時,影象將轉換為點陣圖,並且在需要使用點陣圖重新繪製控制元件。

使用程式碼

步驟1 - 將這些檔案新增到您的專案

  • GdipButton.h
  • GdipButton.cpp
  • MemDC.h(
  • CGdiPlusBitmap.h(

步驟2 - 新增資源,成員變數和影象

使用資源編輯器在對話方塊中新增一個按鈕,設定資源ID,然後在Caption框中刪除文字。您可以將樣式設定為Owner Draw,但不需要,因為程式碼將自動設定此樣式。

使用類嚮導,新增一個變數到您剛剛建立的ID。在此示例中,我將ID設定為IDC_PLAY,並將變數名稱設定為m_cPlay編輯對話方塊的.h檔案,並將控制元件更改CButtonCGdiButton不要忘記包含檔案“ GdipButton.h ”。

在資源編輯器中,res資料夾匯入.png檔案,並將資源型別設定為PNG。使用PNG只是慣例,只要程式碼與命名相同,它就可以是任何東西。右鍵單擊IDR_PNG1,選擇屬性,並將其重新命名為有用的東西,IDR_PNG1IDR_PLAY在此示例中。

步驟3 - 新增LoadStdImage()函式

現在,我們只需要在初始化時將影象載入到按鈕。在該OnInitDialg()功能中,在底部附近新增以下程式碼:

BOOL CTestGdipButtonDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    /// a bunch of stuff here

    m_cPlay.LoadStdImage(IDR_PLAY, _T("PNG"));

    return TRUE; 
}

步驟4 - 構建和執行

您現在應該能夠執行它,並看到您的新的PNG按鈕!如果它在這裡崩潰,可能是因為你沒有初始化GDI +。檢視本文的背景部分。

演示專案

這是在測試程式中建立按鈕所需的所有程式碼:

// load the standard image and alternate image
m_cPlay.LoadStdImage(IDR_PLAY, _T("PNG"));
m_cPlay.LoadAltImage(IDR_PAUSE, _T("PNG"));
m_cPlay.EnableToggle(TRUE);

// just to show highlight state for article
m_cPlayHi.LoadStdImage(IDR_PLAY, _T("PNG"));

// set as disabled
m_cPlayDis.LoadStdImage(IDR_PLAY, _T("PNG"));
m_cPlayDis.EnableButton(FALSE);

// show a larger button type
m_cGear.LoadStdImage(IDR_GEAR, _T("PNG"));

// replace the OK button with something
m_cShutDn.LoadStdImage(IDR_EXIT, _T("PNG"));
m_cShutDn.SetToolTipText(_T("Close Program"));//(譯者:這裡應該是m_cShutDn.SetToolTipText(_T("Close Program"),TRUE);)

VC6和VS2005版本都包含在演示專案中。

透明影象問題

按鈕控制元件不知道它下面的背景應該是什麼; 它從與當前DC相關聯的點陣圖獲取此資訊。在大多數情況下,這樣做很好,背景是控制畫面之前的螢幕。但是,應用程式在啟動時可能不是最多的。總是在頂級應用程式,如工作管理員可能會阻礙,所以當它獲取背景影象,這是錯誤的資料。通過SetBkGnd()實際建立背景的程式碼呼叫函式來克服這個問題。

設定父項OnEraseBkgnd()功能中的所有按鈕背景演示程式使用以下程式碼:

BOOL CTestGdipButtonDlg::OnEraseBkgnd(CDC* pDC)
{
    CDialog::OnEraseBkgnd(pDC);
    CRect rect;
    GetClientRect(rect);

    CMemDC pDevC(pDC, rect);

    // fill in the back ground with something
譯者:請注意,在demo中,這裡有一段if (m_hBitmap)
{
pDevC->SelectObject(m_hBitmap);
}沒有的話對話方塊背景是黑色的
    SetButtonBackGrounds(pDevC);

    return TRUE;
}

void CTestGdipButtonDlg::SetButtonBackGrounds(CDC *pDC)
{
    m_cPlay.SetBkGnd(pDC);
    m_cPlayHi.SetBkGnd(pDC);
    m_cPlayDis.SetBkGnd(pDC);
    m_cShutDn.SetBkGnd(pDC);
}

由於傳遞的DC是一個記憶體DC,所以其他應用程式可能正在做的事情並不重要。上面的程式碼假設你想要使用除了預設背景之外的東西; 否則,您可能只需使用預設的crummy按鈕。

VC6構建問題

VC6需要一些額外的東西才能正確編譯,將以下內容新增到stdafx.h檔案中。還要將SDK include和lib路徑新增到您的環境中。

隱藏   複製程式碼
// VC6
#if defined(_MSC_VER) && _MSC_VER == 1200

#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#endif
#include <spanclass="code-keyword"><Specstrings.h></span>
#include <spanclass="code-keyword"><gdiplus.h></span>

#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;

// VS2005
#else 

#include <spanclass="code-keyword"><gdiplus.h></span>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;

#endif