Как нарисовать графику / текст поверх другого приложения - PullRequest
7 голосов
/ 03 мая 2009

Я хочу улучшить приложение, но нет 3-стороннего API. Таким образом, в основном идея состоит в том, чтобы рисовать графику / текст поверх окон приложений.

Есть проблемы с z-порядком, отсечкой и перетаскиванием щелчков мыши либо в мое приложение, либо в другое приложение.

Какой элегантный способ сделать это?

Пример изображения здесь. Это торговое приложение, в котором мое приложение хочет добавить дополнительную информацию в окна торгового приложения. [URL = http://img104.imageshack.us/my.php?image=windowontop.png][/URL]

Ответы [ 3 ]

7 голосов
/ 04 мая 2009

Нет хороших способов сделать это, но один из подходов, который может сработать для вас, - это подключить рассматриваемое приложение, используя SetWindowsHookEx (...), чтобы добавить GetMsgProc, который рисует ваше наложение в ответ на сообщения WM_PAINT. Основная идея заключается в том, что вы рисуете СВОЮ графику сразу после того, как приложение заканчивает свой собственный рисунок.

В вашем основном приложении:

....
HMODULE hDllInstance = LoadLibrary("myFavoriteDll");
HOOKPROC pOverlayHook = (HOOKPROC)GetProcAddress(hDllInstance, "OverlayHook");
SetWindowsHookEx(WH_GETMESSAGE, pOverlayHook, hDllInstance, threadId);

Выключен в DLL где-то:

LRESULT CALLBACK OverlayHook(int code, WPARAM wParam, LPARAM lParam)
{
  //Try and be the LAST responder to WM_PAINT messages;
  //Of course, if some other application tries this all bets are off
  LRESULT retCode = CallNextHookEx(NULL, code, wParam, lParam);

  //Per GetMsgProc documentation, don't do anything fancy
  if(code < 0) return retCode;

  //Assumes that target application only draws when WM_PAINT message is
  //removed from input queue.
  if(wParam == PM_NOREMOVE) return retCode;

  MSG* message = (MSG*)lParam;

  //Ignore everything that isn't a paint request
  if(message->message != WM_PAINT) return retCode;

  PAINTSTRUCT psPaint;    

  BeginPaint(message->hwnd, &psPaint);
  //Draw your overlay here
  ...
  EndPaint(message->hwnd, &psPaint);

  return retCode;
}

Это все win32, поэтому ваш код на C # будет p / invoke тяжелым и, соответственно, довольно уродливым. Ваша DLL также должна быть неуправляемой (если вы собираетесь внедрить ее в процесс, отличный от вашего), что делает это решение еще более неприятным.

Это решит вашу проблему с проблемами z-порядка и отсечения, когда вы будете рендерить в само окно. Однако, если приложение, на которое вы нацеливаетесь, делает любой рисунок вне WinProc, отвечающий на WM_PAINT, вещи распадаются; это не совсем редкий случай.

1 голос
/ 20 августа 2013

Возможно, вы захотите нарисовать его поверх DirectX для игр

http://spazzarama.com/2011/03/14/c-screen-capture-and-overlays-for-direct3d-9-10-and-11-using-api-hooks/

0 голосов
/ 30 ноября 2010

Есть проблемы с z-порядком, отсечение и направление щелчков мыши или к моей заявке или другой применение.

Это все задачи, для решения которых был разработан оконный менеджер. Вы должны создать многоуровневое окно поверх окон приложений.

См. Также: Запретить перерисовку окна в C ++

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...