TListView: Fix dragging (with/without MultiSelect), avoid 2nd context-menu event, fix order for mouse up/down/click/popup events. Issue #0035362, Issue #0035917 and related

git-svn-id: trunk@63012 -
This commit is contained in:
martin 2020-04-18 19:28:35 +00:00
parent ad4d6f4caf
commit 13e6d2cd23

View File

@ -56,6 +56,12 @@ type
// Msg handlers // Msg handlers
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
var
ListViewWindProcInfo: record
ActiveListView: TCustomListView;
NoMouseUp: Boolean;
end;
function ListViewParentMsgHandler(const AWinControl: TWinControl; Window: HWnd; function ListViewParentMsgHandler(const AWinControl: TWinControl; Window: HWnd;
Msg: UInt; WParam: Windows.WParam; LParam: Windows.LParam; Msg: UInt; WParam: Windows.WParam; LParam: Windows.LParam;
var MsgResult: Windows.LResult; var WinProcess: Boolean): Boolean; var MsgResult: Windows.LResult; var WinProcess: Boolean): Boolean;
@ -241,6 +247,10 @@ begin
HandleListViewOwnerData(TCustomListViewAccess(AWinControl)); HandleListViewOwnerData(TCustomListViewAccess(AWinControl));
NM_CUSTOMDRAW: NM_CUSTOMDRAW:
HandleListViewCustomDraw(TCustomListViewAccess(AWinControl)); HandleListViewCustomDraw(TCustomListViewAccess(AWinControl));
LVN_BEGINDRAG, LVN_BEGINRDRAG: begin
if ListViewWindProcInfo.ActiveListView = AWinControl then
ListViewWindProcInfo.NoMouseUp := True;
end;
end; end;
end; end;
end; end;
@ -766,6 +776,13 @@ var
AMsg: UINT; AMsg: UINT;
begin begin
case Msg of case Msg of
WM_CONTEXTMENU:
begin
if ListViewWindProcInfo.ActiveListView <> nil then begin
Result := 1;
exit;
end;
end;
WM_LBUTTONDOWN, WM_RBUTTONDOWN: WM_LBUTTONDOWN, WM_RBUTTONDOWN:
begin begin
// A ListView doesn't get a WM_LBUTTONUP, WM_RBUTTONUP message, // A ListView doesn't get a WM_LBUTTONUP, WM_RBUTTONUP message,
@ -777,23 +794,27 @@ begin
WindowInfo := GetWin32WindowInfo(Window); WindowInfo := GetWin32WindowInfo(Window);
ListView := TListView(WindowInfo^.WinControl); ListView := TListView(WindowInfo^.WinControl);
ListItem := ListView.GetItemAt(WindowInfo^.MouseX, WindowInfo^.MouseY); ListItem := ListView.GetItemAt(WindowInfo^.MouseX, WindowInfo^.MouseY);
ListViewWindProcInfo.ActiveListView := ListView;
ListViewWindProcInfo.NoMouseUp := False;
try
if Msg = WM_LBUTTONDOWN if Msg = WM_LBUTTONDOWN
then AMsg := LM_LBUTTONUP then AMsg := LM_LBUTTONUP
else AMsg := LM_RBUTTONUP; else AMsg := LM_RBUTTONUP;
// for multiselected listbox the message has to be send after current
// message or the list item selecting does not work, also see issue #33330
if not Assigned(ListItem) and ListView.MultiSelect then
begin
Result := WindowProc(Window, Msg, WParam, LParam); Result := WindowProc(Window, Msg, WParam, LParam);
if not (Msg = WM_LBUTTONDBLCLK) and ((Msg = WM_LBUTTONDOWN) or not Assigned(ListView.PopupMenu)) then // for multiselected listbox the message has to be send after current
// message or the list item selecting does not work, also see issue #33330
if (not ListViewWindProcInfo.NoMouseUp) and
(Assigned(ListItem) or ListView.MultiSelect)
then
begin
PostMessage(Window, AMsg, 0, MakeLParam(WindowInfo^.MouseX, WindowInfo^.MouseY)); PostMessage(Window, AMsg, 0, MakeLParam(WindowInfo^.MouseX, WindowInfo^.MouseY));
Exit; end;
finally
ListViewWindProcInfo.ActiveListView:= nil;
end; end;
exit;
if Assigned(ListItem) then
PostMessage(Window, AMsg, 0, MakeLParam(WindowInfo^.MouseX, WindowInfo^.MouseY));
end; end;
end; end;
Result := WindowProc(Window, Msg, WParam, LParam); Result := WindowProc(Window, Msg, WParam, LParam);