Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何查找下一个未选择的ListView项目?_Listview_Delphi_Delphi 2009 - Fatal编程技术网

如何查找下一个未选择的ListView项目?

如何查找下一个未选择的ListView项目?,listview,delphi,delphi-2009,Listview,Delphi,Delphi 2009,我想在ListView中搜索下一个未选中的项目,但只能使用windows API 我尝试了ListView\u FindItem宏,但它不起作用。结果始终为-1: function TNewListView.NextUnselected(I: Integer): Integer; var FindInfo: TLVFindInfo; ItemInfo: TLVItem; begin if not HandleAllocated then Exit(-1) else begin

我想在ListView中搜索下一个未选中的项目,但只能使用windows API

我尝试了
ListView\u FindItem
宏,但它不起作用。结果始终为-1:

function TNewListView.NextUnselected(I: Integer): Integer;
var FindInfo: TLVFindInfo;
    ItemInfo: TLVItem;
begin
 if not HandleAllocated then Exit(-1)
 else begin
   FillChar(ItemInfo, SizeOf(ItemInfo), 0);
   ItemInfo.mask:= LVIF_STATE;
   ItemInfo.state:= 0;
   ItemInfo.stateMask:= LVIS_SELECTED;

   FillChar(FindInfo, SizeOf(FindInfo), 0);
   FindInfo.flags:= LVFI_PARAM;
   FindInfo.lParam:= LPARAM(@ItemInfo);
   Result:= ListView_FindItem(Handle, I, FindInfo);
 end;

您正在使用以下标志调用
ListView\u FindItem()

LVFI_参数

搜索此结构的
lParam
成员与项的
LVITEM
结构的
lParam
成员之间的匹配

它告诉ListView将指定的
TLVFindInfo.lParam
与每个列表项的
lParam
进行比较,直到找到匹配项

如果您在非虚拟模式下使用
TListView
OwnerData=False
),列表项的
lParam
值将保留其相应的
TListItem
对象指针

如果在虚拟模式下使用
TListView
OwnerData=True
),列表项的
lParam
值始终为0

ListView\u FindItem()
(以及底层的
LVM\u FindItem
消息)可以通过其
标题(完整或部分)、其
lParam
1或其位置来搜索列表项,而无需其他搜索

1:例如,
TListItems.IndexOf()
方法使用
ListView\u FindItem()
返回指定的
TListItem
对象的索引,使用
lParam
搜索(仅在非虚拟模式下工作,其中每个项的
lParam
TListItem
对象指针)

您还试图执行
lParam
搜索,但您使用了错误的
lParam
值来搜索!您正在将
TLVFindInfo.lParam
值设置为指向本地
TLVItem
变量的指针
,因此
LVFI_参数
比较将永远找不到匹配的列表项。这就是为什么你总是得到-1的结果

ListView\u FindItem()
在您的示例中基本上执行以下逻辑:

function ListView_FindItem(hWnd: HWND; iStart: Integer; const plvfi: TLVFindInfo): Integer;
var
  lvi: TLVItem;
begin
  for Result := iStart+1 to ListView_GetItemCount(hWnd)-1 do
  begin
    FillChar(lvi, SizeOf(lvi), 0);
    lvi.iIndex := Result;
    lvi.mask = LVIF_PARAM;
    ListView_GetItem(hWnd, lvi);
    if lvi.lParam = plvfi.lParam then // <-- NEVER FINDS A MATCH!
      Exit;
  end;
  Result := -1;
end;
function TNewListView.NextUnselected(StartIndex: Integer): Integer;
begin
  if HandleAllocated then
  begin
    for Result := StartIndex+1 to ListView_GetItemCount(Handle)-1 do
    begin
      if (ListView_GetItemState(Handle, Result, LVIS_SELECTED) and LVIS_SELECTED) = 0 then
        Exit;
    end;

    // if you want to implement wrap-around searching, uncomment this...
    {
    for Result := 0 to StartIndex-1 do
    begin
      if (ListView_GetItemState(Handle, Result, LVIS_SELECTED) and LVIS_SELECTED) = 0 then
        Exit;
    end;
    }
  end;
  Result := -1;
end;
因此,您无法使用
ListView\u FindItem()
/
LVM\u FindItem
按状态搜索项目,它们不支持这种搜索

您可能会尝试使用
ListView\u GetNextItem()
/
LVM\u GetNextItem

搜索具有指定属性且与指定项具有指定关系的列表视图项

但是,它们只能用于搜索已启用指定特征的列表项(例如已选中
LVNI_
已启用)。它们不能用于查找缺少指定特征的项目(例如选择了
LVNI_
禁用)

