这一篇来说说位图的输出。相信大家对背景图片都不陌生,这也是游戏的必要元素了。
在windows编程中,使用GDI来输出位图的方式其实很简单。
它就是调用了一下
WINGDIAPI BOOL WINAPI BitBlt(
_In_ HDC hdc,
_In_ int x, _
In_ int y,
_In_ int cx,
_In_ int cy,
_In_opt_ HDC hdcSrc,
_In_ int x1,
_In_ int y1,
_In_ DWORD rop);
这个方法,来输出位图,参数我们等等可以通过下面我写的代码来深刻理解一下。所以,这里就知道有这么几个参数就行了。
WINGDIAPI BOOL WINAPI StretchBlt(
_In_ HDC hdcDest,
_In_ int xDest,
_In_ int yDest,
_In_ int wDest,
_In_ int hDest,
_In_opt_ HDC hdcSrc,
_In_ int xSrc,
_In_ int ySrc,
_In_ int wSrc,
_In_ int hSrc,
_In_ DWORD rop);
这个和上面一个类似,不过就是实现缩放的显示。
好,我们可以注意到,上面的两个方法都需要传入两个设备环境。这里就直接说它们是通过后备的设备环境的东西,来映射到我们的设备环境中来。即后备环境有什么,我们只是拷贝到当前设备环境上而已。了解这个就行了。
不过,位图输出之前,我们需要把位图加载出来,我们调用的函数是:
WINUSERAPI
HANDLE
WINAPI
LoadImageW(
_In_opt_ HINSTANCE hInst,
_In_ LPCWSTR name,
_In_ UINT type,
_In_ int cx,
_In_ int cy,
_In_ UINT fuLoad);
具体怎么用,也是先不用着急知道,等等看下代码就知道了,这里需要注意的是你需要把你的位图图片放在当前目录。就是和你的.cpp文件一起的文件夹上。
好,现在直接看下我写的代码吧:
#include <windows.h>
//函数声明
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);//窗口处理函数
void init();//初始化设备环境
void Render();//渲染函数
void CleanUp();//释放设备环境
//变量定义
HWND hwnd;
HDC hdc,hdcmen;
BITMAP bm;
HBITMAP hbm;
//主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)
{
//设计窗口类
WNDCLASS wndclass = {
CS_HREDRAW | CS_VREDRAW,
WndProc,
0,
0,
hInstance,
LoadIcon(NULL, IDI_APPLICATION),
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)GetStockObject(WHITE_BRUSH),
NULL,
TEXT("MYDEMO")
};
//注册窗口类
RegisterClass(&wndclass);
//创建窗口类
hwnd = CreateWindow(
TEXT("MYDEMO"),
TEXT("MyDemo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
//显示窗口
ShowWindow(hwnd, nCmdShow);
//更新窗口
UpdateWindow(hwnd);
//初始化
init();
//消息循环
MSG Msg;
BOOL bRet;
PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE);
while (Msg.message != WM_QUIT)
{
bRet = PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE);
if (bRet)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
Render();
}
CleanUp();
return Msg.wParam;
}
//窗口过程处理函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
//初始化函数
void init()
{
if (!hwnd)
{
return;
}
//设备环境获取
hdc = GetDC(hwnd);
//获取兼容设备环境
hdcmen = CreateCompatibleDC(hdc);
//加载位图
hbm = (HBITMAP)LoadImage(
NULL,
L"flower.bmp",
IMAGE_BITMAP,
0,
0,
LR_LOADFROMFILE);
//将位图选入设备环境
SelectObject(hdcmen, hbm);
//获取位图大小
GetObject(hbm, sizeof(BITMAP), &bm);
}
//渲染
void Render()
{
if (hdc)
{
//正常位图输出
BitBlt(hdc, 200, 0, bm.bmWidth,bm.bmHeight,hdcmen, 0, 0, SRCCOPY);
//缩放模式设置,一般采用COLORONCOLOR该模式来处理彩色点阵图
SetStretchBltMode(hdc, COLORONCOLOR);
//位图缩放输出
/************************************************
这里在设备环境中从(0,0)坐标并以宽为200,高为 200输出该位图,
而该位图是从后备设备环境hdcmen中从(0,0)坐标开始,宽高为该位图大小的位图截取出来
从而实现缩放显示
*************************************************/
StretchBlt(hdc, 0, 0, 200, 200, hdcmen, 0, 0, bm.bmWidth,bm.bmHeight, SRCCOPY);
}
}
//清除设备环境
void CleanUp()
{
//清除位图相关
DeleteObject(hbm);
DeleteDC(hdcmen);
ReleaseDC(hwnd, hdc);
}
结果如下:
好了,其实实现背景图片的输出其实并不难,对吧~