Problem with subclassing ListCtrl
I tried to subclass a ListCtrl (SysListView32-CommonCtrl) in a DialogBox by calling
OldListCtrlWndProc = ( WNDPROC )::SetWindowLong( m_hWndListCtrl, GWL_WNDPROC, ( DWORD )NewListCtrlWndProc );
in the WM_INITDIALOG-Handler, with
LRESULT ( CALLBACK* OldListCtrlWndProc )( HWND, UINT, WPARAM, LPARAM );
LRESULT CALLBACK NewListCtrlWndProc( HWND hWnd, WORD Message, WPARAM wParam, LPARAM lParam )
{
return CallWindowProc( OldListCtrlWndProc, hWnd, Message, wParam, lParam );
}
Whenever this code is in effect, the background and frame of my ListCtrl isn't painted anymore. The Items and subitems as well as the header-control are drawn correctly.
I abused the CANCEL-Button to toggle old and new ListCtrl-WndProc. With Spy++ I investigated the Messages, the control receives, either with the new and the old (original) WndProc but I couldn't make out any difference asides the fact, that in Spy++-properties-window the address of the windows-procedure changes. (When the new proc is active, it has a strange address of 0xffff****, followed by "(As subclass)", in contrast to 0x0******* (Unicode) with the original one.)
Any ideas? I browsed the web for this problem for serveral days, but nobody seems to have a problem like this one.
Thanks in advance
Re: Problem with subclassing ListCtrl
Code:
LRESULT ( CALLBACK* OldListCtrlWndProc )( HWND, UINT, WPARAM, LPARAM );
Although this may be correct, why don't you use WNDPROC as you did with SetWindowLong?
Code:
WNDPROC OldListCtrlWndProc = NULL
Re: Problem with subclassing ListCtrl
Quote:
Originally Posted by bobbyb
Code:
LRESULT CALLBACK NewListCtrlWndProc( HWND hWnd, WORD Message, WPARAM wParam, LPARAM lParam )
The signature of your NewListCtrlWndProc is incorrect. A WORD is an unsigned short, whereas the correct type for the message is a UINT which is an unsigned int. Try:
Code:
LRESULT CALLBACK NewListCtrlWndProc( HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam )
Mike
Re: Problem with subclassing ListCtrl
Hello kkez and MikeAThon,
thank you very much for your answers. Both of you were on the right track asking me to check the signature of my WindowProc. The code snippet, that i gave you in my question, wasn't the new WindowProc of the ListCtrl. It was the name-corrected WindowProc of an EditCtrl, asuming they were identic apart from their names, that i adjusted. The EditCtrl i had also subclassed and used without any problems. But the real WindowProc of my ListCtrl was.
LRESULT CALLBACK NewListCtrlWndProc( HWND hWnd, WORD Message, WORD wParam, LONG lParam )
{
return CallWindowProc( OldListCtrlWndProc, hWnd, Message, wParam, lParam );
}
As you can see, not only the 'Message'-Param, but also the 'wParam'-Param was of wrong type. And the wrong type of Param 'wParam' was the actual cause of my problem.
No idea what this corrupt signature came from. Even the compiler didn't complain but this probably is due to fact, that SetWindowLong only gets a cast of the WindowProc to LONG.
After correcting these issues, ListCtrl now works as expected.
Greetings of an embarrassed but happy
bobbyb