2008-11-07 38 views

回答

6

是的。除非您從DFM中刪除未在Delphi 2007中發佈的屬性,否則這是不可能的。

+0

你試試我的答案?它似乎對我很有用,上面提到的警告 - D2009特有的屬性在D2007中不會保存回.dfm - 但只要您不修改和重新保存D2007中的表單,它們至少會被保留。 – 2008-11-18 19:36:50

+0

我想這是可能的,只是不太實用 – 2008-11-19 13:03:31

2

每個窗體都有一個dfm文件,其中包含窗體及其組件的屬性設置。某些屬性值具有默認值,因此如果保留默認值,則不會存儲它們。 只是做了一個小測試:

  • 創建於2009年
  • 將窗體添加幾個標準控件
  • 保存
  • 打開它在2006年(抱歉沒有2007這個PC)

它沒有消息的工作。但也許你不那麼幸運。

使用Delphi,在版本之間共享數據通常有點麻煩。升級可能性很大,但降級很麻煩。所以我建議不要在不同版本之間共享表單文件。

據我所知,在dfm文件中添加條件定義是不可能的。但是,再一次,我們真的想要那樣的...我寧願一種忽略未知屬性的機制。

4

德爾菲項目一直非常容易轉向新版本。你必須更加小心,但對於較老的編譯器使用最新的代碼也非常簡單。我在Delphi 2005/2006/2007中維護了其他人仍然需要在Delphi 6和7中使用的代碼。

如果您從DFM中刪除不兼容的屬性,它們應該在舊版本中正常工作,而不會將它們混淆爲Delphi最大的例子是德爾福2006年引入的顯式*屬性。我有一個家庭釀造的「DFM洗滌器」,將它們去掉。請記住,這些屬性存在是有原因的,所以你應該只擦洗那些你打算向後兼容的屬性。

您也可以考慮投資靜態代碼分析工具,如CodeHealer或Pascal Analyzer。除了指出問題(特別是CodeHealer)並幫助您清理代碼之外,您可以選擇要分析哪個版本的Delphi,從而更容易找到除DFM屬性以外的不兼容性。它們可以作爲構建過程的一部分進行自動化。

只是一個說明。共享源代碼,但爲每個版本保留單獨的項目。這在Delphi 2007和Delphi 2009之間尤爲重要。最近的.dproj文件使用相同的擴展名,但與Delphi 2007不兼容。您也可以運行一些帶有不兼容資源的問題。

+0

我不同意Delphi項目輕鬆移植。過去我已經完成了遷移,看起來大多數組件/控件至少需要很小的變化,通常是重大的變化。 這比較說,在Visual Studio中完成的C#項目要糟得多。 – 2009-02-02 02:05:08

2

您可以安全地在窗體的OnCreate方法的代碼中添加屬性,並在它們周圍包裝一個{$ IFDEF VER200} // NEW PROPERTIES {$ ENDIF}。你可以在ifdefs之外離開DoubleBuffered,因爲它是在Delphi 2007中出現的,只是對於屬性檢查員不可用。

您只需要擔心您設置的屬性與默認值不同。對於雙緩衝,如果它設置爲true,則只需要擔心這一點。

在Delphi 2007中加載Delphi 2009表單時,您會收到一個警告,說明某個屬性將被銷燬,請記下這些屬性,因爲這些屬性是您需要處理的。

我正在使用這種方法將代碼從Delphi 2006遷移到Delphi 2009中。我的大多數項目都包含幾個共享單元,並且必須在Delphi 2006中針對運輸版和Delphi 2009進行「下一個」版本的編譯。我還大量使用{$ IFDEF UNICODE}定義,我需要根據例程確保字符串是寬字符串還是ansistring。

14

DoubleBuffered已經在TWinControl一段時間了。 Delphi 2009的不同之處在於它現在已經發布。 如果你可以只忽略錯誤(而不是使屬性的作用,而不是)生活,這裏是一個可能的解決方案:

unit Delphi2009Form; 

interface 

uses 
    Windows, Classes, SysUtils, Controls, Forms; 

type 
{$IFDEF VER200} 
    TDelphi2009Form = class(TForm); 
{$ELSE} 
    TDelphi2009Form = class(TForm) 
    private 
    procedure ReaderError(Reader: TReader; const Message: string; var Handled: Boolean); 
    protected 
    procedure ReadState(Reader: TReader); override; 
    end; 

    TReaderErrorProc = procedure(const Message: string); 

var 
    ReaderErrorProc: TReaderErrorProc = nil; 
{$ENDIF} 

implementation 

{$IFNDEF VER200} 
type 
    THackReader = class(TReader); 

procedure TDelphi2009Form.ReaderError(Reader: TReader; const Message: string; var Handled: Boolean); 
begin 
    with THackReader(Reader) do 
    Handled := AnsiSameText(PropName, 'DoubleBuffered') or AnsiSameText(PropName, 'ParentDoubleBuffered'); 
    if Handled and Assigned(ReaderErrorProc) then 
    ReaderErrorProc(Message); 
end; 

procedure TDelphi2009Form.ReadState(Reader: TReader); 
begin 
    Reader.OnError := ReaderError; 
    inherited ReadState(Reader); 
end; 
{$ENDIF} 

end. 

然後改變的形式聲明,在您的項目從TDelphi2009Form,如繼承:

type 
    TFormMain = class(TDelphi2009Form) 
    ... 

這將在運行時工作 - 屬性錯誤將被忽略。爲了使它在設計時的工作,也創建一個唯一的設計,包裝,加designide.dcp其要求條款,以及下面的單元添加到它:

unit Delphi2009FormReg; 

interface 

uses 
    Delphi2009Form; 

procedure Register; 

implementation 

uses 
    DesignIntf, DesignEditors, ToolsAPI; 

procedure ShowReaderError(const Message: string); 
begin 
    with BorlandIDEServices as IOTAMessageServices do 
    AddTitleMessage(Message); 
end; 

procedure Register; 
begin 
    RegisterCustomModule(TDelphi2009Form, TCustomModule); 
    ReaderErrorProc := ShowReaderError; 
end; 

initialization 

finalization 
    ReaderErrorProc := nil; 

end. 

安裝包在Delphi 2007 IDE和財產在IDE中打開表單時,DoubleBuffered和ParentDoubleBuffered屬性的錯誤將被自動忽略。 在Delphi 2007中保存表單時,這些屬性的值將會丟失,因此您應該用代碼初始化它們。

編輯:我添加的代碼輸出讀者錯誤信息到IDE消息窗口:

IDE error messages