Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WH_CALLWNDPROC or WH_CALLWNDPROCRET to get WM_PAINT

659 views
Skip to first unread message

Kirsten

unread,
May 30, 2004, 8:08:57 AM5/30/04
to
Hi @all,

Currently I'm developing fully transparent windows controls. And what
should I say, I really did it (some people said that it isn't
possible?!?).

I only have got a *last* little problem:
For example I use my own (transparent) component and a windows
standard component. Now I need to know when the windows standard
component (a button for example) receives a WM_PAINT message. Because
I want to redraw my transparent window after the button was repainted.

I thought that this is no problem. I already have some SetWindowHookEx
experiences, so I thought capturing the WM_PAINT message should do it.
But WH_CALLWNDPROC *NEVER* gets the WM_PAINT message on my system!
WH_CALLWNDPROCRET does not, too!

Upfmh?? I read in the newsgroups that it is possible to receive
WM_PAINT with hooks? But how?

------------------
My code:


function PaintHookPreProc(nCode: Integer; wParam: WPARAM; lParam:
LPARAM): LRESULT; stdcall;
var
CWP: PCWPSTRUCT;
begin
Result := CallNextHookEx(GPaintHookPre, nCode, wParam, lParam);
if (nCode = HC_ACTION) then
begin
CWP := PCWPSTRUCT(lParam);
if (CWP.message = WM_PAINT) then
begin
// Debugger never gets in
end;
if (CWP.message = WM_NCPAINT) then
begin
// Debugger gets in
end;
end;
end;

[...]

GPaintHookPre := SetWindowsHookEx(WH_CALLWNDPROC, @PaintHookPreProc,
hInstance, GetCurrentThreadId);

----------

BTW: I'm using WinXP and Delphi!

Thanks,
Kirsten

John Carson

unread,
May 30, 2004, 8:51:41 AM5/30/04
to
"Kirsten" <tthu...@gmx.de> wrote in message
news:911abfed.04053...@posting.google.com
> Hi @all,
>
> Currently I'm developing fully transparent windows controls. And what
> should I say, I really did it (some people said that it isn't
> possible?!?).
>
> I only have got a *last* little problem:
> For example I use my own (transparent) component and a windows
> standard component. Now I need to know when the windows standard
> component (a button for example) receives a WM_PAINT message. Because
> I want to redraw my transparent window after the button was repainted.
>
> I thought that this is no problem. I already have some SetWindowHookEx
> experiences, so I thought capturing the WM_PAINT message should do it.
> But WH_CALLWNDPROC *NEVER* gets the WM_PAINT message on my system!
> WH_CALLWNDPROCRET does not, too!
>
> Upfmh?? I read in the newsgroups that it is possible to receive
> WM_PAINT with hooks? But how?


WM_PAINT is retrieved with a WH_GETMESSAGE hook.


--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)


Kirsten

unread,
May 30, 2004, 4:36:09 PM5/30/04
to

"John Carson" <donald...@datafast.net.au> schrieb im Newsbeitrag news:40b9d8dd$1...@usenet.per.paradox.net.au...

>
>
> WM_PAINT is retrieved with a WH_GETMESSAGE hook.
>
>
> --
> John Carson
> 1. To reply to email address, remove donald
> 2. Don't reply to email address (post here instead)
>
>

Well, this helps finding a solution. The only thing is:

The GetMsgProc hook procedure:

---------------------------------

"Before passing the retrieved message to the destination window procedure, the system passes the message to the hook procedure"

Unfortunatelly I need to do something after WM_PAINT! Suggestions?

John Carson

unread,
May 30, 2004, 10:16:03 PM5/30/04
to
"Kirsten" <stefan...@gmx.de> wrote in message
news:c9dgjv$mvv$06$1...@news.t-online.com

>
> Well, this helps finding a solution. The only thing is:
>
> The GetMsgProc hook procedure:
>
> ---------------------------------
>
> "Before passing the retrieved message to the destination window
> procedure, the system passes the message to the hook procedure"
>
> Unfortunatelly I need to do something after WM_PAINT! Suggestions?


One technique would be to subclass any window procedure that gets a WM_PAINT
message. Less intrusive (but possibly less effective, depending on what you
are doing), would be to register a user defined message with the system
(using RegisterWindowMessage) and then have your hook procedure post it to
the relevant window whenever the hook intercepts a WM_PAINT message. The
posted message will be retrieved by the window after it has processed
WM_PAINT. When this happens, the message will be passed to your hook and you
can take this as the cue to do your own painting.

Kirsten

unread,
Jun 1, 2004, 10:09:40 AM6/1/04
to

"John Carson" <donald...@datafast.net.au> schrieb im Newsbeitrag news:40ba9592$1...@usenet.per.paradox.net.au...

