2006. február 19., vasárnap

Not select an item in a TListView


Problem/Question/Abstract:

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.

type
  TExlistview = class(TListview)
  private
    procedure WMRButtonDown(var msg: TWMRButtonDown); message WM_RBUTTONDOWN;
    procedure WMRButtonUp(var msg: TWMRButtonUp); message WM_RBUTTONUP;
  end;

procedure TExlistview.WMRButtonDown(var msg: TWMRButtonDown);
begin
  MouseDown(mbRight, KeysToShiftState(msg.Keys), msg.XPos, msg.YPos);
end;

procedure TExlistview.WMRButtonUp(var msg: TWMRButtonUp);
begin
  MouseUp(mbRight, KeysToShiftState(msg.Keys), msg.XPos, msg.YPos);
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:

procedure TExListview.WMRButtonUp(var msg: TWMRButtonUp);

  function SmallpointToScreen(const pt: TSmallpoint): Longint;
  var
    lp: TPoint;
  begin
    lp := ClientToScreen(SmallpointToPoint(pt));
    Result := LongInt(PointToSmallpoint(lp));
  end;

begin
  MouseUp(mbRight, KeysToShiftState(msg.Keys), msg.XPos, msg.YPos);
  Perform(WM_CONTEXTMENU, handle, SmallpointToScreen(msg.Pos));
end;

Nincsenek megjegyzések:

Megjegyzés küldése