Windows C:LoadBitmap() 函数不起作用
Posted
技术标签:
【中文标题】Windows C:LoadBitmap() 函数不起作用【英文标题】:Windows C: LoadBitmap() function is not working 【发布时间】:2016-11-27 09:49:11 【问题描述】:我编写了一个简单的windows c程序来在按下鼠标左键的地方显示位图。第一次单击鼠标左键时,会出现位图。但是在第二次上,位图没有显示在我单击鼠标左键的地方。
这是我的代码.........
LRESULT CALLBACK myHandler(HWND hw, UINT m, UINT mextra, long co_ord)
HDC hdc, hmemdc;
PAINTSTRUCT ps;
HBITMAP hbmp;
RECT r;
HGDIOBJ holdbmp;
int x, y;
switch(m)
case WM_LBUTTONDOWN:
hdc = BeginPaint(hw,&ps);
hmemdc = CreateCompatibleDC(hdc);
hbmp = LoadBitmap(h, MAKEINTRESOURCE(IDB_BITMAP1));
holdbmp = SelectObject(hmemdc, hbmp);
x = LOWORD(co_ord);
y = HIWORD(co_ord);
BitBlt(hdc, x, y, 190, 220, hmemdc, 0, 0, SRCCOPY);
EndPaint(hw,&ps);
SelectObject(hmemdc, holdbmp);
DeleteObject(hbmp);
DeleteDC(hmemdc);
DeleteDC(hdc);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hw,m,mextra,co_ord);
return 0L;
【问题讨论】:
DeleteDC(hdc);
根本不应该在那里;从 BeginPaint
返回的 DC 的设备上下文清理由您已经调用的 EndPaint
管理。更重要的是,BeginPaint
/EndPaint
根本不应该被称为 ,除非是为了响应 WM_PAINT
,这不是。
谢谢 WhozCraig,我已删除 BeginPaint()、EndPaint() 和 DeleteDC()。相反,我使用了 GetDC() 函数。我工作....
记住:Release
你是什么 Get
和 Delete
你是什么 Create
在你的情况下,如果你 GetDC
获得一个客户 DC,那么你需要确保你ReleaseDC
完成后的结果。祝你好运。
【参考方案1】:
从周日开始,代码有七种不同的方式是错误的。即使您为响应 WhozCraig 的 cmets 做出了更改,它仍然是错误的。
对于初学者,您唯一可以致电BeginPaint
和EndPaint
的地方是回复WM_PAINT
消息。您正在尝试调用这些函数以响应 WM_LBUTTONDOWN
消息。那是行不通的。您要做的是从您的WM_LBUTTONDOWN
消息处理程序中触发WM_PAINT
消息,您可以通过调用InvalidateRect()
函数、传递您的窗口句柄和NULL
来使矩形无效(到使整个窗口无效)。然后,在WM_PAINT
消息处理程序中,您可以调用BeginPaint
/EndPaint
并进行绘图。如果您希望绘图根据鼠标左键是否按下而有所不同,您可以在WM_LBUTTONDOWN
消息处理程序内设置一个标志并在WM_PAINT
消息处理程序内测试该标志的值,或者您可以使用GetKeyState
之类的东西来确定鼠标按钮是否按下(VK_LBUTTON
)。
您还泄漏了 GDI 对象,因为您没有正确释放/销毁它们。使用LoadBitmap
加载的位图需要通过调用DeleteObject
来销毁。 (但是,在 WM_PAINT
消息处理程序中重复加载位图会导致性能下降。相反,更喜欢单次加载位图以响应 WM_CREATE
消息,将其句柄缓存在全局或类级别变量,在必要时使用它,并通过该句柄销毁位图以响应WM_DESTROY
消息。)
LOWORD
和 HIWORD
宏应该永远用于提取光标坐标。这些可能会在多个监视器系统上返回错误的结果。相反,您应该使用GET_X_LPARAM
和GET_Y_LPARAM
。这在 WM_LBUTTONDOWN
消息的 MSDN 文档中特别提到。 总是阅读你不熟悉的东西的文档!
最后,您的窗口过程的签名也完全错误。我不知道你从哪里得到那个签名,但你不仅有非标准的参数名称会掩盖这些参数的实际含义,而且你有错误的类型。一个窗口过程如下所示:
LRESULT CALLBACK myHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
...
仅靠四处乱窜来学习 Windows API 编程是极其困难的,尤其是如果您不习惯阅读 MSDN 文档。如果你真的想学,可以考虑买一本书,比如Charles Petzold's classic Programming Windows, 5th edition(是的,你需要的是第 5 版,而不是新版)。
【讨论】:
以上是关于Windows C:LoadBitmap() 函数不起作用的主要内容,如果未能解决你的问题,请参考以下文章