View Issue Details

IDProjectCategoryView StatusLast Update
0035917LazarusLCLpublic2019-08-11 12:02
ReporternanobitAssigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Platformwin32OSWindowsOS Version10
Product Version2.0.2Product Build 
Target VersionFixed in Version 
Summary0035917: MSWindows: TListView.OnContextPopup is called twice
DescriptionIn TListView (with Multiselect = true),
on empty space (where no item is hit), right click to trigger OnContextPopup.
TListView.OnContextPopup (TControl.WMContextMenu()) is called two times,
thus the menu is shown twice.

The reason is in win32wscustomlistview.inc / ListViewProc() which ignores OnContextPopup.

A solution is: replace
"not Assigned(ListView.PopupMenu))"
with:
"not (Assigned(ListView.PopupMenu) or Assigned(ListView.OnContextPopup)))"

This also requires:
TcustomListView.OnContextPopup to be public instead of protected.

This fixes the reported bug, but the source section is probably not enough overall,
if this section is also related to: https://bugs.freepascal.org/view.php?id=35362
TagsNo tags attached.
Fixed in Revision
LazTarget
WidgetsetWin32/Win64
Attached Files

Relationships

related to 0035362 assignedMichl ListView with MultiSelect incorrectly deselects items on MouseDown 

Activities

nanobit

2019-08-03 11:41

reporter   ~0117552

Last edited: 2019-08-08 18:37

View 3 revisions

I changed ListViewProc() to address more issues (also 0035362).
I'm not a LCL author, so please check/improve, and on many systems.

win32wscustomlistview.inc:
function ListViewProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
    LParam: Windows.LParam): LResult; stdcall;
var
  WindowInfo: PWin32WindowInfo;
  BtnUpMsg: UINT;
begin
  case Msg of
    WM_LBUTTONDOWN, WM_RBUTTONDOWN:
    begin
      WindowInfo := GetWin32WindowInfo(Window);
      WindowInfo^.LastLVNMsg := 0;
      Result := WindowProc(Window, Msg, WParam, LParam);
      if (WindowInfo^.LastLVNMsg = abs(NM_Click)) or (WindowInfo^.LastLVNMsg = abs(NM_RClick)) then
      begin
        WindowInfo^.LastLVNMsg := 0;
        // Condition (GetCapture <> 0) would block too much.
        if (WindowInfo^.MouseX >-1) and (WindowInfo^.MouseY >-1) then
        begin
          if Msg = WM_LBUTTONDOWN
          then BtnUpMsg := LM_LBUTTONUP
          else BtnUpMsg := LM_RBUTTONUP;
          SendMessage(Window, BtnUpMsg, 0, MakeLParam(WindowInfo^.MouseX, WindowInfo^.MouseY));
        end;
      end;
      exit;
    end;
    WM_CONTEXTMENU:
    begin
      WindowInfo := GetWin32WindowInfo(Window);
      WindowInfo^.LastLVNMsg := 0; // smarter would be: reset only if context menu is shown
    end;
  end;
  Result := WindowProc(Window, Msg, WParam, LParam);
end;

------------------------
win32wscustomlistview.inc:
Added StoreListViewMsg() at the end of ListViewParentMsgHandler():

  procedure StoreListViewMsg(ALV: TCustomListViewAccess);
  var
    LVInfo: PWin32WindowInfo;
  begin
    LVInfo := GetWin32WindowInfo(ALV.Handle);
    LVInfo^.LastLVNMsg := Byte( abs(Longint(NMHdr^.code)));
  end;

begin
  Result := False;
  case Msg of
    WM_NOTIFY:
    begin
      case PNMHdr(LParam)^.code of
        LVN_GETDISPINFOA, LVN_GETDISPINFOW:
          HandleListViewOwnerData(TCustomListViewAccess(AWinControl));
        NM_CUSTOMDRAW:
          HandleListViewCustomDraw(TCustomListViewAccess(AWinControl));
        NM_CLICK, NM_RCLICK, LVN_BEGINDRAG, LVN_BEGINRDRAG, LVN_KEYDOWN:
          StoreListViewMsg(TCustomListViewAccess(AWinControl));
      end;
    end;
  end;
end;

------------------------
and in win32proc.pp:

TWin32WindowInfo = record
....
IMEComposed: Boolean;
LastLVNMsg: byte; // added one field
DrawItemHandler: TDrawItemHandlerProc;
....
end;

------------------------
Known issue: The LCL publishes listview OnMouseDown/Up-properties,
but their support is limited and influenced by dragmode/multiselect,
caused by constraints in Windows and LCL. Typically, apps don't use them.
But the builtin mouse-actions and high level events (select, drag, popup, OnClick) work.

Juha Manninen

2019-08-11 12:01

developer   ~0117641

Last edited: 2019-08-11 12:02

View 3 revisions

If you know how to fix it, please create a proper patch.
 https://wiki.lazarus.freepascal.org/Creating_A_Patch
Use the trunk (development version) when creating patches.

Issue History

Date Modified Username Field Change
2019-07-31 20:01 nanobit New Issue
2019-08-03 11:41 nanobit Note Added: 0117552
2019-08-04 15:53 nanobit Note Edited: 0117552 View Revisions
2019-08-08 18:37 nanobit Note Edited: 0117552 View Revisions
2019-08-11 11:41 Juha Manninen Relationship added related to 0035362
2019-08-11 12:01 Juha Manninen Note Added: 0117641
2019-08-11 12:02 Juha Manninen Note Edited: 0117641 View Revisions
2019-08-11 12:02 Juha Manninen Note Edited: 0117641 View Revisions