我编写简单的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;
}
答案 0 :(得分:3)
关于星期日的七种不同方式,代码是错误的。即使在你为回应WhozCraig的评论而做出的改变之后,它仍然是错误的。
首先,您可以拨打BeginPaint
和EndPaint
的唯一地方是回复WM_PAINT
消息。您正在尝试调用这些函数以响应WM_LBUTTONDOWN
消息。那不行。您要做的是从WM_PAINT
消息处理程序中触发WM_LBUTTONDOWN
消息,您可以通过调用InvalidateRect()
函数,传递窗口句柄和{{1}来执行此操作。使矩形无效(使整个窗口无效)。然后,在NULL
邮件处理程序内,您可以调用WM_PAINT
/ BeginPaint
并进行绘图。如果您希望绘图不同,具体取决于鼠标左键是否已关闭,您可以在EndPaint
消息处理程序内设置一个标志,并在WM_LBUTTONDOWN
消息内测试该标志的值处理程序,或者您可以使用WM_PAINT
之类的内容来确定鼠标按钮是否已关闭(GetKeyState
)。
您也在泄漏GDI对象,因为您没有正确释放/销毁它们。需要通过调用VK_LBUTTON
来销毁已加载LoadBitmap
的位图。 (但是,在DeleteObject
消息处理程序内重复加载位图会导致性能不佳。相反,更喜欢一次加载位图以响应WM_PAINT
消息,将其句柄缓存在全局中或类级变量,必要时使用它,并通过该句柄销毁位图以响应WM_CREATE
消息。)
{<1}}和WM_DESTROY
宏从不用于提取光标坐标。这些可能会在多个监视器系统上返回错误的结果。相反,您应该使用LOWORD
和HIWORD
。有关GET_X_LPARAM
消息的MSDN文档中特别提到了这一点。 始终阅读您不熟悉的文档!
最后,窗口过程的签名也完全错误。我不知道你在哪里获得了这个签名,但是你不仅有非标准的参数名称来掩盖这些参数的实际含义,而且你的类型也是错误的。窗口过程如下所示:
GET_Y_LPARAM
通过黑客攻击学习Windows API编程非常困难,特别是如果您没有阅读MSDN文档的规范。如果您真的想学习它,可以考虑购买一本书,如Charles Petzold's classic Programming Windows, 5th edition(是的,您需要第5版,而不是新版本)。