視窗:基於基類CApplication-位圖(六乙)
老子最近研究位圖(就是bmp,可以理解為Windows下的圖片),相當之煩人,書上寫的都是錯的!氣死了,於是潛心鑽研,完成了個小例子,發商來供初學者學習吧。
本次將把一個位圖文件(bitmap1.bmp)添加到工程中,主程式還是老樣子為一個全屏帶菜單欄的窗口。通過點選菜單“檔案”->“裝載”將此圖片(拉伸,如有必要)顯示在窗口中。如下圖。就這麽簡單。
程式運行效果:
工程文件點擊這裡下載。(注:因海底光纜震斷,恢復後吾再將其放上來)
注意:本例子是將位圖文件作爲資源倒入工程中,故編譯出來的僅為一個exe文件,圖片已編譯到exe文件中了。
新建個工程“圖片乙”,將CApplication.h、CApplication.cpp啥的都導入了,再造個main.h、main.cpp等等,把架子搭起來,不懂的同學不妨從頭閲讀本系列。
首先我們得在工程中添加圖片資源,“插入”->“資源”->點擊“插入資源”對話框右側之“倒入”按鈕,選“所有文件”,然後再選中你慾插入的bmp文件,比如這裡我就從軒轅劍裏r了幅圖出來,因爲我發現他們都喜歡那軒轅劍做例子,^_^。那圖的資源ID就叫“IDB_BITMAP1”吧。
注意:如果你插入的位圖顔色超過256色,比如是24位色的,那麽VC將無法預覽、編輯,不用理會它。
現在來看看代碼:
先看main.cpp文件
/ main.cpp //
#include <windows.h>
#include "CApplication.h"
#include "main.h"
#include "extra.h"
#include "resource.h"
CApplication App;
//主窗口處理過程
LRESULT CALLBACK WinProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
static HINSTANCE hInstance;
HWND hwndDesktop;
static HDC hdcMem;
HDC hdc, hdcDesktop;
static HBITMAP hBitmap;
BITMAP bitmap;
static UINT cxScreen, cyScreen, cxClient, cyClient;
PAINTSTRUCT ps;
//消息處理
switch(uMsg)
{
//創建
case WM_CREATE:
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
hwndDesktop = GetDesktopWindow();
hdcDesktop = GetDC(hwndDesktop);
hdcMem = CreateCompatibleDC(hdcDesktop);
cxScreen = GetDeviceCaps(hdcDesktop, HORZRES);
cyScreen = GetDeviceCaps(hdcDesktop, VERTRES);
hBitmap = CreateCompatibleBitmap(hdcDesktop,
cxScreen, cyScreen);
//將hBitmap裝入hdcMem
SelectObject(hdcMem, hBitmap);
//ShowWindow(hWnd, SW_HIDE);
BitBlt(hdcMem, 0, 0,
cxScreen, cyScreen,
hdcDesktop, 0, 0, SRCCOPY);
ShowWindow(hWnd, SW_SHOW);
DeleteDC(hdcDesktop);
return 0;//創建閉合
//尺寸改變
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;//尺寸改變閉合
//繪圖
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
if(hBitmap)
{
//
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBitmap);
//
SetStretchBltMode(hdc, COLORONCOLOR);
StretchBlt(hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, cxScreen, cyScreen,SRCCOPY);
DeleteDC(hdcMem);
}
EndPaint(hWnd, &ps);
return 0;
//菜單之使用
case WM_COMMAND:
switch(LOWORD(wParam))
{
//檔案->退出
case IDM_FILE_EXIT:
SendMessage(hWnd, WM_CLOSE, 0, 0);
return 0;
//檔案->裝載
case IDM_FILE_LOAD:
if(hBitmap)
{
DeleteObject(hBitmap);
hBitmap = NULL;
}
hBitmap = (HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_BITMAP1),
IMAGE_BITMAP,
cxClient, cyClient,
LR_CREATEDIBSECTION);
//強制重繪
InvalidateRect(hWnd, NULL, TRUE);
break;
//幫助->關於
case IDM_HELP_ABOUT:
DialogBox(hInstance,
MAKEINTRESOURCE(IDD_ABOUT),
hWnd,
(DLGPROC)DialogAboutProc);
return 0;
}
return 0;//菜單閉合
}//消息處理閉合
//默認消息處理
return App.MsgProc(hWnd, uMsg, wParam, lParam);
}//主窗口處理過程閉合
//主程式入口
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//載入圖標
App.Set_hIcon(hInstance, IDI_ICON1);
//載入光標
App.Set_hCursor(hInstance, IDC_CURSOR1);
//載入菜單
App.Set_hMenu(hInstance, IDR_MENU1);
//窗口大小設置
App.isFullScreen(TRUE);
//App.SetScreenW(400);
//App.SetScreenH(300);
//客戶區背景色
//App.SetClientBKColor(BLACK_BRUSH);
//創建窗口
App.CreateWin(WinProc,
hInstance,
"圖片乙",
WS_OVERLAPPEDWINDOW);
//運行默認的消息循環機制
return App.RunDefault();
}
/ eof ///
所有的新東西都在這個文件裏,來重點分析一下:
首先創建了一個BITMAP對象bitmap,然後創建了一個BITMAP的句柄hBitmap,這個句柄用來“句柄”待會兒LoadImage函數打開的位圖。
BITMAP bitmap;
static HBITMAP hBitmap;
在菜單“裝載”選項的處理中先用if清理現場,然後再
hBitmap = (HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_BITMAP1),
IMAGE_BITMAP,
cxClient, cyClient,
LR_CREATEDIBSECTION);
參數MAKEINTRESOURCE(IDB_BITMAP1)指定打開的資源為“IDB_BITMAP1”,就是我們剛才載入的位圖,得到器句柄後“InvalidateRect(hWnd, NULL, TRUE);”強制重繪。
在“case WM_PAINT:”繪圖中利用剛才的句柄hBitmap將圖片拉伸(如有必要)繪製在客戶區内。即完。