(Windows API) WM_PAINT Проблемы с мышью - PullRequest
1 голос
/ 20 февраля 2010

Я создал окно со следующими флагами для наложения приложения 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);
}

Спасибо за любую помощь, которую вы можете оказать.

Ответы [ 2 ]

1 голос
/ 20 февраля 2010

Сообщения 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.

0 голосов
/ 20 февраля 2010

WndProc () не всегда повторный. Я полагаю, что с основным насосом сообщений сообщения мыши и клавиатуры ставятся в очередь и ждут, пока вы закончите предыдущее сообщение WM_PAINT. И наоборот, если вы вызываете SendMessage () из WndProc (), то вы смотрите на повторный захват. Другой случай - PostMessage (), который добавил бы сообщение в очередь. Может быть, посмотрите на использование DirectInput для ввода с клавиатуры и мыши, если это проблема. В противном случае ищите способы ускорить ваш рисунок.

...