吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1499|回复: 7
收起左侧

[求助] 大事不好了!控件神经了!输出结果时好时坏!

[复制链接]
冥界3大法王 发表于 2024-3-10 21:50
本帖最后由 冥界3大法王 于 2024-3-10 21:56 编辑

控件需要在此下载:https://www.alphaskins.com/dwnld.php不然没有  sShellListView1这个控件哟~~

故事是这样的,我要加一个编辑框过滤文件的功能


uses
   IOUtils, Types;

procedure TMainForm.File_Filter_EditKeyPress(Sender: TObject; var Key: Char);
var
  dir: TDirectory;
  files: TStringDynArray;
  str: string;
  List: TListItem;====================================>后来单独加的
begin
  sShellListView1.clear;
  if Key = #13 then
  begin
    files := dir.GetFiles(数据路径);      
    for str in files do
    begin
//       showmessage(str);                                      文件全路径
//       showmessage(ExtractFileName(str));          只取文件名
      if Pos(File_Filter_Edit.text, ExtractFileName(str)) > 0 then
      begin
        List.SubItems.Add(str);==============================>后来单独加的
//       sShellListView1.AddItem(ExtractFileName(str), sShellListView1); //神经的代码在这句上,时而过滤输出结果是正确的
//        Memo1.Lines.Add(str);         算法是对的!上一句有问题!Add加到Memo上没问题啊!!!
      end;
      ShowMessage(List.ToString);===========================>后来单独加的
//     List.SubItems.Assign(sShellListView1.Items);=================>后来单独加的
    end;
  end;
end;


开始以为是因为
  if Pos(File_Filter_Edit.text, ExtractFileName(str)) > 0 then 这句造成的,所以后来加了红字部分
因为确实会不严谨,所以后来加了为了局部匹配对比

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

爱飞的猫 发表于 2024-3-11 01:47
本帖最后由 爱飞的猫 于 2024-3-11 01:54 编辑

因为你没有提供最小复现的项目代码,我也不懂 Delphi 的 IDE。

你文中提到的 AlphaSkins 是控件皮肤库,和 Delphi 本身没啥关系。本身应继承自 TShellList 控件。


网上晃悠了一圈,发现 Lazarus 使用的 Free Pascal 自带了这个 TShellList 控件而且不用额外配置,所以我就用它了。

(1) 第一种方法是利用 FileUtil.FindAllFiles 来进行过滤,但 Delphi 好像没这个东西:

procedure TForm1.BtnFilterClick(Sender: TObject);
var
  i: Integer;
  ListOfFiles: TStringList;
begin
     ListOfFiles := TStringList.Create;
     FileUtil.FindAllFiles(ListOfFiles, Dir_Input.Directory, Edit_Filter.Text, False, faAnyFile);

     shellListView.Clear;
     for i := 0 to ListOfFiles.Count - 1 do
     begin
       shellListView.AddItem(ExtractFileName(ListOfFiles[i]), TStringWrapper.Create(ListOfFiles[i]));
     end;
end;

(2) 第二种方法则是用 System.SysUtils 中的 FindFirst/FindNext/FindClose 来查找信息:

procedure TForm1.BtnFilter2Click(Sender: TObject);
var
  SearchRecord: TSearchRec;
  FilePath: String;
begin
     shellListView.Clear;
     if FindFirst(Dir_Input.Directory + DirectorySeparator + Edit_Filter.Text, faAnyFile, SearchRecord) = 0 then
     begin
       repeat
         if (SearchRecord.Attr and faDirectory) <> 0 then continue;
         FilePath := Dir_Input.Directory + DirectorySeparator + SearchRecord.Name;
         shellListView.AddItem(SearchRecord.Name, TStringWrapper.Create(FilePath));
       until FindNext(SearchRecord) <> 0;
       FindClose(SearchRecord);
     end;
end;

实测效果如下:

完整项目代码(使用 Lazarus IDE 编译)和编译后的文件:52pj-tid-1898934-Pascal文件过滤.7z

 楼主| 冥界3大法王 发表于 2024-3-11 09:52
@爱飞的猫
我去搜索这个控件名
image.png
搜索出来的东西外来安装的控件
image.png
如图所示,我觉得最有问题可能的就是最后一个参数。它说的是啥?对象。
如果输出结果到Memo1,则和预期结果一样。
我现在严重怀疑这个对象我的写法有问题。
明明上面POS函数对比的结果是对的。可是不对的结果为啥反而添加到了文件列表?可是为啥Memo1中添加来的却又是对的?
所以综合而看,我方认为最后一个参数对象,我写得有问题。改成啥呢?



