47.位图资源显示HBITMAP、BITMAP、LoadBitmap、GetObject、CreateCompatibleDC、SelectObject、BitBlt

本文介绍了Windows编程中如何加载并显示位图资源的步骤,包括使用LoadBitmap加载位图,通过GetObject获取位图信息,创建兼容的内存设备上下文(hdcMem),使用SelectObject选择对象,最后通过BitBlt函数将内存位图拷贝到窗口上显示。

先说说HBITMAP和BITMAP的区别,及两个结构
HBITMAP是一个句柄

DECLARE_HANDLE(HBITMAP);
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name

BITMAP是一个结构,用于存储位图的信息

/* Bitmap Header Definition */
typedef struct tagBITMAP
  {
    LONG        bmType; //类型,必须为0
    LONG        bmWidth; //位图宽度
    LONG        bmHeight; //位图高度
    LONG        bmWidthBytes; //每一行像素所在的byte数
    WORD        bmPlanes;//颜色平面数
    WORD        bmBitsPixel;//像素的位数
    LPVOID      bmBits;//位图内存指针
  } BITMAP, *PBITMAP, NEAR *NPBITMAP, FAR *LPBITMAP;

先说下位图资源显示的步骤
1.加载位图资源
HBITMAP hBitmap = LoadBitmap((HINSTANCE)hWnd,MAKEINTRESOURCE(IDB_BITMAP1));

/*
 * Resource Loading Routines
 */

WINUSERAPI
HBITMAP
WINAPI
LoadBitmapA(
    __in_opt HINSTANCE hInstance,
    __in LPCSTR lpBitmapName);
WINUSERAPI
HBITMAP
WINAPI
LoadBitmapW(
    __in_opt HINSTANCE hInstance,
    __in LPCWSTR lpBitmapName);
#ifdef UNICODE
#define LoadBitmap  LoadBitmapW
#else
#define LoadBitmap  LoadBitmapA
#endif // !UNICODE

2.获取位图信息
GetObject(hBitmap,sizeof(BITMAP),&bitmap);

WINGDIAPI int   WINAPI GetObjectA(__in HANDLE h, __in int c, __out_bcount_opt(c) LPVOID pv);
WINGDIAPI int   WINAPI GetObjectW(__in HANDLE h, __in int c, __out_bcount_opt(c) LPVOID pv);
#ifdef UNICODE
#define GetObject  GetObjectW
#else
#define GetObject  GetObjectA
#endif // !UNICODE

3.创建内存绘图设备环境上下文,创建与设备环境兼容的内存环境
HDC hdcMem = CreateCompatibleDC(hdc);

WINGDIAPI HDC     WINAPI 
CreateCompatibleDC( 
__in_opt HDC hdc //绘图设备上下文
);

4.把GDI位图对象选入内存设备环境
SelectObject 该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
SelectObject(hdcMem,hBitmap);

__gd
#include <iostream> #include <windows.h> #include <vector> #include <cstdio> #include <tchar.h> #include <sal.h> // 引入 SAL 注解支持 #pragma comment(lib,"Winmm.lib")// 链接声音的 PlaySound 函数需要导入 winmm 库 #include <io.h> #include <fcntl.h> #include <windows.h> #include <gdiplus.h> using namespace Gdiplus; #pragma comment (lib,"Gdiplus.lib") // 初始化GDI+ ULONG_PTR gdiplusToken; GdiplusStartupInput gdiplusStartupInput; //GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // 加载并显示位图 void LoadAndDisplayBitmap(HWND hwnd, const wchar_t* filename) { HDC hdc = GetDC(hwnd); Graphics graphics(hdc); // 加载位图 Bitmap* bitmap = new Bitmap(filename); if (bitmap->GetLastStatus() != Ok) { MessageBox(hwnd, L"无法加载位图文件", L"错误", MB_OK | MB_ICONERROR); delete bitmap; return; } // 获取窗口尺寸 RECT rect; GetClientRect(hwnd, &rect); // 绘制位图 graphics.DrawImage(bitmap, 0, 0, rect.right, rect.bottom); // 清理资源 delete bitmap; ReleaseDC(hwnd, hdc); } HINSTANCE g_hInst; int g_windowWidth = 1000; int g_windowHeight = 800; LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnViewLargeIcons(HWND hWnd, UINT nCheckedID); void PrintTopMenuText(HWND hWnd); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { AllocConsole(); FILE* stream; freopen_s(&stream, "CONOUT$", "w", stdout); GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); const wchar_t CLASS_NAME[] = L"SmoothDrawDemo"; { UINT cp = GetACP(); // 获取当前系统 ANSI 代码页 printf("当前系统 ANSI 代码页: %u\n", cp); UINT oemcp = GetOEMCP(); // 获取 OEM 代码页(控制台) printf("当前控制台 OEM 代码页: %u\n", oemcp); } // 示例1:直接输出原始命令行 //MessageBoxA(NULL, lpCmdLine, "原始命令行参数", MB_OK); g_hInst = hInstance; WNDCLASS wc = {}; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; //wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); // 注意:使用绝对路径或相对路径,这里使用相对路径"my_icon.ico" //wc.hIcon = (HICON)LoadImage(NULL, L"res\\IDI_ICON_SMALL.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED); // 如果加载失败,可以尝试使用默认图标 if (wc.hIcon == NULL) { wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); } wc.hCursor = LoadCursor(NULL, IDC_CROSS); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2); HBRUSH hBrush = CreateSolidBrush(RGB(255, 192, 203)); wc.hbrBackground = (HBRUSH)(hBrush); if (!RegisterClass(&wc)) { MessageBox(NULL, L"注册窗口类失败", L"错误", MB_ICONERROR); return 1; } HWND hwnd = CreateWindowEx( 0, CLASS_NAME, L"无延迟绘图示例", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, g_windowWidth, g_windowHeight, NULL, NULL, hInstance, NULL ); if (hwnd == NULL) { MessageBox(NULL, L"创建窗口失败", L"错误", MB_ICONERROR); return 1; } //EnableMenuItem((HMENU)IDR_MENU1, ID_FILE_NEW, MF_DISABLED | MF_GRAYED); ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); MSG msg = {}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc, hdcMem; HBITMAP hBitmap; BITMAP bmp; switch (uMsg) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); hdcMem = CreateCompatibleDC(hdc); //hBitmap = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_GIRL)); hBitmap = (HBITMAP)LoadImage(NULL, TEXT("BitMap.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); SelectObject(hdcMem, hBitmap); // 绘图操作 SetBkMode(hdcMem, TRANSPARENT); TextOut(hdcMem, 10, 10, TEXT("窈窕淑女君子好逑"), _tcslen(TEXT("窈窕淑女君子好逑"))); // 把内存位图复制到窗口客户区中 GetObject(hBitmap, sizeof(bmp), &bmp); BitBlt(hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY); EndPaint(hwnd, &ps); DeleteObject(hBitmap); DeleteDC(hdcMem); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); } 为什么无法加载图片到窗口
最新发布
08-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值