VC++技術內幕(第四版)筆記(第10章)

第十章:位圖

1,Windows的位圖實際上是一些和顯示象素相對應的位陣列。

2,GDI位圖是設備相關位圖,用MS基本類庫(MFC)中的CBitmap類表示的,依賴具體的設備。

3,DIB社設備無關位圖,比GDI位圖有許多編程優勢。任何運行Windows的機器都可以處理DIB位圖。DIB位圖通常以.BMP文件形式保留在磁盤中,或作爲資源保存在程序的EXE或DLL文件中。WIN32API只直接支持DIB格式文件。

4,Windows在位圖中使用模糊顏色。GDI位圖也是GDI對象,使用時先創建(並初始化),再把它選入設備環境,使用完後還要刪除掉。
注意:
使用GDI位圖的時候,不能直接把位圖選進顯示設備環境或打印機設備環境中。必須利用CDC::CreateCompatibleDC函數爲位圖創建一個特殊的內存設備環境,然後使用CDC::StretchBlt或CDC::BitBlt函數把內存設備環境中的各個位複製到真正的設備環境中。
說明:
1)CDC::CreateCompatibleDC 
virtual BOOL CreateCompatibleDC( CDC* pDC );
// Creates a memory device context that is compatible with the device specified by pDC. A memory device context is a block of memory that represents a display surface. It can be used to prepare images in memory before copying them to the actual device surface of the compatible device.
2)CDC::BitBlt 
BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );
//Copies a bitmap from the source device context to this current device context.
3)CDC::StretchBlt
BOOL StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );
//Moves a bitmap from a source rectangle and device into a destination rectangle, stretching or compressing the bitmap if necessary to fit the dimensions of the destination rectangle.
4)應用事例:
void CGDIView::OnDraw(CDC* pDC)
{
 CBitmap bitmap;
 bitmap.LoadBitmap(IDB_BITMAP1);
 CDC *pdcm=new CDC;
 pdcm->CreateCompatibleDC(pDC);
 pdcm->SelectObject(&bitmap);
 pDC->BitBlt(100,100,54,96,pdcm,0,0,SRCCOPY);
 delete pdcm;
 //pDC->StretchBlt(100,100,500,50,pdcm,0,0,50,50,SRCCOPY);
}
注:事例中顯示映射模式爲MM_TEXT,MM_TEXT下每個位圖象素都映射到一個顯示器象素。如果在其它的模式下需要進行一些伸縮變換處理。處理縮小的位圖時候可以調用CDC::SetStretchBltMode函數(參數可選COLORONCOLOR)使縮小的位圖顯示更好些。
在非MM_TEXT模式下,使用BitBlt或StretchBlt函數,如果GDI要對其進行伸縮變換,則更新的速度較慢.可以使用以下代碼代替BitBlt語句可加快其更新速度:
pDC->SetMapMode(MM_LOENGLISH);//設置映射模式爲MM_LOENGLISH。
CSize size(54,96);
pDC->DPtoLP(&size);
pDC->StretchBlt(0,0,size.cx,-size.cy,dcm,0,0,54,96,SRCCOPY);//MM_LOENGLISH模式下注意-size.cy前的負號不能少。


5,事例EX10A中函數說明:
1)CGdiObject::GetObject
int GetObject( int nCount, LPVOID lpObject ) const;
參數說明:
nCount:Specifies the number of bytes to copy into the lpObject buffer.
lpObject:Points to a user-supplied buffer that is to receive the information.
//Return Value:The number of bytes retrieved; otherwise 0 if an error occurs.
//Fills a buffer with data that describes the Windows GDI object attached to the CGdiObject object.
//
Object  Buffer type
CPen   LOGPEN
CBrush   LOGBRUSH
CFont   LOGFONT
CBitmap  BITMAP
CPalette  WORD
CRgn   Not supported
//If the object is a CBitmap object, GetObject returns only the width, height, and color format information of the bitmap. The actual bits can be retrieved by using CBitmap::GetBitmapBits.

2)CGdiObject::GetSafeHandle
HGDIOBJ GetSafeHandle( ) const;
//Return Value:A HANDLE to the attached Windows GDI object; otherwise NULL if no object is attached.


6,事例EX10B說明:位圖有程序自己生成,並且能使位圖在屏幕上平滑移動。原理:首先將所選擇的位圖繪製在內存設備環境中,然後再將它反覆快速地在屏幕上進行顯示。

