第十一章 顯示位圖
在窗口中顯示位圖(*.bmp文件)的需要是經常會發生的。本章介紹如何把位圖文件加入到工程的資源中,如何在對話框中顯示出來。因爲圖片是在設計階段加入的,成爲靜態加入圖片。VC的資源管理只能夠加入BMP格式的圖片,因此要使用GIF和JPG格式等其他的圖片和想動態地加入圖片,還需要使用別的控件,這在以後專門介紹。
本章要點
1 在工程中添加位圖資源
2 把圖片讀入內存和屏幕顯示
11.1 MyBmp.exe程序的界面和功能
本程序打開後在窗口顯示一幅圖——小貓,上面有一個簡單的菜單,沒有其他控件。File菜單中有Open, Save和Exit三項。Open菜單項沒有加入代碼,點擊後沒有反應;Save菜單項連消息映射都沒有加入;點擊[Exit]則可以退出程序。[Help]菜單項會打開About消息框。但是,窗口是可以改變大小的,當鼠標拖動右下角時,圖片總是充滿整個用戶區域。
11.2 添加資源和設計界面
1 加入位圖資源
事先找好小貓的圖片文件cat.bmp,我這是在WINDOWS目錄中的,也可以用其它的BMP格式的圖片,別的格式不行。右擊工作區資源頁的Bitmap分支,選“導入或Import”;在打開的文件對話框中位圖的文件名;這就在Bitmap分支上增加了一個位圖,你還需要用右鍵菜單設置屬性,把ID改爲IDB_MYBMP。雙擊它還可以對它進行圖片加工。
2 添加菜單
參考第四章敘述的方法添加菜單IDR_MENU1,它包含FIEL和HELP兩個菜單。FIEL菜單包括三個菜單項,HELP菜單就只有Help菜單項。打開類嚮導,將菜單IDR_MENU1與類CMyBmpDlg項關聯。
3 設置主窗口
打開主對話框的屬性頁,設置ID = IDD_MYBMP_DIALOG,標題 = MyBmp-顯示位圖,並把MENU1加入進去。在Styles頁設置窗口是可以改變大小的,加上系統菜單。
11.3 編寫代碼
爲了在屏幕上顯示圖片,需要給出區域的左上角座標和區域的寬度和長度。因爲要使顯示區域是可變的,所以引進兩個全局變量
int m_Width, m_Height ;
定義在構造函數中。
顯示圖片就是先創建一個內存對象(HDC),把圖片讀入到這個內存對象這個內存,再用函數StretchBlt()把它映射到指定的屏幕區域。我們在OnPaint()函數中加入如下代碼:
else
{
//My code startup here
//Create 環境設備
CPaintDC dc(this);
//創建一個位圖對象
HBITMAP hbitmap = ::LoadBitmap(
::AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_MYBMP));
//Create a memory dc
HDC hMemDC = ::CreateCompatibleDC(NULL);
//put the bitmap into memory dv
SelectObject(hMemDC,hbitmap);
//Copy the memory dc into the screen
::StretchBlt(dc.m_hDC, //Draw
on screen field
0,0, m_Width, m_Height, //Place
of the screen
hMemDC, //Memory
DC map into screen
0,0,113,133, //Size
of this pictrue
SRCCOPY); //Copy
Mode
//My code END
......
當對話框的窗口大小被改變時系統會發送消息,因此我們需要添加消息映射WM_SIZE,並且在響應函數OnSize中把窗口的大小值傳遞給m_Width和m_Height,並讓窗口重畫。這函數爲:
void CMyBmpDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
m_Width = cx;
m_Height= cy;
Invalidate();
}
OnSize()中的變量cx,cy就是當前窗口(客戶區)的寬度和高度。
要在HELP菜單中打開About對話框,就在OnHelpAbout()函數中加入代碼:
CAboutDlg dlg;
dlg.DoModal();
給Open菜單項添加消息映射但不加代碼,給EXIT菜單項加入退出代碼OnOK()。編碼結束,編譯和運行。
11.4 代碼解析
HBITMAP hbitmap = ::LoadBitmap(
::AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_MYBMP));
創建一個HBITMAP類的對象hbitmap,雙冒號表示調用一個SDK的函數LoadBitmap(),它返回一個HBITMAP類的對象。它有兩個參數。第一個由:AfxGetInstanceHandle()函數提供,它是這個對象的句柄。第二個由宏MAKEINTRESOURCE()生成,它對應位圖資源。
下一行
HDC hMemDC = ::CreateCompatibleDC(NULL);
定義了一個HDC類型的對象,它表示一塊內存區域,由函數CreateCompatibleDC()創建。然後,讓內存區域和位圖對象hbitmap聯繫起來,這項任務由函數SelectObject()來實現。
現在,就可以用StretchBlt()函數來顯示圖形了。這項任務是由StretchBlt()函授來實現的,它有11個參數,列舉如下:
::StretchBlt(dc.m_hDC, //環境設備dc的可畫的對象
0,0, m_Width, m_Height, //屏幕區域
hMemDC, //內存對象源,它已經含有圖片信息。
0,0,113,133, //原圖片的大小
SRCCOPY); //Copy模式
dc.m_hDC是dc的一個數據成員,是“可畫圖”的對象。原圖片的大小必須事先查好。0