Author: Tomas Rutkauskas
I have a TListView which contains sequential items which may be grouped together.
Users can create a group by left-clicking and dragging the mouse over a series of
items. These items are regular, multiselected, highlighted (default) blue items.
The user can then right-click to bring up a menu, and select Create Group. Grouped
items show up in various colors, and the Data portion of the Item describes the
group. I would like users to be able to edit the properties of a group by
right-clicking on an item within the group to bring up a menu, then selecting Edit
Group. However, whenever I right-click the listview, it highlights the item
underneath the cursor, and the Create Group menu selections are enabled. Is there a
way to 'turn off' the right-select? Groups are allowed to overlap, so I can't just
check to see if the Item underneath is part of a group.
Answer:
You can make a listview descendent that handles the right mouse button differently.
1 type
2 TExlistview = class(TListview)
3 private
4 procedure WMRButtonDown(var msg: TWMRButtonDown); message WM_RBUTTONDOWN;
5 procedure WMRButtonUp(var msg: TWMRButtonUp); message WM_RBUTTONUP;
6 end;
7
8 procedure TExlistview.WMRButtonDown(var msg: TWMRButtonDown);
9 begin
10 MouseDown(mbRight, KeysToShiftState(msg.Keys), msg.XPos, msg.YPos);
11 end;
12
13 procedure TExlistview.WMRButtonUp(var msg: TWMRButtonUp);
14 begin
15 MouseUp(mbRight, KeysToShiftState(msg.Keys), msg.XPos, msg.YPos);
16 end;
This will still fire the mouse events for the right button but do nothing of the
default processing, like right select or popping up the popup menu. If you still
want the menu to pop use:
17
18 procedure TExListview.WMRButtonUp(var msg: TWMRButtonUp);
19
20 function SmallpointToScreen(const pt: TSmallpoint): Longint;
21 var
22 lp: TPoint;
23 begin
24 lp := ClientToScreen(SmallpointToPoint(pt));
25 Result := LongInt(PointToSmallpoint(lp));
26 end;
27
28 begin
29 MouseUp(mbRight, KeysToShiftState(msg.Keys), msg.XPos, msg.YPos);
30 Perform(WM_CONTEXTMENU, handle, SmallpointToScreen(msg.Pos));
31 end;
|