这是基本的,因此只需要一个来自绘图函数的代码片段,因为它具有必要的信息
void draw()
{
RECT rect;
GetClientRect(hwnd, &rect);
HBITMAP FRAME1ANIMDASH = NULL;
FRAME1ANIMDASH = (HBITMAP) LoadImage(NULL, "Hidden but correct pathname that won't be shown here", 0, LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_CREATEDIBSECTION);
if(FRAME1ANIMDASH == NULL)
{
MessageBox(NULL, "CANNOT LOAD", "CANNOT LOAD", MB_OK);
}
HDC device;
PAINTSTRUCT ps;
BITMAP bm;
GetObject(FRAME1ANIMDASH,sizeof(BITMAP),&bm);
HDC hdcdevice=CreateCompatibleDC(device);
SelectObject(hdcdevice,FRAME1ANIMDASH);
BitBlt(device,0,0,0,0,hdcdevice,0,0,SRCCOPY);
UpdateWindow(hwnd);
device=GetDC(hwnd);
DeleteDC(hdcdevice);
DeleteObject((HBITMAP) FRAME1ANIMDASH);
DWORD lastError = GetLastError();
cout << GetLastError();
}
Run Code Online (Sandbox Code Playgroud)
获取上一个错误显示错误6,这是一个无效的文件句柄.消息框显示,这意味着图像从未加载和失败,因此其后的代码不是主要关注点.
我正在尝试加载位图并将其放在我创建的Win32窗口上.
不需要其他代码,因为没有任何具体的任何其他代码可以导致整体可能的答案.告诉我如何才能成功加载图像.
你来电GetLastError()太晚了.此时错误代码毫无意义,因为它可能会被您调用的任何其他函数覆盖.您必须在失败后GetLastError() 立即致电LoadImage():
HBITMAP FRAME1ANIMDASH = (HBITMAP) LoadImage(...);
if (FRAME1ANIMDASH == NULL)
{
DWORD lastError = GetLastError();
cout << "CANNOT LOAD IMAGE, ERROR " << lastError;
MessageBox(NULL, "CANNOT LOAD IMAGE", "CANNOT LOAD IMAGE", MB_OK);
return; // <-- add this, too!
}
Run Code Online (Sandbox Code Playgroud)
LoadImage()失败的原因是因为您未LR_LOADFROMFILE按照LoadImage()文档指定标志,而不是正确请求图像大小:
lpszName [in]
...
如果hinst参数为NULL并且fuLoad参数省略了LR_LOADFROMFILE值,则lpszName指定要加载的OEM映像.OEM映像标识符在Winuser.h中定义,并具有以下前缀.
...
如果fuLoad参数包含LR_LOADFROMFILE值,则lpszName是包含独立资源(图标,光标或位图文件)的文件的名称.因此,将hinst设置为NULL....
cxDesired [in]
...
... 如果此参数为零且未使用LR_DEFAULTSIZE,则该函数使用实际资源宽度....
cyDesired [中]
...
... 如果这个参数是零,不使用LR_DEFAULTSIZE,该函数使用的实际资源的高度....
fuLoad [in]
...
LR_DEFAULTSIZE
... 如果未指定此标志且cxDesired和cyDesired设置为零,则该函数使用实际资源大小.
...
LR_LOADFROMFILE
...从lpszName(图标,光标或位图文件)指定的文件中加载独立图像.
所以看起来应该更像这样:
HBITMAP FRAME1ANIMDASH = (HBITMAP) LoadImage(NULL, "pathname", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
Run Code Online (Sandbox Code Playgroud)
解决之后,代码还有其他问题.
您正在CreateCompatibleDC()使用未初始化的 HDC变量进行调用,而不是检查CreateCompatibleDC()失败的结果.你的电话GetDC()是在错误的地方,需要将其移到上方CreateCompatibleDC().而你泄漏HDC是GetDC()返回,你需要调用ReleaseDC()释放它.
您还要告知BitBlt()复制像素的0x0矩形,而不是使用BITMAP结构中位图的真实尺寸,甚至RECT是您要从中检索的窗口GetClientRect().
尝试更像这样的东西:
void draw()
{
HBITMAP FRAME1ANIMDASH = (HBITMAP) LoadImage(NULL, "pathname", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
if (FRAME1ANIMDASH == NULL)
{
DWORD lastError = GetLastError();
cout << "CANNOT LOAD IMAGE, ERROR " << lastError;
MessageBox(NULL, "CANNOT LOAD IMAGE", "CANNOT LOAD IMAGE", MB_OK);
return;
}
HDC hdcWnd = GetDC(hwnd);
if (hdcWnd === NULL)
{
DeleteObject(FRAME1ANIMDASH);
cout << "CANNOT GET WINDOW DC";
MessageBox(NULL, "CANNOT GET WINDOW DC", "CANNOT GET DC", MB_OK);
return;
}
HDC hdcMem = CreateCompatibleDC(hdcWnd);
if (hdcMem == NULL)
{
ReleaseDC(hwnd, hdcWnd);
DeleteObject(FRAME1ANIMDASH);
cout << "CANNOT CREATE COMPATIBLE DC";
MessageBox(NULL, "CANNOT CREATE COMPATIBLE DC", "CANNOT CREATE DC", MB_OK);
return;
}
BITMAP bm;
GetObject(FRAME1ANIMDASH, sizeof(BITMAP), &bm);
HBITMAP oldBm = (HBITMAP) SelectObject(hdcMem, FRAME1ANIMDASH);
BitBlt(hdcWnd, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, oldBm);
DeleteDC(hdcMem);
ReleaseDC(hwnd, hdcWnd);
DeleteObject(FRAME1ANIMDASH);
UpdateWindow(hwnd);
}
Run Code Online (Sandbox Code Playgroud)
话虽如此,PAINTSTRUCT变量意味着您的代码正在WM_PAINT消息处理程序中使用.如果这是真的,你应该使用BeginPaint()而不是GetDC()让目标HDC绘制:
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
draw(hdc);
EndPaint(hwnd, &ps);
break;
};
Run Code Online (Sandbox Code Playgroud)
void draw(HDC hdcTarget)
{
HBITMAP FRAME1ANIMDASH = (HBITMAP) LoadImage(NULL, "pathname", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
if (FRAME1ANIMDASH == NULL)
{
DWORD lastError = GetLastError();
cout << "CANNOT LOAD IMAGE, ERROR " << lastError;
// DO NOT use MessageBox() in a WM_PAINT handler,
// You will trigger an endless re-paint loop!
return;
}
HDC hdcMem = CreateCompatibleDC(hdcTarget);
if (hdcMem == NULL)
{
DeleteObject(FRAME1ANIMDASH);
cout << "CANNOT CREATE COMPATIBLE DC";
return;
}
BITMAP bm;
GetObject(FRAME1ANIMDASH, sizeof(BITMAP), &bm);
HBITMAP oldBm = (HBITMAP) SelectObject(hdcMem, FRAME1ANIMDASH);
BitBlt(hdcWnd, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, oldBm);
DeleteDC(hdcMem);
DeleteObject(FRAME1ANIMDASH);
}
Run Code Online (Sandbox Code Playgroud)
否则,如果你在外面使用你的代码WM_PAINT,那么代码几乎没用,因为它UpdateWindow()会触发一次擦除你的绘图的重新绘制.在窗口上持续图纸必须使用来完成WM_PAINT(除非您使用UpdateLayeredWindow()一个WS_EX_LAYERED窗口).
| 归档时间: |
|
| 查看次数: |
675 次 |
| 最近记录: |