1

我创建了一个带有以下标志的窗口来覆盖 d3d 应用程序:WS_EX_TOPMOST | WS_EX_COMPOSITED | WS_EX_TRANSPARENT | WS_EX_LAYERED 我继续对窗口进行颜色键控以实现透明化,一切都运行良好。但是,一旦我开始使用 GDI 绘制它,就会出现一个无法预料的问题:

由于某种原因,当 WM_PAINT 正在进行时,鼠标事件(尤其是移动)没有正确地通过窗口,因此看起来鼠标和键盘似乎滞后了。FPS 很好,这是一些 API 问题,我怀疑由于某种原因,在 WM_PAINT 正在进行时键盘/鼠标消息没有按应有的方式处理,因为计时器设置得越慢,抽搐就越少。

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

 switch(msg)
 {
  case WM_DESTROY:
  {
          KillTimer(hwnd, ID_TIMER);
          PostQuitMessage(0);
          break;
         }
  case WM_CREATE:
  {
   SetTimer(hwnd, ID_TIMER, 10, NULL);
   break;
  }
  case WM_TIMER:
  {
   InvalidateRect(hwnd, 0, 1);
   break;
         }
  case WM_PAINT:
  {
   paint(hwnd);
   break;
  }
 }
 return DefWindowProc(hwnd, msg, wParam, lParam);
}

void paint (HWND hwnd)
{
 PAINTSTRUCT Ps;
 HDC hdc = BeginPaint(hwnd, &Ps);

 SetBkColor(hdc, RGB(0,0,0));
 SetBkMode(hdc, TRANSPARENT);



 LOGBRUSH log_brush;
 log_brush.lbStyle = BS_NULL;
 HBRUSH handle_brush = CreateBrushIndirect(&log_brush);
 SelectObject(hdc, handle_brush);


..........................................


 DeleteObject(font);
 DeleteObject(pen);
 DeleteObject(handle_brush);

 EndPaint(hwnd, &Ps);
}

感谢您提供的任何帮助。

4

2 回答 2

1

WM_PAINT 消息永远不会传递到您的窗口,除非有人打电话UpdateWindow或您的输入队列中没有键盘或鼠标消息。

一旦您开始处理 WM_PAINT,如果键盘或鼠标消息到达,它就会留在您的队列中,直到您处理完 WM_PAINT。所以你描述的是不可能的。

如果您的 WM_PAINT 代码需要很长时间才能执行,这可能会导致抖动,但您说这不是问题,所以也许是您对 WM_ERASEBKGND 的处理?我没有看到该代码,但我确实看到当您InvalidateRect将 TRUE 作为最后一个参数传递时,这意味着您希望删除背景。

如果您不处理 WM_ERASEBKGND,那么 DefWindowProc 将为您使用窗口类中的画笔擦除整个窗口。这可能会导致窗口认为窗口的任何部分都不是透明的。

如果您希望鼠标消息通过您的窗口,更可靠的方法是处理 WM_NCHITTEST 消息并在您希望鼠标通过的位置返回 HTTRANSPARENT。
这基本上就是 WS_EX_TRANSPARENT 样式的工作原理。像这样

case WM_NCHITTEST:
   {
   lRet = DefWindowProc(hwnd, uMsg, wParam, lParam);
   if (HTCLIENT == lRet)
      lRet = HTTRANSPARENT;
   }

如果您的窗口没有非客户区,那么您可以跳过对 DefWindowProc 的调用。

于 2010-02-20T05:21:54.430 回答
0

WndProc() 并不总是可重入的。我相信使用主消息泵,鼠标和键盘消息会排队等待您完成之前的 WM_PAINT 消息。相反,如果您要从 WndProc() 调用 SendMessage(),那么您正在查看重新进入。另一种情况是 PostMessage() ,它将消息添加到队列中。如果这是一个问题,也许可以考虑使用 DirectInput 进行鼠标和键盘输入。否则,请寻找加快绘图速度的方法。

于 2010-02-20T04:58:42.380 回答