因此,要执行所需操作,您只需手动迭代列表项,使用
ListView\u GetItem()
ListView\u GetItemState()
检索每个项的当前状态,直到找到要查找的内容

例如:

function ListView_FindItem(hWnd: HWND; iStart: Integer; const plvfi: TLVFindInfo): Integer;
var
  lvi: TLVItem;
begin
  for Result := iStart+1 to ListView_GetItemCount(hWnd)-1 do
  begin
    FillChar(lvi, SizeOf(lvi), 0);
    lvi.iIndex := Result;
    lvi.mask = LVIF_PARAM;
    ListView_GetItem(hWnd, lvi);
    if lvi.lParam = plvfi.lParam then // <-- NEVER FINDS A MATCH!
      Exit;
  end;
  Result := -1;
end;
function TNewListView.NextUnselected(StartIndex: Integer): Integer;
begin
  if HandleAllocated then
  begin
    for Result := StartIndex+1 to ListView_GetItemCount(Handle)-1 do
    begin
      if (ListView_GetItemState(Handle, Result, LVIS_SELECTED) and LVIS_SELECTED) = 0 then
        Exit;
    end;

    // if you want to implement wrap-around searching, uncomment this...
    {
    for Result := 0 to StartIndex-1 do
    begin
      if (ListView_GetItemState(Handle, Result, LVIS_SELECTED) and LVIS_SELECTED) = 0 then
        Exit;
    end;
    }
  end;
  Result := -1;
end;
或:


这两种方法都适用于您正在尝试的操作。

您正在使用以下标志调用
ListView\u FindItem()

LVFI_参数

搜索此结构的
lParam
成员与项的
LVITEM
结构的
lParam
成员之间的匹配

它告诉ListView将指定的
TLVFindInfo.lParam
与每个列表项的
lParam
进行比较,直到找到匹配项

如果您在非虚拟模式下使用
TListView
OwnerData=False
),列表项的
lParam
值将保留其相应的
TListItem
对象指针

如果在虚拟模式下使用
TListView
OwnerData=True
),列表项的
lParam
值始终为0

ListView\u FindItem()
(以及底层的
LVM\u FindItem
消息)可以通过其
标题(完整或部分)、其
lParam
1或其位置来搜索列表项,而无需其他搜索

1:例如,
TListItems.IndexOf()
方法使用
ListView\u FindItem()
返回指定的
TListItem
对象的索引,使用
lParam
搜索(仅在非虚拟模式下工作,其中每个项的
lParam
TListItem
对象指针)

您还试图执行
lParam
搜索,但您使用了错误的
lParam
值来搜索!您正在将
TLVFindInfo.lParam
值设置为指向本地
TLVItem
变量的指针
,因此
LVFI_参数
比较将永远找不到匹配的列表项。这就是为什么你总是得到-1的结果

ListView\u FindItem()
在您的示例中基本上执行以下逻辑:

function ListView_FindItem(hWnd: HWND; iStart: Integer; const plvfi: TLVFindInfo): Integer;
var
  lvi: TLVItem;
begin
  for Result := iStart+1 to ListView_GetItemCount(hWnd)-1 do
  begin
    FillChar(lvi, SizeOf(lvi), 0);
    lvi.iIndex := Result;
    lvi.mask = LVIF_PARAM;
    ListView_GetItem(hWnd, lvi);
    if lvi.lParam = plvfi.lParam then // <-- NEVER FINDS A MATCH!
      Exit;
  end;
  Result := -1;
end;
function TNewListView.NextUnselected(StartIndex: Integer): Integer;
begin
  if HandleAllocated then
  begin
    for Result := StartIndex+1 to ListView_GetItemCount(Handle)-1 do
    begin
      if (ListView_GetItemState(Handle, Result, LVIS_SELECTED) and LVIS_SELECTED) = 0 then
        Exit;
    end;

    // if you want to implement wrap-around searching, uncomment this...
    {
    for Result := 0 to StartIndex-1 do
    begin
      if (ListView_GetItemState(Handle, Result, LVIS_SELECTED) and LVIS_SELECTED) = 0 then
        Exit;
    end;
    }
  end;
  Result := -1;
end;
因此,您无法使用
ListView\u FindItem()
/
LVM\u FindItem
按状态搜索项目,它们不支持这种搜索

您可能会尝试使用
ListView\u GetNextItem()
/
LVM\u GetNextItem

搜索具有指定属性且与指定项具有指定关系的列表视图项

但是,它们只能用于搜索已启用指定特征的列表项(例如已选中
LVNI_
已启用)。它们不能用于查找缺少指定特征的项目(例如选择了
LVNI_
禁用)

因此,要执行所需操作,只需使用
ListView\u GetItem()
L手动迭代列表项即可