Board logo

Subject: 输入助手单词列表类定义单元在处理LoadFromSysPath时会漏掉单元的简单处理办法 [Print This Page]

Author: xychen    Time: 2015-12-9 11:52     Subject: 输入助手单词列表类定义单元在处理LoadFromSysPath时会漏掉单元的简单处理办法

在Uses节输入引用单元的时候,输入助手可以自动提示系统中的所有可引用单元文件列表,但是最近的版本似乎只能识别系统内置的单元,而对用户自己安装的组件不起作用。
单元的列表来自CnInputSymbolList的TUnitNameList类,类的LoadFromSysPath用于获取系统中搜索路径和Lib路径中的pas和dcu文件列表,其中GetLibraryPath用于获取库路径,原始代码如下:

procedure TUnitNameList.LoadFromSysPath;
var
  I: Integer;
  Paths: TStringList;
begin
  Paths := TStringList.Create;
  try
    Paths.Sorted := True;
    GetLibraryPath(Paths, False);

    if not SameText(Paths.Text, FSysPath) then
    begin
      FSysUnits.Clear;
      FCurrList := FSysUnits;
      for I := 0 to Paths.Count - 1 do
      begin
        FindFile(Paths[I], '*.pas', DoFindFile, nil, False, False);
        FindFile(Paths[I], '*.dcu', DoFindFile, nil, False, False);
      end;
      FindFile(MakePath(GetInstallDir) + 'Lib\', '*.dcu', DoFindFile, nil,
        False, False);
      UpdateCaseFromModules(FSysUnits);
      FSysPath := Paths.Text;
    end;
  finally
    Paths.Free;
  end;

  for I := 0 to FSysUnits.Count - 1 do
    AddUnit(FSysUnits[I]);
end;

// 取环境设置中的 LibraryPath 内容
procedure GetLibraryPath(Paths: TStrings; IncludeProjectPath: Boolean);
var
  Svcs: IOTAServices;
  Options: IOTAEnvironmentOptions;
  Text: string;
  List: TStrings;
  procedure AddList(AList: TStrings);
  var
    S: string;
    i: Integer;
  begin
    for i := 0 to List.Count - 1 do
    begin
      S := Trim(MakePath(List));
      if (S <> '') and (Paths.IndexOf(S) < 0) then
        Paths.Add(S);
    end;
  end;
begin
  Svcs := BorlandIDEServices as IOTAServices;
  if not Assigned(Svcs) then Exit;
  Options := Svcs.GetEnvironmentOptions;
  if not Assigned(Options) then Exit;
  List := TStringList.Create;
  try
    Text := ReplaceToActualPath(Options.GetOptionValue('LibraryPath'));
    List.Text := StringReplace(Text, ';', #13#10, [rfReplaceAll]);
    AddList(List);
    Text := ReplaceToActualPath(Options.GetOptionValue('BrowsingPath'));
    List.Text := StringReplace(Text, ';', #13#10, [rfReplaceAll]);
    AddList(List);
    if IncludeProjectPath then
    begin
      GetProjectLibPath(List);
      AddList(List);
    end;
  finally
    List.Free;
  end;
end;

问题出在Options.GetOptionValue('LibraryPath')和Options.GetOptionValue('BrowsingPath'),它们获取的信息不全,直接读取注册表相关键值后能够把所有的单元加载进单元列表,把代码改动如下,但是这个改动只适合特定的平台和Delphi版本,依然有缺陷,不过暂时够我用了,希望开发者看看这个问题,找个完善的解决方案。

//  Text := ReplaceToActualPath(Options.GetOptionValue('LibraryPath'));
  Text := ReplaceToActualPath(RegReadStringDef(HKEY_CURRENT_USER,
    'Software\Embarcadero\BDS\17.0\Library\Win32','Search Path',''));

// Text := ReplaceToActualPath(Options.GetOptionValue('BrowsingPath'));
  Text := ReplaceToActualPath(RegReadStringDef(HKEY_CURRENT_USER,
    'Software\Embarcadero\BDS\17.0\Library\Win32','Browsing Path',''));

[ 本帖最后由 xychen 于 2015-12-9 12:15 编辑 ]
Author: Passion    Time: 2015-12-15 22:45

能否说明一下Options.GetOptionValue('LibraryPath')和Options.GetOptionValue('BrowsingPath'),它们获取的信息不全,具体是怎么个不全法?照理它们应该和注册表里都保持一致才对。
Author: 淹死的鱼    Time: 2015-12-16 16:39

win7  /32

        CnWizards_1.0.9.802_Unstable.exe       

D2007,DXE,DXE10 试过了 ,自己的单元  可以识别啊
Author: xychen    Time: 2015-12-18 22:29

对比如下:

Image Attachment: a.png (2015-12-18 22:29, 7.18 K) / Download count 469
http://bbs.cnpack.org/attachment.php?aid=1029



Image Attachment: b.png (2015-12-18 22:29, 12.19 K) / Download count 490
http://bbs.cnpack.org/attachment.php?aid=1030


Author: xychen    Time: 2015-12-18 22:38

安装完Delphi后,通过其自带的GetIt Package Manager安装JCL和JVCL,然后装CnWizards,装完以后想引用JCL的单元时获得的提示的效果是上面的图片,后来改了代码,可以获得下面的提示效果。为了验证代码,我重新安装了纯净的操作系统和只有JCL、JVCL组件的Delphi开发环境,系统中没有任何其他第三方软件,也没有安装别的组件包,所有Delphi和CnWizards的设置也均采用默认设置未做修改,还是再次复现了上面的差异,但是3楼又说没有问题,我晕菜了。。。
Author: Passion    Time: 2015-12-19 13:55

我们是通过IDE提供的ToolsAPI来获取当前环境设置选项的,照理和注册表读出来的应该一致。目前我也不清楚为啥会出现楼主提到的问题。

我打算加一些调试信息做个Debug版本,楼上是否可以帮记录一下Log并反馈给我们?
Author: Passion    Time: 2015-12-19 14:10

http://www.cnpack.org/downbuilds.php?kind=debug&lang=zh-cn

可否麻烦下载804版本,按本论坛置顶贴的说明,在出现“图片附件 a.png"的情况时,帮我们记录一下Log并发到我们邮箱或上传到此处?
Author: xychen    Time: 2015-12-21 13:42

我在注册表中给每一个编译平台的库路径和浏览路径都加上一个代表平台版本的前缀,然后运行调试版本CnWizards,获得的日志信息表明用Options.GetOptionValue获得的是IOS32平台的注册表项,有点诡异啊!

Image Attachment: 注册表内容.png (2015-12-21 13:42, 33.48 K) / Download count 505
http://bbs.cnpack.org/attachment.php?aid=1032



Image Attachment: 日志信息.png (2015-12-21 13:42, 9.05 K) / Download count 483
http://bbs.cnpack.org/attachment.php?aid=1033


Author: xychen    Time: 2015-12-21 13:56

这是Win32平台的注册表项和Win64平台的注册表项,Options.GetOptionValue无视了他们。。。

Image Attachment: Win32平台注册表.png (2015-12-21 13:56, 36.08 K) / Download count 480
http://bbs.cnpack.org/attachment.php?aid=1034



Image Attachment: Win64平台注册表.png (2015-12-21 13:56, 36.88 K) / Download count 459
http://bbs.cnpack.org/attachment.php?aid=1035


Author: Passion    Time: 2015-12-21 19:17

谢谢反馈。

看来是IDE提供的接口有问题,目前通过ToolsAPI获得的环境接口,并没有地方可以让我们指定当前的Platform。麻烦。
Author: Passion    Time: 2015-12-21 20:39

XE2以上的版本存在此问题。我们目前按楼主的想法修改了一下代码,将XE2下的情形改成从注册表里读取路径数据,每日构建版中的806版本已经集成了此修改,烦请有空下载体验一下?

http://www.cnpack.org/downbuilds.php?lang=zh-cn




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0