检查线程中的WM_LBUTTONDOWN

时间:2014-02-01 10:18:54

标签: c++ windows winapi

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

case WM_LBUTTONDOWN: {
      InvalidateRect(hwnd, NULL, TRUE);
      _beginthread(mouseMoveThread, 0, &params);
      return 0;
}

并且线程mouseMoveThread设置Pixel,在左键按下时:

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循环,左键是否按下???

1 个答案:

答案 0 :(得分:4)

您的GUI线程应将相应的消息转发给呈现线程。也许您的情况是WM_MOUSEMOVEWM_LBUTTONDOWNWM_LBUTTONUP。例如,您可以与Event个对象进行通信。

如果您的“渲染线程”有自己的消息循环,AttachThreadInput可能会引起您的兴趣。

但这似乎毫无意义。只需在主线程中执行;没有理由在这里创建一个单独的线程,无论如何最好在GUI线程中完成。您正在尝试处理WM_MOUSEMOVE事件以跟随鼠标光标。这只需要处理GUI线程中的事件。你这样做的方式,你会做同样的事情,除了从另一个线程。 你已经引入了大量的卷积,绝对没有收获

关于您的代码的其他一些评论:

  • 您正在调用InvalidateRect,这将导致WM_PAINTSetPixel是一个“流氓”电话 - 系统无法跟踪此情况,如果您在WM_PAINT中进行绘制,则您的SetPixel电话将始终被覆盖。因此,大多数应用WM_PAINT中进行绘画。
  • 如果您没有在WM_PAINT中绘画,如果您的窗口被隐藏并重新显示,您的SetPixel来电仍将被遗忘。所有这些绘画业务的正常解决方案是保留一个“后台缓冲区”,您可以在其中绘制一些私有位图,然后在WM_PAINT上,您只需将其复制到窗口。
  • 你的线程循环没有意义,但即使你可以while(WM_LBUTTONDOWN),它也会是一个紧凑的循环。如果您的鼠标保持静止,您的循环将继续在100%CPU上反复调用同一位置的SetPixel
  • 您的主题使用static个局部变量。这意味着所有线程都将使用相同的变量。这里有几个同步问题。例如,如果iCountGetCursorPos之间的ScreenToClient调用发生了变化。
  • 你永远不会测试iCount是否越界。
  • 如果用户在按下左键时关闭了应用,该怎么办?您需要更多退出条件,由父线程驱动。