Capturing WM_PAINT messages

Started by
12 comments, last by Sp00n00n 15 years, 2 months ago
My application is required to draw onto another processes Windows. I am doing this by creating a hook with SetWindowsHookEx(). I can see the thread processing WM_PAINT messages with WH_CALLWNDPROC and WH_GETMESSAGE style hooks, but not WH_CALLWNDPROCRET. I require a WH_CALLWNDPROCRET style hook because I need to draw after the recipient Window has done its drawing, so I can draw on top of it. The reason I think that I can not see WM_PAINT messages, is that WH_CALLWNDPROCRET only receives messages sent by SendMessage() and WM_PAINT is not sent in this way. If anyone has any other solutions of drawing on another Processes/Threads Windows avoiding constant flickering, or how I can modify my current solution to solve the problem, let me know, because I am stumped! [Edited by - Sp00n00n on January 20, 2009 12:03:23 PM]
Advertisement
I am going to try to draw a transparent child Window over the client area of the Window I want to draw over, and draw on top of that. I'll let you know how it goes!
You could subclass the target window, then install your own window proc (traping the WM_PAINT messages, and forwarding the other messages to the original window proc).
As far as I can find out, Window subclassing intercepts messages before they reach the wndproc. I need to capture WM_PAINT messages after they have been processed by the message handler. I can't think of a way to intercept messages before they reach the message handler and then wait until after they have been processed to begin drawing, but am I missing something?
If you subclass the window you replace the old window proc with your one.
Then your window proc is called in place of the original one to process messages.
Couldn't you call the original window proc and make your stuff after the call when you receive the WM_PAINT message ?
I mean, when the call to the original window proc ends the message processing has been done, then you can execute your own code after the original handler no ?
Quote:Original post by Sp00n00n
As far as I can find out, Window subclassing intercepts messages before they reach the wndproc. I need to capture WM_PAINT messages after they have been processed by the message handler. I can't think of a way to intercept messages before they reach the message handler and then wait until after they have been processed to begin drawing, but am I missing something?
Subclassing a window is a way of replacing the windows WndProc with your own function, so your replacement can call the original WndProc, and if the message is WM_PAINT, then you do your drawing - which is after the original WndProc has been called.

However, I'm not sure if you can subclass a window in another process, so you may have to inject code into the target process.
Thanks I'm working on a solution now using subclassing. I am already injecting dll's into the processes, so that won't be a problem Evil Steve! Thanks for help, will let you know if I run into troubles.
From MSDN: "Subclassing is allowed only within a process. An application cannot subclass a window or class that belongs to another process."

oh dear! I will try my method of creating a blanket child window over the client area.
Of course, you can't subclass a window from another process, because the window proc adress must be in the target process adress space.
As you are injecting a dll in the target process, you can subclass the window easily, just do it in DllMain ().
Hi Dear members,

I'm facing the same problem: I set a hook on a window in a third party application and catch the WM_PAINT message without problem. My trouble is that my added drawing is not on that window.

Here is my hook setting:
DWORD dwThreadID = GetWindowThreadProcessId(mpParent->m_hWnd, NULL);
mhHook = SetWindowsHookEx(WH_CALLWNDPROCRET ,CallWndRetProc,NULL,dwThreadID);

And Here is my drawing inside the catched WM_PAINT event in CallWndRetProc:

HWND hwnd = mpParent->GetSafeHwnd();
HDC hDC = GetDC(hwnd);
RECT lRect;
mpParent->GetClientRect(&lRect);
int mapmode = GetMapMode(hDC);
CDC* pDC = CDC::FromHandle(hDC);
pDC->SelectStockObject(WHITE_BRUSH);
pDC->Rectangle(&lRect);
mpParent->InvalidateRect(&lRect, true);
ReleaseDC(hwnd ,hDC);

It should a white rectangle in that window but it change nothing.

Please help me or tell me how to fix the problem.

Great thanks!

This topic is closed to new replies.

Advertisement