Author: Jonas Bilinkevicius
How to subclass your header-control (using a TListView), to receive a
OnColumnDblClick- equivalent notification?
Answer:
This requires a bit of work. MS did not see fit to send a notification to the
TListView when the user double-clicks on the header. But the header control class
does have the CS_DBLCLKS style, so it does get WM_LBUTTONDBLCLK messages, it just
does not do anything with them.
To get at these messages requires API-style subclassing of the header control. How?
See below.
1 uses..., Commctrl;
2 ...
3 const
4 UM_LISTVIEW_COLUMN_DBLCLICK = WM_USER + 1982;
5 ....
6 { the HeaderProc function should look something like this: }
7
8 function
9 HeaderProc(wnd: HWND; msg: Cardinal; wparam: WPARAM; lparam: LPARAM): Longint;
10 stdcall;
11 var
12 hti: THDHitTestInfo;
13 begin
14 Result := CallWindowProc(Pointer(GetWindowLong(wnd, GWL_USERDATA)),
15 wnd, msg, wparam, lparam);
16 if msg = WM_LBUTTONDBLCLK then
17 begin
18 FillChar(hti, sizeof(hti), 0);
19 hti.Point := SmallPointToPoint(TSmallPoint(lparam));
20 if SendMessage(wnd, HDM_HITTEST, 0, Longint(@hti)) >= 0 then
21 if hti.Flags = HHT_ONHEADER then
22 PostMessage(MainForm.Handle, UM_LISTVIEW_COLUMN_DBLCLICK, hti.Item, 0);
23 { Change MainForm to whatever you need }
24 end;
25 end;
26
27 procedure TMainForm.FormCreate(Sender: TObject);
28 var
29 wnd: HWND;
30 oldProc: Integer;
31 begin
32 {beginning of workaround for missing TListView.OnColumnDblClick}
33 wnd := GetWindow(aListView.handle, GW_CHILD); { <-- your TListView's name here }
34 if wnd <> 0 then
35 begin
36 if (GetClassLong(wnd, GCL_STYLE) and CS_DBLCLKS) <> 0 then
37 begin
38 oldproc := GetWIndowLong(wnd, GWL_WNDPROC);
39 if GetWindowLong(wnd, GWL_USERDATA) <> 0 then
40 raise
41 Exception.Create('Cannot sublcass ListView header, USERDATA already in
42 use'
43 SetWIndowLong(wnd, GWL_USERDATA, oldproc);
44 SetWindowLong(wnd, GWL_WNDPROC, integer(@HeaderProc));
45 end;
46 end
47 else
48 ShowMessage('ListView component in vsReport state is missing !!!');
49 {...}
50 {Do some more wonderful things}
51 end;
and then don't forget to declare a custom message handler for UM_LISTVIEW_COLUMN_DBLCLICK (this will be your OnColumnDblClick equivalent).
|