Board index » cppbuilder » Listview Column header resizing related events in a component

Listview Column header resizing related events in a component


2008-01-09 07:10:16 AM
cppbuilder24
Hi,
I'm building a component that contains a listview and I'd like to get
notification of listview's columns resize within my component.
The folowing codes works fine for a custom_list_view derived from TListView.
class TSMyCustomListView
: public TListView
{
...
MESSAGE void __fastcall WMNotify(TMessage& Msg)
{
NMHDR *pnmh = (NMHDR*) Msg.LParam;
switch( pnmh->code )
{
case HDN_BEGINTRACKA:
case HDN_BEGINTRACKW:
// do something
break;
case HDN_TRACKA:
case HDN_TRACKW:
// do something
break;
case HDN_ENDTRACKA:
case HDN_ENDTRACKW:
// do something
break;
default:
TListView::Dispatch(&Msg); // Default processing
break;
}
}
But I want to use a TListView (not TSMyCustomListView) and I need to put
this code in a component which declaration looks like
class PACKAGE TMYComponent
: public TScrollBox
{
TListView * list;
...
I have tried several way found in the NG (but it was for a list view
being in a form) but none worked. I'm a little bit confused with the
WMNOTIFY, CNNOTIFY, ... and so on.
Could you give me some hints to get it to work ?
thank you
 
 

Re:Listview Column header resizing related events in a component

Hi E B
This might help You:
HEADERWNDPROC OldHeaderWndProc;
void __fastcall TYourComponent::HeaderWndProc(TMessage &Message )
{
}
hHeader = ListView_GetHeader( ListView->Handle );
if( hHeader )
OldHeaderWndProc = reinterpret_cast<HEADERWNDPROC>(
::SetWindowLong(hHeader, GWL_WNDPROC, HeaderWndProcPtr) );
Kind regards
Asger
 

Re:Listview Column header resizing related events in a component

Thank you, I'll try this right now, I have 2 additional questions:
1. do I have to set back header's wndproc to the old value when the
component is destroyed ?
2. do I have to call OldHeaderWndProc within TYourComponent::HeaderWndProc ?
Asger Joergensen a écrit :
Quote
Hi E B

This might help You:

HEADERWNDPROC OldHeaderWndProc;

void __fastcall TYourComponent::HeaderWndProc(TMessage &Message )
{

}

hHeader = ListView_GetHeader( ListView->Handle );
if( hHeader )
OldHeaderWndProc = reinterpret_cast<HEADERWNDPROC>(
::SetWindowLong(hHeader, GWL_WNDPROC, HeaderWndProcPtr) );

Kind regards
Asger
 

{smallsort}

Re:Listview Column header resizing related events in a component

"E B" < XXXX@XXXXX.COM >wrote in message
Quote
I want to use a TListView (not TSMyCustomListView)
You need to subclass the ListView's WindowProc property in order to
intercept its messages from an external handler, ie:
class PACKAGE TMyComponent : public TScrollBox
{
private:
TListView * list;
TWndMethod DefListViewWndProc;
void __fastcall MyListViewWndProc(TMessage &Message);
...
};
__fastcall TMyComponent::TMyComponent(TComponent *Owner)
: TScrollBox(Owner)
{
list = new TListView;
list->Parent = this;
DefListViewWndProc = list->WindowProc;
list->WindowProc = MyListViewWndProc;
...
}
void __fastcall TMyComponent::MyListViewWndProc(TMessage &Message)
{
if( Message.Msg == CN_NOTIFY )
{
NMHDR *pnmh = (NMHDR*) Message.LParam;
switch( pnmh->code )
{
case HDN_BEGINTRACKA:
case HDN_BEGINTRACKW:
// do something
break;
case HDN_TRACKA:
case HDN_TRACKW:
// do something
break;
case HDN_ENDTRACKA:
case HDN_ENDTRACKW:
// do something
break;
}
}
DefListViewWndProc(Message); // Default processing
}
Quote
I'm a little bit confused with the WMNOTIFY, CNNOTIFY, ...
WM_NOTIFY is the original notification message that Windows sends to a
control's parent window. CN_NOTIFY is a custom message that a VCL windowed
control will forward the WM_NOTIFY message as to the intended child control
(the ListView in this case) so it can handle its own notifications directly.
The same applies for the WM_COMMAND/CN_COMMAND pair as well.
Gambit
 

Re:Listview Column header resizing related events in a component

"Asger Joergensen" < XXXX@XXXXX.COM >wrote in message
Quote
This might help You:
You do not need to subclass the ListView's header directly. In fact,t hat
won't work anyway since the notifications are sent to the header's parent
window, which is the ListView itself. So you have to subclass the ListView
itself instead of its header.
Gambit
 

Re:Listview Column header resizing related events in a component

Hi E B
E B says:
Quote
Thank you, I'll try this right now, I have 2 additional questions:

1. do I have to set back header's wndproc to the old value when the
component is destroyed ?
I would do that, but since the listview is destroid with Your
component I don't know how important it is.
Quote

2. do I have to call OldHeaderWndProc within TYourComponent::HeaderWndProc ?
Yes defenetly.
Kind regards
Asger
 

Re:Listview Column header resizing related events in a component

Hi Remy
Thanks for the correction.
Kind regards
Asger
 

Re:Listview Column header resizing related events in a component

thank you, I dit it as you shown and it works (the new wndproc is
actually called).
nevertheless, it seems that HDN_ENDTRACKA and HDN_ENDTRACKW are never
notified. I got several notifications that are not HDN_ENDTRACK? but no
HDN_ENDTRACKW?.
Could this be due to the fact that my list view is virtual (ownerdata =
true) ?
if yes, how could I get HDN_ENDTRACK? notification for virutal list view ?
 

Re:Listview Column header resizing related events in a component

Are column event notified when the listview is virtual (ownerdata=true)?
I tend to think that they are not notified, as I do not get them in any way.
Asger Joergensen a écrit :
Quote
Hi E B

E B says:
>Thank you, I'll try this right now, I have 2 additional questions:
>
>1. do I have to set back header's wndproc to the old value when the
>component is destroyed ?

I would do that, but since the listview is destroid with Your
component I don't know how important it is.

>2. do I have to call OldHeaderWndProc within TYourComponent::HeaderWndProc ?

Yes defenetly.

Kind regards
Asger
 

Re:Listview Column header resizing related events in a component

"E B" < XXXX@XXXXX.COM >wrote in message
Quote
Are column event notified when the listview is virtual (ownerdata=true)?
Yes. The virtual setting only applies to how the item data is managed, not
how it is displayed.
Quote
I tend to think that they are not notified
Works fine for me when I just tried it.
Quote
as I do not get them in any way.
Then you are not catching them correctly.
Gambit
 

Re:Listview Column header resizing related events in a component

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
if( Message.Msg == CN_NOTIFY )
Small correction. You have to look for WM_NOTIFY instead, as the header is
sending that directly to the ListView, so there is no VCL forwarding
involved.
Gambit
 

Re:Listview Column header resizing related events in a component

"E B" < XXXX@XXXXX.COM >wrote in message
Quote
nevertheless, it seems that HDN_ENDTRACKA and HDN_ENDTRACKW
are never notified.
Yes, they are. See my other reply.
Gambit
 

Re:Listview Column header resizing related events in a component

Asger Joergensen < XXXX@XXXXX.COM >wrote:
Quote

HEADERWNDPROC OldHeaderWndProc;

void __fastcall TYourComponent::HeaderWndProc(TMessage &Message )
{
}

hHeader = ListView_GetHeader( ListView->Handle );
if( hHeader )
OldHeaderWndProc = reinterpret_cast<HEADERWNDPROC>(
::SetWindowLong(hHeader, GWL_WNDPROC, HeaderWndProcPtr) );
Please re-examine the sample that you were working from. You
missed the #define's completely and subsequently so does your
sample.
~ JD
 

Re:Listview Column header resizing related events in a component

here is my code for the new wnd proc
void __fastcall TMyComponent::ListViewWndProc(TMessage &Message )
{
if( Message.Msg == CN_NOTIFY )
{
NMHDR *pnmh = (NMHDR*) Message.LParam; // if I put a breakpoint
here it stops several time =>so I assume the wndproc is actually used
if ( (pnmh->code == HDN_ENDTRACKA)
|| (pnmh->code == HDN_ENDTRACKW)
)
{
OnColumnHeaderResized(this); // but never reach this line !!!
}
}
DefListViewWndProc(Message); // Default processing
}
in the constructor I have
lvList = new TListView (this) ;
lvList->Parent = this;
DefListViewWndProc = lvList->WindowProc;
lvList->WindowProc = ListViewWndProc;
I must have done something wrong but don't see what !!
Remy Lebeau (TeamB) a crit :
Quote
"E B" < XXXX@XXXXX.COM >wrote in message
news:4784155f$ XXXX@XXXXX.COM ...

>Are column event notified when the listview is virtual (ownerdata=true)?

Yes. The virtual setting only applies to how the item data is managed, not
how it is displayed.

>I tend to think that they are not notified

Works fine for me when I just tried it.

>as I do not get them in any way.

Then you are not catching them correctly.


Gambit


 

Re:Listview Column header resizing related events in a component

That was the problem the following works fine
void __fastcall TMyComponent::ListViewWndProc(TMessage &Message )
{
if( Message.Msg == WM_NOTIFY )
{
NMHDR *pnmh = (NMHDR*) Message.LParam; // if I put a breakpoint
here it stops several time =>so I assume the wndproc is actually used
if ( (pnmh->code == HDN_ENDTRACKA)
|| (pnmh->code == HDN_ENDTRACKW)
)
{
OnColumnHeaderResized(this); // but never reach this line !!!
}
}
DefListViewWndProc(Message); // Default processing
}
thank you for your help