mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-19 19:29:25 +02:00
LCL/ListView: implement incremental search in virtual mode for Windows. Issue #39748.
This commit is contained in:
parent
78ff1c894f
commit
0883c8c524
@ -1545,6 +1545,9 @@ type
|
||||
function DoOwnerDataHint(AStartIndex, AEndIndex: Integer): Boolean; virtual;
|
||||
function DoOwnerDataStateChange(AStartIndex, AEndIndex: Integer; AOldState,
|
||||
ANewState: TListItemStates): Boolean; virtual;
|
||||
function DoOwnerDataFind(AFind: TItemFind; const AFindString: string;
|
||||
const AFindPosition: TPoint; AFindData: Pointer; AStartIndex: Integer;
|
||||
ADirection: TSearchDirection; AWrap: Boolean): Integer; virtual;
|
||||
|
||||
protected
|
||||
// Multiselection
|
||||
|
@ -294,7 +294,7 @@ begin
|
||||
end;
|
||||
// LVN_GETDISPINFO:
|
||||
// LVN_ODCACHEHINT:
|
||||
// LVN_ODFINDITEM:
|
||||
// LVN_ODFINDITEM: implemented in win32 widgetset
|
||||
// LVN_ODSTATECHANGED:
|
||||
// LVN_BEGINLABELEDIT: implemented via TCustomListViewEditor
|
||||
// LVN_ENDLABELEDIT: implemented via TCustomListViewEditor
|
||||
@ -883,6 +883,16 @@ begin
|
||||
FOnDataStateChange(Self, AStartIndex, AEndIndex, AOldState, ANewState);
|
||||
end;
|
||||
|
||||
function TCustomListView.DoOwnerDataFind(AFind: TItemFind; const AFindString: string;
|
||||
const AFindPosition: TPoint; AFindData: Pointer; AStartIndex: Integer;
|
||||
ADirection: TSearchDirection; AWrap: Boolean): Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
if Assigned(FOnDataFind) then
|
||||
FOnDataFind(Self, AFind, AFindString, AFindPosition, AFindData, AStartIndex,
|
||||
ADirection, AWrap, Result);
|
||||
end;
|
||||
|
||||
procedure TCustomListView.QueuedShowEditor(Data: PtrInt);
|
||||
begin
|
||||
if fShowEditorQueued and IsVisible then
|
||||
|
@ -232,22 +232,65 @@ var
|
||||
MsgResult := MsgResult or CDRFRESULT[ResultFlag];
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Workaround for issue #39715 to prevent the selection jumping to the first
|
||||
item in virtual mode when a normal key is pressed (the listview probably
|
||||
tries to perform an incremental search in this case which has not been
|
||||
implemented, yet (handler for OnDataFind). }
|
||||
|
||||
{ Implements incremental search for TCustomListView in virtual mode.
|
||||
See:
|
||||
- https://docs.microsoft.com/de-DE/windows/win32/api/commctrl/ns-commctrl-nmlvfinditema
|
||||
- https://docs.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvfindinfoa }
|
||||
procedure HandleListViewFindItem(ALV: TCustomlistViewAccess);
|
||||
var
|
||||
FindInfo: PNMLVFindItem;
|
||||
listitem: TListItem;
|
||||
findItem: PNMLVFindItem;
|
||||
itemFind: TItemFind;
|
||||
findStr: String = '';
|
||||
findStrLen: Integer = 0;
|
||||
findData: Pointer = nil;
|
||||
findPt: TPoint = (X: 0; Y: 0);
|
||||
findDir: TSearchDirection = sdAll;
|
||||
findStart: Integer;
|
||||
findWrap: Boolean;
|
||||
begin
|
||||
if ALV.OwnerData then
|
||||
begin
|
||||
FindInfo := PNMLVFindItem(NMHdr);
|
||||
if Assigned(FindInfo) then
|
||||
findItem := PNMLVFindItem(NMHdr);
|
||||
if Assigned(findItem) then
|
||||
begin
|
||||
MsgResult := -1;
|
||||
if findItem^.lvfi.flags and LVFI_PARAM <> 0 then
|
||||
itemFind := ifData
|
||||
else if findItem^.lvfi.flags and LVFI_PARTIAL <> 0 then
|
||||
itemFind := ifPartialString
|
||||
else if findItem^.lvfi.flags and LVFI_STRING <> 0 then
|
||||
itemFind := ifExactString
|
||||
else if findItem^.lvfi.flags and LVFI_NEARESTXY <> 0 then
|
||||
itemFind := ifNearest
|
||||
else
|
||||
itemFind := ifData;
|
||||
|
||||
case itemFind of
|
||||
ifPartialString, ifExactString:
|
||||
begin
|
||||
findStrLen := SendMessage(ALV.Handle, LVM_GETISEARCHSTRING, 0, 0);
|
||||
if findStrLen > 0 then
|
||||
begin
|
||||
SetLength(findStr, findStrLen);
|
||||
ListView_GetISearchString(ALV.Handle, PChar(findStr));
|
||||
end;
|
||||
end;
|
||||
ifData:
|
||||
findData := Pointer(PtrUInt(findItem^.lvfi.lParam));
|
||||
ifNearest:
|
||||
begin
|
||||
findPt := findItem^.lvfi.pt;
|
||||
case findItem^.lvfi.vkDirection of
|
||||
VK_LEFT: findDir := sdLeft;
|
||||
VK_UP: findDir := sdAbove;
|
||||
VK_RIGHT: findDir := sdRight;
|
||||
VK_DOWN: findDir := sdBelow;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
findstart := findItem^.iStart;
|
||||
findWrap := findItem^.lvfi.flags and LVFI_WRAP <> 0;
|
||||
MsgResult := ALV.DoOwnerDataFind(itemFind, findStr, findPt, findData, findStart, findDir, findWrap);
|
||||
WinProcess := false;
|
||||
end;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user