2014-12-04 55 views
2

Delphi中是否可以將項目的.DSK文件中的斷點保存並且沒有其他桌面設置?Delphi 2007:只保存DSK文件中的斷點選項?

大多數.DSK阻礙,但不能保存調試斷點是一個真正的痛苦(特別是當它們有條件或附加操作時)。

+0

因爲現在的我,他們做中間人對HTTPS流量:http://stackoverflow.com/users/3990592/jeroen-pluimers-binck – 2014-12-04 09:14:01

+0

OK,這是有道理的! – 2014-12-04 09:16:45

回答

6

我從來沒有遇到IDE設施,只保存.Dsk文件中的斷點相關設置。

對於娛樂,我想我會試着通過使用OTA通知的IDE加載項來實現某些內容。下面的代碼可以很好地安裝到D7中安裝的軟件包中,IDE似乎很樂意重新打開一個項目,該文件的.Dsk文件已經被它處理(並且斷點已經設置!)。

正如您所看到的,當使用ofnProjectDesktopSave的NotifyCode調用OTA通知程序的FileNotification事件時,它會捕獲OTA通知程序的FileNotification事件,該事件恰好在IDE保存了.Dsk文件(最初帶有擴展名'。$$$',I在第一次寫這篇文章時沒有注意到)。然後它讀取保存的文件文件,並準備除去指定的部分列表之外的所有部分都被刪除的更新版本。用戶然後可以選擇將稀疏文件保存回磁盤。我使用了TMemIniFile來完成大多數處理,只是爲了儘量減少所需的代碼量。

當我讀到你的q時,我沒有寫過OTA通知器的經驗,但下面引用的GE專家常見問題非常有幫助,尤其是示例通告程序代碼。

正常情況下,刪除項目的.Dsk文件是無害的,但請謹慎使用此代碼,因爲它未經過壓力測試。

更新:我注意到TIdeNotifier.FileNotification事件接收到的文件名實際上有一個'。$$$'的擴展名。我不太清楚爲什麼會這樣,但看起來事件在文件重命名爲xxx.Dsk之前被調用。我認爲這需要更改 以保存稀疏版本,但顯然不是。

更新#2:已經使用的文件夾監測工具,看看到底發生了什麼,事實證明,該代碼接收桌面保存通知僅僅是最早的一批的操作有關的.dsk文件。這些包括將任何現有版本的.Dsk文件重命名爲。〜Dsk文件,並最終將。$$$文件保存爲新的.Dsk文件。

unit DskFilesu; 

interface 

{$define ForDPK} // undefine to test in regular app 

uses 
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
    Buttons, StdCtrls, IniFiles, TypInfo 
{$ifdef ForDPK} 
    , ToolsApi 
{$endif} 
    ; 

{$ifdef ForDPK} 

{ 
    Code for OTA TIdeNotifier adapted from, and courtesy of, the link on http://www.gexperts.org/open-tools-api-faq/#idenotifier 
} 

type 
    TIdeNotifier = class(TNotifierObject, IOTANotifier, IOTAIDENotifier) 
    protected 
    procedure AfterCompile(Succeeded: Boolean); 
    procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); 
    procedure FileNotification(NotifyCode: TOTAFileNotification; 
     const FileName: string; var Cancel: Boolean); 
    end; 
{$endif} 

