如何将一个方法钩子挂接到Delphi 7 IDE中的编辑事件?

35

我希望在开始编辑 Delphi 7 IDE 中的文件时自动检出它。

ClearCase 是我的版本控制系统,我真的很讨厌在开始编辑前需要检出文件。这总是打断了我的思路流程:我正在尝试解决一个问题,找到需要更改的位置,尝试编辑它,失败,因为该文件是只读的。然后打开 ClearCase,搜索文件,最终检出,再次尝试编辑文件,然后失败,因为IDE仍然认为它是只读的,告诉IDE不是只读的。当我最终返回到代码时,我忘记了我正在尝试做什么。

我找到了这个简单而好用的 ClearCase IDE 集成代码。它能够工作,但使用了已弃用的 ToolIntf unit。我添加了一些快捷方式。这里是一个简化版本(没有尝试编译):

unit clearcase;

interface
uses ToolsApi, ToolIntf;

implementation
uses
  Windows, Dialogs, Classes, ExptIntf, Menus, ShellApi, SysUtils;

type
  TDelphiClearcase = class
  private
    FClearcaseMenu,
    FDoCheckOutPasDfm,
    FDoCheckInPasDfm : TIMenuItemIntf;

    procedure ExecCommand(const command: string; path: PChar = nil);
  public
    destructor Destroy;override;
    procedure DoClick(Sender: TIMenuItemIntf);
    property ClearcaseMenu: TIMenuItemIntf read FClearcaseMenu write FClearcaseMenu;
    property DoCheckOutPasDfm:TIMenuItemIntf write FDoCheckOutPasDfm;
    property DoCheckInPasDfm: TIMenuItemIntf write FDoCheckInPasDfm;
  end;

var
  dcc: TDelphiClearcase = nil;

{ TDelphiClearcase }

destructor TDelphiClearcase.Destroy;
  procedure Remove(item: TIMenuItemIntf);
  begin
    if( item = nil )then
      Exit;
    item.DestroyMenuItem;
    FreeAndNil(item);
  end;
begin
  Remove(FDoCheckOutPasDfm);
  Remove(FDoCheckInPasDfm);
  inherited;
end;

procedure TDelphiClearcase.DoClick(Sender: TIMenuItemIntf);
  function GetPasDfm(const f: string): string;
  var
    aux: string;
  begin
    aux := Copy(f, 1, Length(f) - 4);
    Result := aux + '.pas' + ' ' + aux + '.dfm'
  end;

var
  command, fileName  : string;
begin
  fileName := ToolServices.GetCurrentFile;

  if( Sender = FDoCheckOutPasDfm )then
    command := 'cleartool co ' + GetPasDfm(fileName)
  else if( Sender = FDoCheckInPasDfm )then
    command := 'cleartool ci ' + GetPasDfm(fileName);

  ExecCommand(command);

  ToolServices.ReloadFile(fileName);

end;

procedure TDelphiClearcase.ExecCommand(const command: string; path: PChar);
var
  pi  : TProcessInformation;
  stinfo : TStartupInfo;
begin
  FillChar(stinfo, SizeOf(stinfo), 0);
  stinfo.cb := SizeOf(stinfo);

  if( CreateProcess(nil, PChar(command), nil, nil, True, CREATE_NEW_CONSOLE,
      nil, path, stinfo, pi) )then begin
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess)
  end
end;

procedure CreateMenus;
var
  services: TIToolServices;
begin
  if( BorlandIDEServices = nil )then
    Exit;
  services := ToolServices;

  if( services = nil )then
    Exit;

  dcc := TDelphiClearcase.Create;

  dcc.ClearcaseMenu := services.GetMainMenu.GetMenuItems.InsertItem(6,
    'C&learcase', 'ClearcaseMenu', 'ClearcaseTools', 0, 0, 0,
    [mfEnabled, mfVisible], nil);


  dcc.DoCheckOutPasDfm := dcc.ClearcaseMenu.InsertItem(2,
    'Check Out pas and dfm', 'DoCheckOutPasDfm', 'Undo the check outs', ShortCut(Ord('>'),
    [ssCtrl]), 0, 2,
    [mfEnabled, mfVisible], dcc.DoClick);
  dcc.DoCheckInPasDfm:= dcc.ClearcaseMenu.InsertItem(4,
    'Check In pas and dfm', 'DoCheckInPasDfm', 'Check in current files', ShortCut(Ord('<'),
    [ssCtrl]), 0, 2,
    [mfEnabled, mfVisible], dcc.DoClick);

end;

procedure DestroyMenus;
begin
  FreeAndNil(dcc);
end;

initialization
  CreateMenus;

finalization
  DestroyMenus
end.

我希望在首次编辑只读文件时,能够将其检出。我不知道如何将函数钩子连接到文件的IDE编辑事件。欢迎任何指导。


2
一个可能的解决方法是将您的项目管理在git中,本地进行更改,并在一天结束时将更改推送到Clearcase存储库中。白天无需检出文件,也无需更改只读标志。您可以查看以下问题以获取更多相关信息https://dev59.com/Q3E95IYBdhLWcg3wXcvd - Lieven Keersmaekers
6
天啊,刚刚发现这个问题:https://dev59.com/B0fRa4cB1Zd3GeqP_rsM - neves
4
首先,你不应该使用强制你要签出文件的版本控制系统,因为有其他选择。尝试使用Subversion、Git或Mercurial。如果你真的被Clearcase卡住了,你一定不想意外签出文件,所以不应该尝试自动签出。 - Cosmin Prund
这可能不适用于Delphi 7,但仍然很有趣:http://sourceforge.net/projects/radstudioverins/ 这是Delphi XE的版本洞察项目。 - Kaos
2
我必须使用ClearCase。我们只用它进行集成;日常工作我们使用Mercurial。 - Leonardo Herrera
显示剩余3条评论
2个回答

1
替代编写 API 或类似功能的方法是只需使用快照视图并使用“劫持”功能自动编写文件...然后稍后将其检入即可。

这不是我所问的答案,但你是正确的。劫持文件是使用ClearCase的唯一合理方式。 - neves

0

或者,您可以使用开放的ToolsAPI来监听编辑器中的更改,并在用户更改文件内容时检出该文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接