程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 一個透明位圖類的例子

一個透明位圖類的例子

編輯:關於VC++

編寫一個簡單的透明位圖類,有時候可以為程序潤色不少,下面是我寫的一個程序的UI,個人覺得蠻有意思的。

圖一 外觀

這個類可以插入到任何一個程序當中,它提供一個統一的接口,接口函數接收圖象的資源索引號、長、寬3個參數。當然,你也可以加上一個父窗口的指針參數,用來決定該類對象Create行為,便於指定該圖象代表的窗口應該依附在哪個父窗口之上。

編寫這個類需要熟悉對CRgn類的運用。如成員函數CombineRgn和SetWindowRgn,具體信息請查閱msdn。

那麼好,下面我們來一步步創建這個類。

一、首先要准備一幅用來展示在UI上的圖象,自己定義一種透明色,用該色來填充透明部分,這裡要注意的是,透明色應該是該圖象中顏色最少的色,還要注意的是透明和非透明的交界處一定要求清晰,不能存在過渡色。這裡我使用的是RGB(255, 0,255)。如下:

圖二 透明位圖

二、使用MFC AppWizard創建一個對話框程序,在資源選項卡中把上一步的圖象添加進來,創建一個新的窗口類CMyWnd,派生自generic CWnd。

為該類添加3個私有成員:

private:
  CRect m_rtWnd;
  CBitmap m_bitmap;
  BITMAP m_bmp;
為該類添加WM_CREATE和WM_ERASEBKGND2個消息處理函數:int CMyWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CWnd::OnCreate(lpCreateStruct) == -1)
    return -1;

  // TODO: Add your specialized creation code here
  COLORREF crl;
  GetWindowRect(&m_rtWnd);
  CRgn wndRgn, rgnTemp;
  CDC* pDC = GetWindowDC();
  CDC dcCompatible;
  dcCompatible.CreateCompatibleDC(pDC);
  CBitmap* pOldBitmap = dcCompatible.SelectObject(&m_bitmap);

  wndRgn.CreateRectRgn(0,0,m_rtWnd.Width(),m_rtWnd.Height());
  for(int x=0; x<m_rtWnd.Width(); x++)
  {
    for(int y=0; y<m_rtWnd.Height(); y++)
    {
      crl = dcCompatible.GetPixel(x, y);
      if(crl == TRANSCOLOR)
      {
        rgnTemp.CreateRectRgn(x, y, x+1, y+1);
        //裁減掉透明色區域
        wndRgn.CombineRgn(&wndRgn,&rgnTemp, RGN_XOR);
        rgnTemp.DeleteObject();
      }
    }
  }
  //設置最終的窗口范圍
  SetWindowRgn((HRGN)wndRgn,TRUE);

  dcCompatible.SelectObject(pOldBitmap);
  ReleaseDC(pDC);
  ReleaseDC(&dcCompatible);
  return 0;
}
BOOL CMyWnd::OnEraseBkgnd(CDC* pDC)
{
  // TODO: Add your message handler code here and/or call default
  CDC dcCompatible;
  dcCompatible.CreateCompatibleDC(pDC);
  CBitmap* pOldBitmap = dcCompatible.SelectObject(&m_bitmap);
  pDC->StretchBlt(0, 0, m_bmp.bmWidth, m_bmp.bmHeight,
          &dcCompatible, 0, 0, m_bmp.bmWidth,
          m_bmp.bmHeight, SRCCOPY);
  dcCompatible.SelectObject(pOldBitmap);
  ReleaseDC(&dcCompatible);
  return TRUE;
}

為該類添加一個供外部調用的函數SetPic:

void CMyWnd::SetPic(UINT nIDPic, int nLeft, int nTop)
{
  if(NULL != m_bitmap.m_hObject)
  {
    m_bitmap.DeleteObject();
  }
  m_bitmap.LoadBitmap(nIDPic);
  m_bitmap.GetBitmap(&m_bmp);
  int nRight = m_bmp.bmWidth + nLeft;
  int nBottom = m_bmp.bmHeight + nTop;
  Create(NULL, NULL, WS_CHILD, CRect(nLeft, nTop, nRight,  nBottom),
      AfxGetApp()->m_pMainWnd, nIDPic);
  ShowWindow(SW_SHOWNORMAL);
}

最後別忘了在MyWnd.cpp文件的前面加上:

#define TRANSCOLOR RGB(255,0,255)

這是定義的用作透明色的紫色,這樣,透明位圖類就寫完了。

現在在對話框XXXDlg.h頭文件中加上一個CmyWnd m_wnd,用來做裁減圖象的承載窗口對象,並在BOOL CTransBMPDlg::OnInitDialog()函數中加上一條代碼:

m_wnd.SetPic(IDB_BITMAP1, 10, 10);

這樣就大功告成啦,還簡單吧^_^。

編程環境:Visual C++6.0 & MFC

本文配套源碼

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved