Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.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
Delphi 组件在设计时如何确定项目目录_Delphi_Delphi 2010_Components_Design Time - Fatal编程技术网

Delphi 组件在设计时如何确定项目目录

Delphi 组件在设计时如何确定项目目录,delphi,delphi-2010,components,design-time,Delphi,Delphi 2010,Components,Design Time,我编写了一个组件,它应该存储一些与项目目录相关的信息。每次更改组件的属性时,它都应该写入一个文件。那么组件如何在设计时确定当前项目目录呢 提前谢谢 编辑: 我希望在每次更改组件的属性时生成一个delphi源文件,以便在编译代码时始终获得最新版本。把它想象成一种代码生成器 目前,我设置了源代码应该存储的完整路径和文件名,但我更喜欢项目的相对路径(或包含我的组件的表单/数据模块),以便于在不同的开发人员机器上复制项目。我不认为可以。您可以很容易地确定EXE运行的目录,但您的组件在设计时是作为IDE的

我编写了一个组件,它应该存储一些与项目目录相关的信息。每次更改组件的属性时,它都应该写入一个文件。那么组件如何在设计时确定当前项目目录呢

提前谢谢

编辑:
我希望在每次更改组件的属性时生成一个delphi源文件,以便在编译代码时始终获得最新版本。把它想象成一种代码生成器


目前,我设置了源代码应该存储的完整路径和文件名,但我更喜欢项目的相对路径(或包含我的组件的表单/数据模块),以便于在不同的开发人员机器上复制项目。

我不认为可以。您可以很容易地确定EXE运行的目录,但您的组件在设计时是作为IDE的一部分运行的。我怀疑组件是否有办法通过IDE访问项目信息。

组件无法访问源路径,因为组件放置在应用程序中,并作为应用程序的一部分在Delphi IDE之外运行

如果您想要访问项目路径,或者自动化IDE中的任何流程;您必须使用OpenTools API编写IDE专家,而不是组件。

请参阅

然后

www.href.com/pub/sw/ProjectOptions.html


可能会有帮助

谢谢你的提示。OpenToolsAPI是一种方法,在设计时从表单上的组件使用OpenToolsAPI是可能的

因此,我的解决方案如下:

我需要两个单元,一个用于组件,另一个用于注册使用OpenToolsAPI的组件和代码

下面是组件单元:


unit TestLabels;

interface

uses
  SysUtils, Classes, Windows, Controls, StdCtrls;

type
  TTestLabel = class(TLabel)
  private
    FTestProperty: Boolean;
    procedure SetTestProperty(const Value: Boolean);
    procedure Changed;
  published
    property TestProperty: Boolean read FTestProperty write SetTestProperty;
  end;

var
  OnGetUnitPath: TFunc;

implementation

{ TTestLabel }

procedure TTestLabel.Changed;
begin
  if not (csDesigning in ComponentState) then
     Exit; // I only need the path at designtime

  if csLoading in ComponentState then
     Exit; // at this moment you retrieve the unit path which was current before

  if not Assigned(OnGetUnitPath) then
    Exit;

  // only for demonstration
  Caption := OnGetUnitPath;
  MessageBox(0, PChar(ExtractFilePath(OnGetUnitPath)), 'Path of current unit', 0);
end;

procedure TTestLabel.SetTestProperty(const Value: Boolean);
begin
  if FTestProperty  Value then
  begin
    FTestProperty := Value;
    Changed;
  end;
end;

end.
以下是用于注册组件和调用Open Tools API的单元:


unit TestLabelsReg;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, TestLabels;

procedure register;

implementation

uses
  ToolsAPI;

function GetCurrentUnitPath: String;
var
  ModuleServices: IOTAModuleServices;
  Module: IOTAModule;
  SourceEditor: IOTASourceEditor;
  idx: integer;

begin
  Result := '';
  SourceEditor := nil;

  if SysUtils.Supports(BorlandIDEServices, IOTAModuleServices,
    ModuleServices) then
  begin
    Module := ModuleServices.CurrentModule;

    if System.Assigned(Module) then
    begin
      idx := Module.GetModuleFileCount - 1;

      // Iterate over modules till we find a source editor or list exhausted
      while (idx >= 0) and not SysUtils.Supports(Module.GetModuleFileEditor(idx), IOTASourceEditor, SourceEditor) do
        System.Dec(idx);

      // Success if list wasn't ehausted.
      if idx >= 0 then
        Result := ExtractFilePath(SourceEditor.FileName);
    end;

  end;

end;

procedure register;
begin
  RegisterComponents('Samples', [TTestLabel]);
  TestLabels.OnGetUnitPath := GetCurrentUnitPath;
end;

end.

从delphi 7开始,ToolsAPI单元定义一个getActiveProject函数,该函数返回当前项目的IOTAProject接口

IOTAProject的fileName属性返回项目主源文件(通常为.dpr文件)的完整路径

因此,在许多情况下,可以使用简单的指令,例如:

if csDesigning in componentState then
    appFolderPath := extractFilePath( getActiveProject.fileName ) 
else
    appFolderPath := extractFilePath( application.exeName );

(没有必要像上面亨氏的例子那样使用两个单位)

这不是我想听到的。:-)我希望可以从我的组件访问IDE的设计API。看看OTAPI,它可以访问IDE的设计API,但我认为不能将OTAPI功能与表单上的组件混合使用。@Heinz:正如Mason所说,不是从您的组件。您可以使用开放工具API(OTAPI)从IDE专家那里获得。将OTAPI与组件混合是可能的(请参阅我的解决方案),我非常确定您的GetCurrentUnitPath不会编译(至少while循环的布尔表达式不会编译),而while循环将永远不会结束。但是这个想法很有趣,所以我对你的答案投了赞成票。@Jeroen:谢谢你指出这一点。stackoverflow.com编辑器裁剪了行“while not((idx<0)或SysUtils.Supports(Module.GetModuleFileEditor(idx)、IOTASourceEditor、SourceEditor)do”。我已经调整了while循环的条件,以便stackoverflow.com正确显示。顺便说一句,提取了CurrentUnitPath(经过修改)来自delphi附带的DUnit wizzard。到gexperts otafaq的链接非常有用。