7,DIB編程(出於個人需要,這裏做概要筆記,詳見P190-204)
1)在MFC庫中有GDI位圖的類CBitmap,但沒有DIB的類。
2)DIB包含一個二維數組,數組的元素爲象素。
3)DIB是標準的Windows位圖格式,且BMP文件包含一個DIB結構。
4)DIB訪問函數:
SetDIBitsToDevice//直接在顯示器或打印機上顯示DIB,不進行縮放,位圖每一位對應一顯示象素或一打印點。
StretchDIBits//仿照StretchBlt類似的方式將DIB顯示在顯示器或打印機上。
GetDIBits//函數利用申請到的內存,由GDI位圖來構造DIB。
CreateDIBitmap//由DIB來創建GDI位圖。
CreateDIBSection//創建一種稱爲DIB項的DIB,然後返回一個GDI句柄。提供了DIB和GDI位圖最好的特性。可以直接訪問DIB的內存,還可以在DIB中調用GDI函數畫圖。
5)LoadImage//The LoadImage function loads an icon, cursor, or bitmap.
LoadImage可以直接從一個磁盤文件中讀入位圖
6)DrawDibDraw//The DrawDibDraw function draws a DIB to the screen.
DrawDibDraw需要MM_TEXT座標和MM_TEXT映射模式。


8,在按鈕上設置位圖
1)先設置按鈕的Owner Draw屬性,然後在對話框類中寫一個消息控制函數,在該按鈕控制的窗口裏畫圖。
2)使用MFC的CBitmapButton類實現在按鈕在設置位圖。步驟如下:
第一步:在對話框中添加按鈕,並設置Owner Draw屬性,大小並不重要。(框架自動調整爲位圖大小)
第二步:添加位圖資源(.bmp),並用相應的按鈕Caption+D/U來標識位圖。即在位圖的屬性ID欄中輸入"按鈕Caption+U"或"按鈕Caption+D",其中名字兩邊的引號不能少,這樣就表示了用名字標識資源而不是ID,U表示不翻轉顯示的位圖,D表示翻轉顯示的位圖。如:按鈕Caption爲[Button1],則在該按鈕上貼位圖的名字應爲["Button1D"]或["Button1U"]。
第三步:爲要設置位圖的按鈕,對應在按鈕所在對話框類中添加CBitmapButton類型的數據成員。
第四步:映射按鈕所在對話框類WM_INITDIALOG消息,在OnInitDialog函數中用剛添加的CBitmapButton類型的數據成員調用
AutoLoad函數把每個按鈕和兩個匹配的位圖資源連接起來。如:VERIFY(CWnd::EnableWindow.AutoLoad(IDC_BUTTON1,this));
說明一:
CBitmapButton::AutoLoad
BOOL AutoLoad( UINT nID, CWnd* pParent );
//nID:The button’s control ID.
//pParent:Pointer to the object that owns the button.
//AutoLoad Associates a button in a dialog box with an object of the CBitmapButton class, loads the bitmap(s) by name, and sizes the button to fit the bitmap.(注意哦,這裏的loads the bitmap by name。)
//Use the AutoLoad function to initialize an owner-draw button in a dialog box as a bitmap button.
說明二:
VERIFY
VERIFY( booleanExpression )
//VERIFY是MFC診斷宏,當參數booleanExpression 爲 0 的時候,停止程序並顯示一個對話框;當booleanExpression 不爲零,則什麼也不做。
說明三:
在爲按鈕設置的位圖加名字標識的時候:
"按鈕Caption+U"  表示按鈕凸起狀態的位圖
"按鈕Caption+D"  表示按鈕凹起狀態的位圖
"按鈕Caption+F"  表示按鈕有焦點狀態的位圖
"按鈕Caption+X"  表示按鈕無效狀態的位圖

9,CWnd::EnableWindow函數可以是一個窗口有效或無效,可以調用它來使按鈕等控件(窗口)無效或恢復有效。
CWnd::EnableWindow 
BOOL EnableWindow( BOOL bEnable = TRUE );
//If this parameter is TRUE, the window will be enabled. If this parameter is FALSE, the window will be disabled.
//EnableWindow Enables or disables mouse and keyboard input. When input is disabled, input such as mouse clicks and keystrokes is ignored. When input is enabled, the window processes all input.
//An application can use this function to enable or disable a control in a dialog box. A disabled control cannot receive the input focus, nor can a user access it.


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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章