HBITMAP 位图句柄
位图中,需要两个资源DC
BOOL BitBlt(_In_ HDC hdcDest, //指向目标设备环境的句柄
_In_ int nXDest, //指定目标矩形区域左上角的X轴逻辑坐标。
_In_ int nYDest, //指定目标矩形区域左上角的Y轴逻辑坐标。
_In_ int nWidth, //指定源在目标矩形区域的逻辑宽度。
_In_ int nHeight, //指定源在目标矩形区域的逻辑高度。
_In_ HDC hdcSrc, //指向资源设备环境的句柄。
_In_ int nXSrc, //指定源矩形区域左上角的X轴逻辑坐标。
_In_ int nYSrc, //指定源矩形区域左上角的Y轴逻辑坐标。
_In_ DWORD dwRop); //指定运算方式。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。
光栅操作代码
值 | 说明 |
---|---|
BLACKNESS | 表示使用与物理调色板的索引0相关的色彩来填充目标矩形区域,(对缺省的物理调色板而言,该颜色为黑色)。 |
DSTINVERT | 表示使目标矩形区域颜色取反。 |
MERGECOPY | 表示使用布尔型的AND(与)操作符将源矩形区域的颜色与特定模式组合一起。 |
MERGEPAINT | 通过使用布尔型的OR(或)操作符将反向的源矩形区域的颜色与目标矩形区域的颜色合并。 |
NOTSRCCOPY | 将源矩形区域颜色取反,于拷贝到目标矩形区域。 |
NOTSRCERASE | 使用布尔类型的OR(或)操作符组合源和目标矩形区域的颜色值,然后将合成的颜色取反。 |
PATCOPY | 将特定的模式拷贝到目标位图上。 |
PATPAINT | 通过使用布尔OR(或)操作符将源矩形区域取反后的颜色值与特定模式的颜色合并。然后使用OR(或)操作符将该操作的结果与目标矩形区域内的颜色合并。 |
PATINVERT | 通过使用XOR(异或)操作符将源和目标矩形区域内的颜色合并。 |
SRCAND | 通过使用AND(与)操作符来将源和目标矩形区域内的颜色合并。 |
SRCCOPY | 将源矩形区域直接拷贝到目标矩形区域。 |
SRCERASE | 通过使用AND(与)操作符将目标矩形区域颜色取反后与源矩形区域的颜色值合并。 |
SRCINVERT | 通过使用布尔型的XOR(异或)操作符将源和目标矩形区域的颜色合并。 |
SRCPAINT | 通过使用布尔型的OR(或)操作符将源和目标矩形区域的颜色合并。 |
WHITENESS | 使用与物理调色板中索引1有关的颜色填充目标矩形区域。(对于缺省物理调色板来说,这个颜色就是白色)。 |
辅助DC
创建一个兼容内存设备上下文环境
HDC CreateCompatibleDC(HDC hdc);//现有设备上下文环境的句柄,如果该句柄为NULL,该函数创建一个与应用程序的当前显示器兼容的内存设备上下文环境。
CreateCompatibleDc函数只适用于支持光栅操作的设备,应用程序可以通过调用GetDeviceCaps函数来确定一个设备是否支持这些操作。
当不再需要内存设备上下文环境时,可调用DeleteDC函数删除它。
代码展示
//WndProc消息处理函数中
switch (message)
{
//鼠标的左键按下
case WM_LBUTTONDOWN:
{
//1.得到设备环境句柄
hdc = GetDC(hWnd); //主DC
HDC hBkDC = CreatCompatibleDC(hdc);//创建兼容DC用来放位图资源的DC
//修改设备属性
//加载位图,从文件加载了资源图片
HBITMAP hbit = (HBITMAP)LoadImage(hInst, //实例句柄
_T("1.bmp"), //位图的路径
IMAGE_BITMAP, //加载什么类型的资源
0, //位图宽高,如果为0,自动匹配宽高
0,
LR_LOADFROMFILE); //表示从文件加载
//把hbit位图关联进了hBkDC
SeletcObject(hBkDC,hbit);
//3.绘图
BitBlt(hdc, //目标DC
50,50, //目标DC需要表现的左上角X,Y坐标
500,300, //目标DC上用500,300来表现资源DC需要操作过来的内容
hBkDC, //资源DC,里面有需要加载的资源
0,0, //拷贝到目标DC的资源起始裁剪X,Y坐标
SRCCOPY);//从资源DC怎么操作到目标DC,用源拷贝
//释放hbit位图资源
DeleteObject(hbit);
//自己创建的DC,需要释放资源hBkDC
DeleteDC(hBkDC);
//4.释放设备环境句柄,因为主DC是不能删除的,只能释放权限
ReleaseDC(hWnd,hdc);
}
break;
}
TransparentBlt,函数功能,该函数对指定的源设备环境中的矩形区域像素的颜色数据进行位块(bit_block)转换,并将结果置于目标设备环境。
//使用此函数需要加载库
#pragma comment (lib,"Msimg32.lib")
BOOL TransparentBlt(HDC hdcDest, //指定目标的句柄
int nXOriginDest, //指定目标矩形左上角的X轴坐标
int nYOriginDest, //指定目标矩形左上角的Y轴坐标
int nWidthDest, //指定目标矩形的宽度
int hHeightDest, //指定目标矩形的高度
HDC hdcSrc, //源图的句柄
int nXOriginSrc, //指定源矩形(左上角)的X轴坐标
int nYOriginSrc, //指定源矩形(左上角)的Y轴坐标
int nWidthSrc, //指定源矩形的宽度
int nHeightSrc, //指定源矩形的高度
UINT crTransparent);//源位图中的RGB值当作透明颜色
代码演示
//WndProc消息处理函数中
switch (message)
{
//鼠标的左键按下
case WM_LBUTTONDOWN:
{
//1.得到设备环境句柄
hdc = GetDC(hWnd); //主DC
HDC hBkDC = CreatCompatibleDC(hdc);//创建兼容DC用来放位图资源的DC
//修改设备属性
//加载位图,从文件加载了资源图片
HBITMAP hbit = (HBITMAP)LoadImage(hInst,_T("1.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//把hbit位图关联进了hBkDC
SeletcObject(hBkDC,hbit);
//3.绘图
BitBlt(hdc,50,50,500,300,hBkDC,0,0,SRCCOPY);
//释放hbit位图资源
DeleteObject(hbit);
//自己创建的DC,需要释放资源hBkDC
DeleteDC(hBkDC);
//加载自定义的人物的图片
HDC hHeroDC = CreatCompatibleDC(hdc);
//人物位图
HBITMAP hbHeroBit = (HBITMAP)LoadImage(hInst,_T("hero.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//关联人物位图
SeletcObject(hHeroDC,hbHeroBit);
//使人物背景色透明,最后一个参数为要透掉的背景色颜色
TransparentBlt(hdc, //主DC
0,0, //主DC用多大的矩形显示人物位图的X,Y坐标
90,88 //矩形显示人物位图的宽高,只有一个人物的矩形大小
hHeroDC, //人物位图的DC
0,0, //人物位图提取矩形的左上角X,Y坐标
360,352, //提取人物位图的宽高
RGB(255,255,255)); //人物图背景白色的用背景图来填充
//释放自己创建的任务DC和位图
DeleteObject(hbHeroBit);
DeleteDC(hHeroDC);
//4.释放设备环境句柄,因为主DC是不能删除的,只能释放权限
ReleaseDC(hWnd,hdc);
}
break;
}
//在资源中加载,会把资源也加载到exe中
HBITMAP LoadBitmap(HINSTANCE hInstance, //指向窗口实例的句柄
LPCTSTR lpBitmapName);//加载的位图资源名称
//可以使用宏MAKEINTRESOURCE来创建这个参数值
代码示例
//WndProc消息处理函数中
switch (message)
{
//鼠标的左键按下
case WM_LBUTTONDOWN:
{
//1.得到设备环境句柄
hdc = GetDC(hWnd);
HDC bitDC = CreatCompatibleDC(hdc);
//2.修改设备环境句柄
HBITMAP hbit = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BATMAP1)); //加载位图
//关联位图DC
SeletcObject(bitDC,hbit);
//3.绘图
BitBlt(hdc,50,50,1024,768,bitDC,0,0,SRCCOPY);
//释放画刷
DeleteObject(hbit);
//释放位图DC
DeleteDC(bitDC);
//4.释放设备环境句柄
ReleaseDC(hWnd,hdc);
}
break;
}
函数功能:该函数装载图标,光标,或位图。
HANDLE LoadImage(HINSTANCE hinst, //实例句柄
LPCTSTR lpszName,//文件路径名
UINT uType, //指定被加载图像类型
int cxDesired, //指定图标或光标的宽度,以像素为单位,如果给0,自动匹配宽高
int cyDesired, //指定图标或光标的高度,以像素为单位
UINT fuLoad); //根据复合值列表指定函数值
参数说明:
hinst :处理包含被装载图像模块的实例。若要装载OEM图像,则设此参数值为0。
lpszName:处理图像装载。如果参数hinst为non-NULL ,而且参数fuLoad省略LR_LOADFROMFILE的值时,那么参数lpszName是一个指向保留在hinst模块中装载的图像资源名称,并以NULL为结束符的字符串。
如果参数hinst为空,并且LR_LOADFROMFILE未被指定,那么这个参数低位字一定是被装载的OEM图像标识的。OEM图像标识符是在WINUSER.H头文件中定义的,下面列举出前缀的含义:
OBM_ OEM:位图;OIC_OEM图标;OCR_OEM:光标。
如果参数fuLoad包含LR_LOADFROMFILE值,那么参数lpszName是包含有图像的文件名。
uType:指定被装载图像类型。此参数可以为下列值,其含义如下:
值 | 说明 |
---|---|
IMAGE_BITMAP | 装载位图 |
IMAGE_CURSOR | 装载光标 |
IMAGE_ICON | 装载图标 |
cxDesired:指定图标或光标的宽度,以像素为单位。如果此参数为零并且参数fuLoad值为LR_DEFAULTSIZE,那么函数使用SM_CXICON或SM_CXCURSOR系统公制值设定宽度;如果此参数为零并且值LR_DEFAULTSIZE没有被使用,那么函数使用目前的资源宽度。
cyDesired:指定图标或光标的高度,以像素为单位。如果此参数为零并且参数fuLoad值为LR_DEFAULTSIZE,那么函数使用SM_CXICON或SM_CXCURSOR系统公制值设定高度;如果此参数为零并且值LR_DEFAULTSIZE没有被使用,那么函数使用目前的资源高度。
fuLoad:根据下面复合值列表指定函数值,值含义如下:
值 | 说明 |
---|---|
LR_DEFAULTCOLOR | 缺省标志,它不作任何事情,它的含义是“无LR_MONOCHROME” |
LR_CREATEDIBSECTION | 当参数uType指定为IMAGE_BITMAP时,使得函数返回一个DIB部分位图,而不是一个兼容的位图。这个标志在装载一个位图,而不是映射它的颜色到显示设备时非常有用。 |
LR_DEFAULTSIZE | 若 cxDesired或cyDesired被设为零,使用系统指定的公制值标识光标或图标的宽和高。如果这个参数不被设置且cxDesired或cyDesired被设为零,函数使用实际资源尺寸。如果资源包含多个图像,则使用第一个图像的大小。 |
LR_LOADFROMFILE | 根据参数lpszName的值装载图像。若标记未被给定,lpszName的值为资源名称。 |
LR_LOADMAP3DCOLORS | 查找图像的颜色表并且按下面相应的3D颜色表的灰度进行替换。 |
LR_MONOCHROME | 装载黑白图。 |
LR_SHARED | 若图像将被多次装载则共享。如果LR_SHARED未被设置,则再向同一个资源第二次调用这个图像时就会再装载一遍这个图像且返回不同的句柄。 |
函数说明:该函数不可用来装载jpg等格式图片,可使用gdi+函数GdipDrawImage装载jpg,png等格式图片。
两个缓冲的DC,让画面不闪屏
HBITMAP CreateCompatibleBitmap(HDC hdc, //设备环境句柄。
int nWidth, //指定位图的宽度,单位为像素。
int nHeight);//指定位图的高度,单位为像素。
//当你不再需要这个位图的时候,调用DeleteObject删除它。
需要与CreateCompatibleDC配合使用
代码示例如下
// 全局变量:
HINSTANCE hInst; // 当前实例
WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
HWND g_hWnd; //窗口句柄
BkBitmap BkMap;
Person Hero;
HDC g_buffDc; //缓冲区dc
HBITMAP g_buffBitmap;//缓冲区位图
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
// 初始化全局字符串
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_MY20170717WIN32, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY20170717WIN32));
MSG msg;
//设备环境句柄
HDC hdc = GetDC(g_hWnd);
//双缓冲
//一个缓冲的兼容DC
g_buffDc = CreateCompatibleDC(hdc);
//一个缓冲位图
g_buffBitmap = CreateCompatibleBitmap(hdc, 1024, 768);
//关联缓冲DC和缓冲位图
SeletcObject(g_buffDc,g_buffBitmap);
//资源加载
HDC hBkDC = CreatCompatibleDC(hdc);//创建兼容DC用来放位图资源的DC
//修改设备属性
//加载位图,从文件加载了资源图片
HBITMAP hbit = (HBITMAP)LoadImage(hInst,_T("1.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//把hbit位图关联进了hBkDC
SeletcObject(hBkDC,hbit);
//加载自定义的人物的图片
HDC hHeroDC = CreatCompatibleDC(hdc);
//人物位图
HBITMAP hbHeroBit = (HBITMAP)LoadImage(hInst,_T("hero.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//关联人物位图
SeletcObject(hHeroDC,hbHeroBit);
// 主消息循环:
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//无论是否有消息,都循环绘制
hdc = GetDC(g_hWnd);
BitBlt(g_buffDc,0,0,960,640,hBkDC,0,0,SRCCOPY); //绘制背景,背景画到缓冲DC
TransparentBlt(g_buffDc,0,0,90,88,hHeroDC,0,0,90,88,RGB(255,255,255)); //绘制人物
//最后一次把缓冲DC的内容拷贝到主DC
BitBlt(hdc,0,0,1024,768,g_buffDc,0,0,SRCCOPY);
//释放环境句柄
Release(g_hWnd,hdc);
}
//使用完成,释放所有位图资源
DeleteObject(hbit);
DeleteObject(hbHeroBit);
DeleteObject(g_buffBitmap);
//使用完成,释放所有DC资源
DeleteObject(hBkDC);
DeleteObject(hHeroDC);
DeleteDC(g_buffDc);
return (int) msg.wParam;
}