6

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

提前致谢

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

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

4

5 回答 5

6

感谢您的提示。Open Tools API 是一种可行的方法,并且可以在设计时从表单上的组件中使用 Open Tools API。

所以这是我的解决方案:

我需要两个单元,一个用于组件,一个用于注册组件和使用 Open Tools API 的代码。

组件单元来了:


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.
于 2010-03-13T00:52:21.653 回答
5

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

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

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

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

(并且不需要像上面亨氏的例子那样使用两个单位)

于 2011-09-08T12:19:52.227 回答
2

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

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

于 2010-03-12T16:58:14.843 回答
1

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

于 2010-03-12T15:53:07.287 回答
1

http://www.gexperts.org/otafaq.html#project

进而

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

可能有帮助

于 2010-03-12T17:17:19.637 回答