检查线程中的WM_LBUTTONDOWN
Check WM_LBUTTONDOWN in a Thread
我有一个WindowProcess,当鼠标左键按下时,它会创建一个线程:
case WM_LBUTTONDOWN: {
InvalidateRect(hwnd, NULL, TRUE);
_beginthread(mouseMoveThread, 0, ¶ms);
return 0;
}
并且线程鼠标MoveThread设置像素,在左键关闭期间:
void mouseMoveThread(PVOID pvoid)
{
HDC hdc;
PPARAMS pparams = (PPARAMS) pvoid;
static POINT pt[MAXPOINTS];
static int iCount;
while(WM_LBUTTONDOWN){
if(GetCursorPos(&pt[iCount]))
{
if (ScreenToClient(pparams->hwnd, &pt[iCount]))
{
iCount++;
hdc = GetDC(pparams->hwnd);
SetPixel(hdc, pt[iCount-1].x, pt[iCount-1].y,(COLORREF)RGB(0,255,0));
ReleaseDC(pparams->hwnd, hdc);
}
}
}
_endthread();
}
但是我如何检查 while-循环,左按钮是否关闭???
您的 GUI 线程应将相应的消息转发到呈现线程。也许对于您的情况来说,这是WM_MOUSEMOVE
,WM_LBUTTONDOWN
,WM_LBUTTONUP
。例如,您可以使用Event
对象进行通信。
如果您的"渲染线程"有自己的消息循环,则AttachThreadInput
可能会感兴趣。
但这似乎毫无意义。只需在主线程中执行此操作;无论如何,没有理由在这里为最好在 GUI 线程中完成的事情创建一个单独的线程。您正在尝试处理WM_MOUSEMOVE
事件以跟随鼠标光标。这只需要处理 GUI 线程中的事件。你这样做的方式,你会做完全相同的事情,除了来自不同的线程。您引入了很多卷积,但绝对没有任何收获。
关于您的代码的其他一些评论:
- 您正在调用
InvalidateRect
,这将引起WM_PAINT
.SetPixel
是一个"流氓"调用 - 系统不会跟踪这一点,如果你在WM_PAINT
中绘制,那么你的SetPixel
调用将始终被覆盖。 出于这个原因,大多数应用程序只做WM_PAINT
绘画 . - 如果您不是在
WM_PAINT
中绘画,如果您的窗口被隐藏并重新显示,您的SetPixel
调用仍将被遗忘。所有这些绘画业务的正常解决方案是保留一个"后台缓冲区",您可以在其中绘制到一些私有位图,然后在WM_PAINT
上从它复制到窗口。 - 你的线程循环没有意义,但即使你可以
while(WM_LBUTTONDOWN)
,那也是一个紧密的循环。如果您的鼠标保持静止,您的循环将继续以 100% CPU 一遍又一遍地调用同一位置的SetPixel
。 - 您的线程使用
static
局部变量。这意味着所有线程都将使用相同的变量。您在此处有几个同步问题。例如,如果iCount
在调用GetCursorPos
和ScreenToClient
之间发生变化。 - 你从不测试
iCount
是否越界。 - 如果用户在仍按下左按钮的同时关闭应用,该怎么办?您需要更多由父线程驱动的退出条件。