Hi everyone!

I'm using WTL and have a class that wraps the window
that is taskbar's child (HHTaskbar).

As this window needs to be transparent I need to capture WM_REPAINT
messages of the taskbar, get the DC it has
repainted itself, and then repaint the background of the child window.
(or at least I think this is the right way to accomplish this ;-)

The problem is that you cannot pass class member function as the
new window procedure (NewWndProc) using SetWindowLong() as long as it is
not static.

Having a static NewWndProc is not possible, because I need to remember
the address of the OldWndProc on a place available only to the
NewWndProc so that I may pass the messages to the OldWndProc.

Having a global variable/class that will store the OldWndProc is not an
option, as I may have more windows that should be transparent and they
should make a WndProc chain, i.e.

Window 2->Window 1->Taskbar

The solution I'm thinking about is to create a single "monitor" child
window that will subclass the HHTaskbar() and then implement Observer
pattern to notify observers on HHTaskbar's repaint.

Huh, maybe I'm just missing something. Is there any way to make a hook
under win ce 4.*? Any other ideas?

Greetings,

---
Esad Hajdarevic
ESSE Software Engineering

Re: Ssubclassing using WTL by Michael

Michael
Fri Nov 18 07:35:14 CST 2005

You can use the ATL CWndProcThunk class. Put one of those in your class.
Initialize it with a static wndproc and a pointer to an instance of your
class (this pointer). I.e. m_WndProcThunk.Init(StaticWndProc, this).

Then call SetWindowLong as follows, and like magic, it'll work. Ok, it's
not really magic, but...

m_OriginalWndProc = (WNDPROC) SetWindowLong(m_SubclassedHWND, GWL_WNDPROC,
(LONG) m_WndProcThunk.thunk)

Uh, it may not work for windows owned by another process...

--
Michael Salamone [eMVP]
Entrek Software, Inc.
www.entrek.com


"Esad Hajdarevic" <esad-remove-this-@esse.at> wrote in message
news:437d0ebe$0$721$79720d31@newsreader.inode.at...
> Hi everyone!
>
> I'm using WTL and have a class that wraps the window
> that is taskbar's child (HHTaskbar).
>
> As this window needs to be transparent I need to capture WM_REPAINT
> messages of the taskbar, get the DC it has
> repainted itself, and then repaint the background of the child window.
> (or at least I think this is the right way to accomplish this ;-)
>
> The problem is that you cannot pass class member function as the
> new window procedure (NewWndProc) using SetWindowLong() as long as it is
> not static.
>
> Having a static NewWndProc is not possible, because I need to remember
> the address of the OldWndProc on a place available only to the NewWndProc
> so that I may pass the messages to the OldWndProc.
>
> Having a global variable/class that will store the OldWndProc is not an
> option, as I may have more windows that should be transparent and they
> should make a WndProc chain, i.e.
>
> Window 2->Window 1->Taskbar
>
> The solution I'm thinking about is to create a single "monitor" child
> window that will subclass the HHTaskbar() and then implement Observer
> pattern to notify observers on HHTaskbar's repaint.
>
> Huh, maybe I'm just missing something. Is there any way to make a hook
> under win ce 4.*? Any other ideas?
>
> Greetings,
>
> ---
> Esad Hajdarevic
> ESSE Software Engineering



Re: subclassing using WTL by Esad

Esad
Sat Nov 19 21:42:01 CST 2005

Hi! Thanks for your reply, but the one piece is still missing: how can I
access m_OriginalWndProc from the StaticWndProc as it is static?

I guess it replaces the hwnd argument of staticwndproc with this but
I cannot simply make this assumption :)

Greetings,

Esad

Michael J. Salamone wrote:

> You can use the ATL CWndProcThunk class. Put one of those in your class.
> Initialize it with a static wndproc and a pointer to an instance of your
> class (this pointer). I.e. m_WndProcThunk.Init(StaticWndProc, this).
>
> Then call SetWindowLong as follows, and like magic, it'll work. Ok, it's
> not really magic, but...
>
> m_OriginalWndProc = (WNDPROC) SetWindowLong(m_SubclassedHWND, GWL_WNDPROC,
> (LONG) m_WndProcThunk.thunk)
>
> Uh, it may not work for windows owned by another process...
>

Re: subclassing using WTL by Michael

Michael
Sat Nov 19 21:51:12 CST 2005

It's not an assumption. It's what the magic of the CWndProcThunk class
does.

Your StaticWndProc will be called with a this pointer instead of hWnd. Your
WndProc declaration would look like this:

static LRESULT StaticWndProc(MyClass *pClassInstance, UINT uMsg, WPARAM
wParam, LPARAM lParam);

The way I've personally done it is like this:

static LRESULT _WndProc(CMyClass *pMyClass, UINT uMsg, WPARAM wParam, LPARAM
lParam)

{

return pMyClass->WndProc(uMsg, wParam, lParam);

}

LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);

--
Michael Salamone [eMVP]
Entrek Software, Inc.
www.entrek.com