其实我也可以直接扔一个JamExplorerBrowser1控件,选项中开启显示文件路径、过滤栏即可。一行代码也不用写。
 楼主| 冥界3大法王 发表于 2024-3-11 10:02
现在得到新结论:
我尝试把最后一个 对象参数修改为其他任意的控件名,都能调试通过。
但最终输出结果还是时对时不对。
所以,是不是 sShellListView1.AddItem 这个方法用的不对?

点评

[md]你应当参考库的文档。通常第二个参数的对象通常是与该项目相关联的数据,方便取 `.Selected.Data` 的时候用。 另外如果只是过滤到列表,你也可以考虑用回标准的 `TListView` 控件。[/md]  详情 回复 发表于 2024-3-11 11:11
爱飞的猫 发表于 2024-3-11 11:11
冥界3大法王 发表于 2024-3-11 10:02
现在得到新结论:
我尝试把最后一个 对象参数修改为其他任意的控件名,都能调试通过。
但最终输出结果还 ...

你应当参考库的文档。通常第二个参数的对象通常是与该项目相关联的数据,方便取 .Selected.Data 的时候用。

另外如果只是过滤到列表,你也可以考虑用回标准的 TListView 控件。

 楼主| 冥界3大法王 发表于 2024-3-11 11:14
本帖最后由 冥界3大法王 于 2024-3-11 11:26 编辑

@爱飞的猫
我又换了个写法: 还是输出效果时而抽风。算了,扔个简单的实现控件就不纠结了,以后有时间再说。
感谢版主哥解答。
procedure TMainForm.File_Filter_EditKeyPress(Sender: TObject; var Key: Char);
var
  dir: TDirectory;
  files: TStringDynArray;
  str: string;
  ListItem: TListItem;
begin
  sShellListView1.clear;
  Memo1_BaoPo.Clear;                               //仅为测试
  if Key = #13 then
  begin
    files := dir.GetFiles(数据路径);   
    for str in files do
    begin
      if Pos(File_Filter_Edit.text, ExtractFileName(str)) > 0 then
      begin
//sShellListView1.AddItem(ExtractFileName(str), sShellListView1);                           //版本1写法时对时错
        ListItem := sShellListView1.Items.Add;
        ListItem.Caption := str;                                                                                
//版本2写法时对时错
        Memo1_BaoPo.Lines.Add(str);            //仅为测试
      end;
    end;
  end;
end;
wyw6813 发表于 2024-3-11 13:44
你的用法可能不对,VCL框架下TListView用法如下,你的那个控件可能继承自TListView,用法应该类似。
[Delphi] 纯文本查看 复制代码
uses
  Vcl.ComCtrls;

procedure TForm1.AddDataToListView;
var
  ListItem: TListItem;
  I: Integer;
begin
  ListView1.Items.BeginUpdate;
  
  try
    for I := 0 to 5 do
    begin
      ListItem := ListView1.Items.Add;
      ListItem.Caption := 'Item ' + IntToStr(I);
      ListItem.SubItems.Add('Detail of Item ' + IntToStr(I));
      // 可以根据需要添加更多子项
    end;
  finally
    ListView1.Items.EndUpdate;
  end;
end;
 楼主| 冥界3大法王 发表于 2024-3-11 16:47
本帖最后由 冥界3大法王 于 2024-3-11 16:56 编辑

@wyw6813
我试着把你的代码的控件名修改了一下,没报错,也没刷新。
然后编译debug版,32位发布版本,64位的竟然把IDE卡死了。
控件需要在此下载:https://www.alphaskins.com/dwnld.php不然没有  sShellListView1这个控件哟~~


[Delphi] 纯文本查看 复制代码
procedure TForm2.Button1Click(Sender: TObject);
var
  ListItem: TListItem;
  I: Integer;
begin
  sShellListView1.Items.BeginUpdate;
  try
    for I := 0 to 5 do
    begin
      ListItem := sShellListView1.Items.Add;
      ListItem.Caption := 'Item ' + IntToStr(I);
      ListItem.SubItems.Add('Detail of Item ' + IntToStr(I));
      // 可以根据需要添加更多子项
    end;
  finally
    sShellListView1.Items.EndUpdate;
  end;
  sShellListView1.Refresh;
end;

应该你说的对。这个控件里这部分帮助的方法啥的说的极少,应该是继承关系。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-6 14:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表