Is it possible to intercept the WM_PAINT message passed to an external process' window(s)?? I can't seem to catch it - I can get most other messages (using a SetWindowsHookEx call) but the WM_PAINT message eludes me....??
Printable View
Is it possible to intercept the WM_PAINT message passed to an external process' window(s)?? I can't seem to catch it - I can get most other messages (using a SetWindowsHookEx call) but the WM_PAINT message eludes me....??
Have you looked at moeur's codebank entry - "Subclassing external program done for you", or such. It has a C++ dll that you can use to subclass an external program and catch the message you need.
Had a look, but couldn't see where this particular message was being called. Really need to do this myself rather than use another control (architecture/IP issues...)
But he does include the source code for the demo project and the C++ dll source code. I figured that the C++ code would be the most relevant part for you. ;)
http://www.vbforums.com/showthread.php?t=322261
Ta, browsing it now. :-p
Hmmm.... still can't work out why that particular message can't be captured. Nothing I can see in his code that is different from what I'm doing....
Perhaps you could show us what you are doing...
The problem I'm trying to solve is manipulating the display in another applications dialog boxes (for example). i.e; I want to draw directly to another window (and eventually, take over control of a particular control - a listview in a popup box). I can do this.
What I can't do is keep what I've drawn into that Window to stay there. I figure to capture WM_PAINT events, which will let me keep my own drawn UI in place. I haven't yet gone into maintaining control of that listview, but I imagine this will be OK (based on what I already understand). It's just the drawing I can't do.
I've written the following method into a C++ .dll;
This is part of a method called by a VB app to kick off the hooking. My CallWndProc implementation is as follows;Code:hHook = SetWindowsHookEx(
WH_CALLWNDPROC,
(HOOKPROC) CallWndProc,
NULL,
GetCurrentThreadId()));
Code:LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0) // do not process message
return CallNextHookEx(hHook, nCode, wParam, lParam);
// cast our message info for use in here
CWPSTRUCT* msgDetail = (CWPSTRUCT*) lParam;
if (msgDetail->message == WM_PAINT) {
TCHAR szBuf[80];
wsprintf(szBuf, "Got WM_PAINT from hWnd[%x]\n", msgDetail->hwnd);
OutputDebugString(szBuf);
}
TCHAR szBuf[80];
wsprintf(szBuf, "Comparing %x = %x\n", WM_PAINT, msgDetail->message);
OutputDebugString(szBuf);
wsprintf(szBuf, "CallWndProc called, checking hWnd...[%x==%x]\n", hWndDlg, msgDetail->hwnd);
OutputDebugString(szBuf);
// check the hWnd from the receiving window...
if (msgDetail->hwnd != hWndDlg) // do not process message
return CallNextHookEx(hHook, nCode, wParam, lParam);
wsprintf(szBuf, "CallWndProc called, checking message...\n", hWndDlg);
OutputDebugString(szBuf);
// check the message type now
if (msgDetail->message != WM_PAINT) // do not process message
return CallNextHookEx(hHook, nCode, wParam, lParam);
wsprintf(szBuf, "CallWndProc called, checking wParam...\n", hWndDlg);
OutputDebugString(szBuf);
// check that the window is being activated
if (msgDetail->wParam == TRUE) // do not process message
return CallNextHookEx(hHook, nCode, wParam, lParam);
wsprintf(szBuf, "CallWndProc called, running!\n", hWndDlg);
OutputDebugString(szBuf);
// All good
DrawMyWindow(hWndDlgFileView);
return 0; //CallNextHookEx(hHook, nCode, wParam, lParam);
}
Two problems I have; firstly, the hWnd of the app I actually want to look for never shows up, and secondly, WM_PAINT messages never show up. (Plenty of other messages do though...)
I'm a bit confused by your hook setting procedure.
If you call this from VB, then you are hooking your own thread and not an external process' thread.
What OS are you running on?
Ok, I'm probably a bit confused about it too then! :-D How do I hook messages (specifically WM_PAINT) in another process? (WinXP)
See the thread that RobDog pointed out to you. It has an in depth explanation as well as example code.
WM_PAINT is a somewhat unusual message (also WM_TIMER is but that is a story for another day) as it only gets posted to a window by the system when there are no other messages in the queue...this may cause problems later on.
Also the hook that you are setting is a local hook. To hook another application (process) you must pass its module handle in the hMod parameter (the third one).
Thanks for that, I got it to work now. I am now able to draw what I want into the ListView control on an Open dialog.
My next issue is that parts of the parent dialog (e.g; some of the buttons), and the application window are not refreshed until I move the dialog. So, switchin application context leaves small parts of the display un-drawn... any ideas?
why would it do that?
Care to post the code you are using?