>
> One technique would be to subclass any window procedure that gets a WM_PAINT
> message. Less intrusive (but possibly less effective, depending on what you
> are doing), would be to register a user defined message with the system
> (using RegisterWindowMessage) and then have your hook procedure post it to
> the relevant window whenever the hook intercepts a WM_PAINT message. The
> posted message will be retrieved by the window after it has processed
> WM_PAINT. When this happens, the message will be passed to your hook and you
> can take this as the cue to do your own painting.
>
> --
> John Carson
> 1. To reply to email address, remove donald
> 2. Don't reply to email address (post here instead)
>

Subclassing? You mean that I override the WndProc? Well, I tried it the following way:

Create a CBT hook to intercept window creation...

Then I used SetWindowLong and GetWindowLong to override the WndProc...

In my new WndProc I asked if message is WM_PAINT...

But what should I say, nobody would believe me! I haven't got any WM_PAINT message in my overriden WndProc!

I know it is absurd, because I use this technique to override the WM_PAINT of a normal top level window, for example?!?

BTW: In "my" WndProc I get everything: WM_ERASEBACKGROUND, WM_NCPAINT,... but NO WM_PAINT. I have no answer to this!

John Carson

unread,
Jun 1, 2004, 1:00:27 PM6/1/04
to
"Kirsten" <stefan...@gmx.de> wrote in message
news:c9i2nj$arc$01$1...@news.t-online.com

> "John Carson" <donald...@datafast.net.au> schrieb im Newsbeitrag
> news:40ba9592$1...@usenet.per.paradox.net.au...
>>
>> One technique would be to subclass any window procedure that gets a
>> WM_PAINT message. Less intrusive (but possibly less effective,
>> depending on what you are doing), would be to register a user
>> defined message with the system (using RegisterWindowMessage) and
>> then have your hook procedure post it to the relevant window
>> whenever the hook intercepts a WM_PAINT message. The posted message
>> will be retrieved by the window after it has processed WM_PAINT.
>> When this happens, the message will be passed to your hook and you
>> can take this as the cue to do your own painting.
>>
>
> Subclassing? You mean that I override the WndProc?

Yes, substitute your own window procedure (which will call the default
window procedure for most if not all messages). Personally, I would have
first tried the other approach I suggested.

> Well, I tried it
> the following way:
>
> Create a CBT hook to intercept window creation...
>
> Then I used SetWindowLong and GetWindowLong to override the WndProc...

I presume that you are using GetWindowLong to retrieve the default window
procedure (I always get it from the return value of SetWindowLong).

> In my new WndProc I asked if message is WM_PAINT...
>
> But what should I say, nobody would believe me! I haven't got any
> WM_PAINT message in my overriden WndProc!
>
> I know it is absurd, because I use this technique to override the
> WM_PAINT of a normal top level window, for example?!?
>
> BTW: In "my" WndProc I get everything: WM_ERASEBACKGROUND,
> WM_NCPAINT,... but NO WM_PAINT. I have no answer to this!


I guess there are two possibilities:

1. This is a strange window that doesn't receive WM_PAINT messages (such
windows are possible).
2. You are doing something wrong.

As for 1., VC++ comes with a program call Spy++ which enables you to monitor
messages for a window. I don't know if your Delphi setup has anything
similar. If not, you can download this program for free:

http://www.windows-spy.com/

(I suggest you test the window WITHOUT your subclassing window procedure.)

As for 2., I couldn't comment without seeing your code.

John Carson

unread,
Jun 1, 2004, 1:03:32 PM6/1/04
to
"John Carson" <donald...@datafast.net.au> wrote in message
news:40bc...@usenet.per.paradox.net.au

>
> As for 2., I couldn't comment without seeing your code.


Since it is Delphi, I still might not have anything useful to say but, if
not, someone else may.

Kirsten

unread,
Jun 2, 2004, 4:47:40 PM6/2/04
to
"John Carson" <donald...@datafast.net.au> wrote in message news:<40bc...@usenet.per.paradox.net.au>...

>
> Since it is Delphi, I still might not have anything useful to say but, if
> not, someone else may.

The code hasn't existed more than 10 hours, so I cannot post it. Of
course an error could be in there, but I have seen over it about 20
times and I'm really used to subclassing. (Yes, I use it the way you
described).

BTW, I'm using Winspector Spy, and my window gets WM_PAINT normally.
When I override it in Delphi the normal way, it works, too! Well, as I
said, very strange. But I have a similar problem with a WM_COMMAND in
Delphi, which isn't sent in design time but in runtime. Perhaps Delphi
really mixes something up.

If anyone has suggestions or answers, please posts!

Thanks,
Kirsten

0 new messages