2016-11-27 47 views
0

我编写简单的windows c程序来在按下鼠标左键的地方显示位图。在第一次点击我的鼠标左键时,会出现位图。但在第二次单词时,位图没有显示在我点击鼠标左键的地方。Windows C:LoadBitmap()函数不起作用

这里是我的代码.........

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; 
} 
+0

'DeleteDC(hdc);'不应该在那儿;从'BeginPaint'返回的DC的设备上下文清理由您已经调用的'EndPaint'管理。更重要的是,'BeginPaint' /'EndPaint'根本不应该被调用*,除非响应'WM_PAINT',否则不会。 – WhozCraig

+0

谢谢你WhozCraig,我已经删除了BeginPaint(),EndPaint()和DeleteDC()。相反,我使用了GetDC()函数。我的工作...... – Sai

+0

请记住:'释放'你得到'和'删除'你创建的'在你的情况下,如果你'GetDC'获得一个客户DC,那么你需要确保' ReleaseDC结束后会得到它。祝你好运。 – WhozCraig

回答

3

的代码是错周日七种不同的方式。即使在您为响应WhozCraig的评论而做出的更改后,仍然是错误的。

对于初学者,唯一允许拨打BeginPaintEndPaint的地方是对WM_PAINT消息的回应。您正尝试调用这些函数以响应WM_LBUTTONDOWN消息。这是行不通的。你需要做的是在你的WM_LBUTTONDOWN消息处理程序中触发WM_PAINT消息,通过调用InvalidateRect()函数,传递窗口句柄和NULL使矩形失效(使整个窗口无效),你可以做到这一点。然后,在WM_PAINT消息处理程序的内部,您可以拨打BeginPaint/EndPaint并进行绘制。如果您希望图形因鼠标左键是否关闭而不同,您可以在WM_LBUTTONDOWN消息处理程序内设置一个标志,并在WM_PAINT消息处理程序内测试该标志的值,也可以使用类似于GetKeyState来确定鼠标按钮是否关闭(VK_LBUTTON)。

您也在泄漏GDI对象,因为您没有正确释放/销毁它们。通过调用DeleteObject需要销毁已加载了LoadBitmap的位图。 (但是,在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) 
{ 
    ... 
} 

这是极其困难的只是黑客各地,特别是如果你没有纪律有关阅读MSDN文档,学习Windows API编程。如果你真的想学习它,可以考虑购买一本书,如Charles Petzold's classic Programming Windows, 5th edition(是的,你需要第5版,而不是更新的版本)。