如何在另一个应用程序之上绘制图形/文本

s58*_*804 7 c# windows graphics winapi

我想增强一个应用程序,但没有3:e party API可用.所以基本上这个想法是在应用程序窗口之上绘制图形/文本.

z order,clip和将鼠标点击指向我的应用程序或其他应用程序时出现问题.

这样做的优雅方式是什么?

这里的示例图像.这是一个交易应用程序,我的应用程序想要在交易应用程序的窗口中添加额外的信息.[URL = http://img104.imageshack.us/my.php?image=windowontop.png] [/ URL ]

Kev*_*ose 7

没有很好的方法可以做到这一点,但是一种可能对您有用的方法是使用SetWindowsHookEx(...)挂钩相关应用程序以添加GetMsgProc,它会根据WM_PAINT消息绘制叠加层.基本思想是在应用程序完成自己的绘图后立即绘制图形.

在您的主应用程序中:

....
HMODULE hDllInstance = LoadLibrary("myFavoriteDll");
HOOKPROC pOverlayHook = (HOOKPROC)GetProcAddress(hDllInstance, "OverlayHook");
SetWindowsHookEx(WH_GETMESSAGE, pOverlayHook, hDllInstance, threadId);
Run Code Online (Sandbox Code Playgroud)

关闭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;
}
Run Code Online (Sandbox Code Playgroud)

这都是win32所以你的C#代码将会调用很多并且相应地非常难看.你的DLL也必须是不受管理的(如果你打算注入你自己以外的进程),这使得这个解决方案更加糟糕.

这将解决您的z-order和裁剪问题,因为您正在渲染到窗口本身.但是,如果您要定位的应用程序在响应WM_PAINT的WinProc之外进行任何绘制,则事情就会崩溃; 这并非完全不常见.