检查线程中的WM_LBUTTONDOWN

Check WM_LBUTTONDOWN in a Thread

本文关键字:LBUTTONDOWN WM 线程 检查      更新时间:2023-10-16

我有一个WindowProcess,当鼠标左键按下时,它会创建一个线程:

case WM_LBUTTONDOWN: {
InvalidateRect(hwnd, NULL, TRUE);
_beginthread(mouseMoveThread, 0, &params);
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_MOUSEMOVEWM_LBUTTONDOWNWM_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在调用GetCursorPosScreenToClient之间发生变化。
  • 你从不测试iCount是否越界。
  • 如果用户在仍按下左按钮的同时关闭应用,该怎么办?您需要更多由父线程驱动的退出条件。