"Esad Hajdarevic" <esad-remove-this-@esse.at> wrote in message
news:437FF089.9080309@esse.at...
> Hi! Thanks for your reply, but the one piece is still missing: how can I
> access m_OriginalWndProc from the StaticWndProc as it is static?
>
> I guess it replaces the hwnd argument of staticwndproc with this but
> I cannot simply make this assumption :)
>
> Greetings,
>
> Esad
>
> Michael J. Salamone wrote:
>
>> You can use the ATL CWndProcThunk class. Put one of those in your class.
>> Initialize it with a static wndproc and a pointer to an instance of your
>> class (this pointer). I.e. m_WndProcThunk.Init(StaticWndProc, this).
>>
>> Then call SetWindowLong as follows, and like magic, it'll work. Ok, it's
>> not really magic, but...
>>
>> m_OriginalWndProc = (WNDPROC) SetWindowLong(m_SubclassedHWND,
>> GWL_WNDPROC, (LONG) m_WndProcThunk.thunk)
>>
>> Uh, it may not work for windows owned by another process...
>>



Re: subclassing using WTL by Esad

Esad
Sat Nov 19 23:04:13 CST 2005

Hello,

This works. However, replacing Taskbar's WndProc proved somewhat
dangerous because if the program doesn't terminate they way it should
(like killing the process from the control panel's memory applet) in
order to put the old wnd proc back, the newWndProc isn't available
anymore and the device freezes.

Any other way I could get notified on taskbar's repaint so that
I can repaint my background and achieve transparency?

Esad


Michael J. Salamone wrote:
> It's not an assumption. It's what the magic of the CWndProcThunk class
> does.
>
> Your StaticWndProc will be called with a this pointer instead of hWnd. Your
> WndProc declaration would look like this:
>
> static LRESULT StaticWndProc(MyClass *pClassInstance, UINT uMsg, WPARAM
> wParam, LPARAM lParam);
>
> The way I've personally done it is like this:
>
> static LRESULT _WndProc(CMyClass *pMyClass, UINT uMsg, WPARAM wParam, LPARAM
> lParam)
>
> {
>
> return pMyClass->WndProc(uMsg, wParam, lParam);
>
> }
>
> LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
>

Re: subclassing using WTL by Michael

Michael
Sun Nov 20 09:41:32 CST 2005

Yeah, it's definitely dangerous. You can protect yourself from closing from
the memory applet by handling WM_CLOSE in your application (put the old
wndproc back).

But, you still have to be worried about getting an unhandled exception in
your program and have it terminate unexpectedly. You also have to worry
about another process calling TerminateProcess on your own (though this is
not likely to happen).

There's no alternative that I know of for knowing when the taskbar will
repaint. You do have an alternative, however - change your app so that it
doesn't have a dependency on when the taskbar repaints. I reread your
original post - not sure what you are trying to accomplish, but there may be
another way to do the same thing. If not, change your UI.

--
Michael Salamone [eMVP]
Entrek Software, Inc.
www.entrek.com


"Esad Hajdarevic" <esad-remove-this-@esse.at> wrote in message
news:438003ca$0$702$79720d31@newsreader.inode.at...
> Hello,
>
> This works. However, replacing Taskbar's WndProc proved somewhat dangerous
> because if the program doesn't terminate they way it should (like killing
> the process from the control panel's memory applet) in
> order to put the old wnd proc back, the newWndProc isn't available anymore
> and the device freezes.
>
> Any other way I could get notified on taskbar's repaint so that
> I can repaint my background and achieve transparency?
>
> Esad
>
>
> Michael J. Salamone wrote:
>> It's not an assumption. It's what the magic of the CWndProcThunk class
>> does.
>>
>> Your StaticWndProc will be called with a this pointer instead of hWnd.
>> Your WndProc declaration would look like this:
>>
>> static LRESULT StaticWndProc(MyClass *pClassInstance, UINT uMsg, WPARAM
>> wParam, LPARAM lParam);
>>
>> The way I've personally done it is like this:
>>
>> static LRESULT _WndProc(CMyClass *pMyClass, UINT uMsg, WPARAM wParam,
>> LPARAM lParam)
>>
>> {
>>
>> return pMyClass->WndProc(uMsg, wParam, lParam);
>>
>> }
>>
>> LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
>>



Re: subclassing using WTL by Esad

Esad
Sun Nov 20 20:42:47 CST 2005

Hi!

Well, the task is to create a window that will sit in the taskbar.

I tried using notification API to place the icon there, but the problem
is that it gets overwritten as soon the next notification comes in (like
for example missed call on phone edition).

As the window is now sitting where the notification should appear, it
should be transparent, to make sure the user sees eventual notification ;-)

Maybe I could start separate minimalistic process whose only task is
to provide the new WndProc for the taskbar - the only that will relay
WM_PAINT to all Taskbar's children, in order to minize the risk of
terminating unexpectedly. It could even relay some user defined message
so that window can differ between own WM_PAINTs and the WM_PAINTs from
the underlying Taskbar.

Thanks for the replies,

Greetings,

Esad


Michael J. Salamone wrote:
> Yeah, it's definitely dangerous. You can protect yourself from closing from
> the memory applet by handling WM_CLOSE in your application (put the old
> wndproc back).
>
> But, you still have to be worried about getting an unhandled exception in
> your program and have it terminate unexpectedly. You also have to worry
> about another process calling TerminateProcess on your own (though this is
> not likely to happen).
>
> There's no alternative that I know of for knowing when the taskbar will
> repaint. You do have an alternative, however - change your app so that it
> doesn't have a dependency on when the taskbar repaints. I reread your
> original post - not sure what you are trying to accomplish, but there may be
> another way to do the same thing. If not, change your UI.
>