我想增强一个应用程序,但是没有3:e派对API可用。 所以基本上这个想法是在应用程序窗口上绘制graphics/文本。
z顺序,裁剪和将鼠标点击指向我的应用程序或其他应用程序都有问题。
什么是这样做的一个优雅的方式?
示例图像在这里。 这是一个交易应用程序,我的应用程序想要在交易应用程序的窗口中添加额外的信息。 [URL = http://img.zgserver.com/c%23/2wwindowontopp] [/ URL ]
没有很好的方法可以做到这一点,但是一种可能适用于你的方法是使用SetWindowsHookEx(…)来挂钩应用程序来添加一个GetMsgProc,该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做出响应,事情就会崩溃; 这不是一个非常罕见的事件。
您可能需要在directX上绘制游戏
z顺序,裁剪和将鼠标点击指向我的应用程序或其他应用程序都有问题。
这些都是窗口管理器设计要处理的所有任务。 您应该在应用程序的窗口上创建一个分层窗口。
另请参阅: 防止在C ++中重新绘制窗口