個類可以插入到任何一個程式當中,它提供一個統一的介面,介面函數接收圖象的資源索引號、長、寬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 hereCOLORREF 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 defaultCDC 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