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 你是什么 GetDelete 你是什么 Create 在你的情况下,如果你 GetDC 获得一个客户 DC,那么你需要确保你ReleaseDC 完成后的结果。祝你好运。 【参考方案1】:

从周日开始,代码有七种不同的方式是错误的。即使您为响应 WhozCraig 的 cmets 做出了更改,它仍然是错误的。

对于初学者,您唯一可以致电BeginPaintEndPaint 的地方是回复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 消息。)

LOWORDHIWORD 宏应该永远用于提取光标坐标。这些可能会在多个监视器系统上返回错误的结果。相反,您应该使用GET_X_LPARAMGET_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() 函数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

怎么用C语言编写一个windows窗口?

C/C++网络编程详解(Windows版)

windows 定时执行回调函数(C/C++)

C - windows函数(套接字)的编译错误

根据两点画出直线,c++ windows编程 函数。帮忙实现

(转)c运行库c标准库windows API的区别和联系