type 
    TDskForm = class(TForm) 
    edDskFileName: TEdit; 
    SpeedButton1: TSpeedButton; 
    OpenDialog1: TOpenDialog; 
    lbSectionsToKeep: TListBox; 
    lbDskSections: TListBox; 
    moDskFile: TMemo; 
    btnSave: TButton; 
    procedure btnSaveClick(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure SpeedButton1Click(Sender: TObject); 
    private 
    procedure GetSectionsToKeep; 
    function GetDskFileName: String; 
    procedure SetDskFileName(const Value: String); 
    function GetDskFile: Boolean; 
    protected 
    public 
    DskIni : TMemIniFile; 
    property DskFileName : String read GetDskFileName write SetDskFileName; 
    end; 

var 
    NotifierIndex: Integer; 
    DskForm: TDskForm; 

{$ifdef ForDPK} 
procedure Register; 
{$endif} 

implementation 

{$R *.DFM} 

{$ifdef ForDPK} 
procedure Register; 
var 
    Services: IOTAServices; 
begin 
    Services := BorlandIDEServices as IOTAServices; 
    Assert(Assigned(Services), 'IOTAServices not available'); 
    NotifierIndex := Services.AddNotifier(TIdeNotifier.Create); 
end; 
{$endif} 

procedure DskPopUp(FileName : String); 
var 
    F : TDskForm; 
begin 
    F := TDskForm.Create(Application); 
    try 
    F.DskFileName := FileName; 
    F.ShowModal; 
    finally 
    F.Free; 
    end; 
end; 

function TDskForm.GetDskFileName: String; 
begin 
    Result := edDskFileName.Text; 
end; 

procedure TDskForm.SetDskFileName(const Value: String); 
begin 
    edDskFileName.Text := Value; 
    if Assigned(DskIni) then 
    FreeAndNil(DskIni); 
    btnSave.Enabled := False; 

    DskIni := TMemIniFile.Create(DskFileName); 
    DskIni.ReadSections(lbDskSections.Items); 
    GetSectionsToKeep; 
end; 

procedure TDskForm.btnSaveClick(Sender: TObject); 
begin 
    DskIni.UpdateFile; 
end; 

procedure TDskForm.FormCreate(Sender: TObject); 
begin 
    lbSectionsToKeep.Items.Add('watches'); 
    lbSectionsToKeep.Items.Add('breakpoints'); 
    lbSectionsToKeep.Items.Add('addressbreakpoints'); 

    if not IsLibrary then 
    DskFileName := ChangeFileExt(Application.ExeName, '.Dsk'); 
end; 

procedure TDskForm.GetSectionsToKeep; 
var 
    i, 
    Index : Integer; 
    SectionName : String; 
begin 
    moDskFile.Lines.Clear; 
    for i := lbDskSections.Items.Count - 1 downto 0 do begin 
    SectionName := lbDskSections.Items[i]; 
    Index := lbSectionsToKeep.Items.IndexOf(SectionName); 
    if Index < 0 then 
     DskIni.EraseSection(SectionName); 
    end; 
    DskIni.GetStrings(moDskFile.Lines); 
    btnSave.Enabled := True; 
end; 

function TDskForm.GetDskFile: Boolean; 
begin 
    OpenDialog1.FileName := DskFileName; 
    Result := OpenDialog1.Execute; 
    if Result then 
    DskFileName := OpenDialog1.FileName; 
end; 

procedure TDskForm.SpeedButton1Click(Sender: TObject); 
begin 
    GetDskFile; 
end; 

{$ifdef ForDPK} 

procedure RemoveNotifier; 
var 
    Services: IOTAServices; 
begin 
    if NotifierIndex <> -1 then 
    begin 
    Services := BorlandIDEServices as IOTAServices; 
    Assert(Assigned(Services), 'IOTAServices not available'); 
    Services.RemoveNotifier(NotifierIndex); 
    end; 
end; 

function MsgServices: IOTAMessageServices; 
begin 
    Result := (BorlandIDEServices as IOTAMessageServices); 
    Assert(Result <> nil, 'IOTAMessageServices not available'); 
end; 

procedure TIdeNotifier.AfterCompile(Succeeded: Boolean); 
begin 
end; 

procedure TIdeNotifier.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); 
begin 
    Cancel := False; 
end; 

procedure TIdeNotifier.FileNotification(NotifyCode: TOTAFileNotification; 
    const FileName: string; var Cancel: Boolean); 
begin 
    Cancel := False; 
    // Note: The FileName passed below has an extension of '.$$$' 
    if NotifyCode = ofnProjectDesktopSave then 
    DskPopup(FileName); 
end; 

initialization 

finalization 
    RemoveNotifier; 
{$endif} 

end. 
+0

哇。謝謝是一個非常聰明的解決方案我稍後會試一試。我喜歡簡單:比我預想的要容易得多。 – 2014-12-04 15:17:40

+0

感謝您的編輯。按照討論,我在編輯後刪除了我的答案。 +1 – 2014-12-04 18:17:50

+1

@ JeroenPluimers-Binck:我的歉意:似乎有關文件擴展名的文件傳回通知者 - 請參閱我的答案的更新部分。 – MartynA 2014-12-04 22:57:02

相關問題