Borland® Delphi® 2005 Migration to .NET using VCL for .NET
by Bob Swart, Bob Swart Training & Consultancy
數據訪問
我們已經將一個VCL應用程序移植到.NET, 現在是時候來操作一個大點的項目了, 這次將會有更多的實際應用會遇到的問題. 這次代碼中包括數據訪問, 所以, 讓我們到Delphi7\Demos\Db 下看看. 在目錄的几個範例中, MastApp和IBMastApp是最大的, 有最多的unit(單元)和form(窗體).
如果你沒有安裝Delphi7, 那你也可打開BDS\3.0\Demos\DelphiWin32\Db目錄, 裹面同樣有MastApp 和 IBMastApp這兩個項目(但已經移植到新的項目格式了-包括bdsproj文件).
MastApp已經被移植到.NET了, 你能在BDS\3.0\Demos\Delphi.NET\DB\MastApp這個目錄下找到對應的版本, 而IBMastApp還沒移植到VCL for .NET, 所以, 你無法在BDS\3.0\Demos\Delphi.NET\DB or BDS\3.0\Demos\Delphi.NET\VCL\Db找到對應的版本.
所以, 作為我們一個重要的示範, 讓我們開始將IBMastApp應用程序從Win32移植到.NET下—一個看起來比較復雜的數據庫應用程序範例.
首先, 我們還是將必要的文件作個備份.
在BDS\3.0\Demos\Delphi.NET\VCL\Db目錄下創建一個新的子目錄, 名字為IBMastApp. 我們工作到最後, 會得到一個新的Delphi for .NET VCL DB項目的範例.
將BDS\3.0\Demos\DelphiWin32\VCLWin32\Db\IBMastApp目錄下的所有文件復製到BDS\3.0\Demos\Delphi.NET\VCL\Db\IBMastApp目錄下
將文件mastapp.bdsproj刪除, 因為這個文件包含了指定這個項目為Delphi Win32項目的信息(而現在我們是要將其移植到.NET)
現在我們已經準備好了開始在一個新的IBMastApp項目上工作, 并將其移植到.NET了.
運行Delphi 2005
在歡迎頁面(Welcome Page)上點擊Open Project按鈕, 并打開BDS\3.0\Demos\Delphi.NET\VCL\Db\IBMastApp目錄下的mastapp.dpr文件(因為我們是Win32的範例中復製過來的)
因為項目沒有包含有.bdsproj文件, Delphi 2005 IDE 需要詢問你來确定是陞級這個項目為Win32還是.NET的項目. 所以, 會彈出一個陞級對話框詢問你, 如下圖
在項目陞級對話框中選擇將mastapp陞級為.NET
選擇Delphi for .NET, 并且按Ok按鈕
我們會得到一個帶有.NET personality信息的mastapp.bdsproj文件. 現在保存文件, 新的個性信息將會保存到mastapp.bdspro文件.
選擇菜單File | Save All, mastapp項目所有的文件會被保存, 包括文件mastapp.bdsproj.
移植數據模塊(Data Module)
現在我們已經將這個項目關聯為Delphi for .NET, 接下來首先要檢查的是數據庫控件是不是指向正确的數據聯接. 你必須在編繹之前做這個工作.當數據聯接配置正常時, 我們就能將精力集中在代碼的移植上.
打開數據模塊(data module), 也就是DataMod.pas. 你可以在項目管理器(Project Manager)中直接雙擊DataMod.pas對應的節點
數據模塊設計如下面屏幕截圖所示, 采用了InterBase Express作為數據訪問的架構
設計期的VCL for .NET數據模塊
我們必須重新設置Database控件, 在數據模塊的右下角可以找到它.
點擊數據模塊上的Database控件(對應的類型為TIBDatabase)
右鍵點擊Database控件, 會顯示一個彈出菜單告訴你現在使用的是InterBaseExpress (9.09), 還有可以編繹數據源的選項Database Editor. 選擇Database Editor, 會顯示一個對話框如下圖:
Database控件編繹框
注意,這裹的D:\是文件路徑所在. 你可能要修改成C:\, 并且使用Common Files 代替路徑中的Borland才可以設置InterBase聯接到這個數據庫. 我默認是將mastsql.gdb安裝到C:\Program Files\Common Files\Borland Shared\Data\mastsql.gdb—你的設置可能有點不同
點擊Test按鈕來驗證是否能夠正确聯接到了InterBase數據庫mastsql.gdb. 如果不是, 确認mastsql.gdb是不是在指定的路徑上, 還有檢查InterBase是不是已經運行了.
如果點擊了Test按鈕後,你得到了"Successful Connection"的信息, 你就可以關閉數據控件編輯器.
*注意在每一次你移植VCL項目到.NET時, 你可能都需要做這個動作: 第一, 确認數據模塊上的數據訪問控件能指到正确的數據庫. 并且,雖然大部分的數據庫控件都有對應的VCL for .NET的版本, 但是在.NET下不支持SQL鏈接, 所以, 你必須將這些項目移植改為使用dbExpress, dbGo for ADO, InterBaseExpress或者其它VCL for .NET的數據訪問技術.
移植源代碼
當數據模塊和指定的數據訪問控件修改成功後, 我們能開始第一次的項目編繹工作.
按Shift+F2來保存項目中所有的文件
按Ctrl+F9第一次編繹mastapp項目
你將會得到大概17條警告信息, 還有一個錯誤信息, 如下所示:
[Warning] mastapp.dpr(23): W1005 Unit 'Borland.Vcl.Forms' is specific to a platform
[Warning] MAIN.PAS(6): W1005 Unit 'Borland.Vcl.Windows' is specific to a platform
[Warning] MAIN.PAS(6): W1005 Unit 'Borland.Vcl.Messages' is specific to a platform
[Warning] MAIN.PAS(6): W1005 Unit 'Borland.Vcl.Graphics' is specific to a platform
[Warning] MAIN.PAS(6): W1005 Unit 'Borland.Vcl.Controls' is specific to a platform
[Warning] MAIN.PAS(7): W1005 Unit 'Borland.Vcl.Forms' is specific to a platform
[Warning] MAIN.PAS(7): W1005 Unit 'Borland.Vcl.Dialogs' is specific to a platform
[Warning] MAIN.PAS(7): W1005 Unit 'Borland.Vcl.Buttons' is specific to a platform
[Warning] MAIN.PAS(7): W1005 Unit 'Borland.Vcl.StdCtrls' is specific to a platform
[Warning] MAIN.PAS(7): W1005 Unit 'Borland.Vcl.Menus' is specific to a platform
[Warning] MAIN.PAS(7): W1005 Unit 'Borland.Vcl.ExtCtrls' is specific to a platform
[Warning] DataMod.pas(8): W1005 Unit 'Borland.Vcl.Windows' is specific to a platform
[Warning] DataMod.pas(8): W1005 Unit 'Borland.Vcl.Messages' is specific to a platform
[Warning] DataMod.pas(8): W1005 Unit 'Borland.Vcl.Graphics' is specific to a platform
[Warning] DataMod.pas(8): W1005 Unit 'Borland.Vcl.Controls' is specific to a platform
[Warning] DataMod.pas(8): W1005 Unit 'Borland.Vcl.Forms' is specific to a platform
[Warning] DataMod.pas(8): W1005 Unit 'Borland.Vcl.Dialogs' is specific to a platform
[Fatal Error] DataMod.pas(9): F1026 File not found: 'VarUtils.dcuil'
我們可以先忽略警告的信息—因為大部分只是提醒我們現在在使用VCL for .NET的單元只能運行于特定的平台. 為了避免老是出現這此平台警告信息, 你能夠屏蔽掉它們.
選擇Project | Options打開項目管理選項(Project Options). 在編繹信息類別(Compiler Messages category)中, 你可以將"Platform Unit"的警告選擇去掉(如下圖屏幕截圖如示). 如果你現在再重新編繹項目, 你就不會再得到同類的警告信息了.
項目管理選項—警告信息列表
選擇菜單Project | Build mastapp, 或者也可按Shift+F9來執行編繹. 現在, 原來的17個警告信息已經沒再出現了, 但還是會有錯誤信息.
[Fatal Error] DataMod.pas(9): F1026 File not found: 'VarUtils.dcuil'
引起這個錯誤的原因是VarUtils這個單元在于VCL for .NET中已經取消了(比較可能的是合并到Variants單元了).所以, 我們能夠將不在存在的VarUtils單元從uses 子句中移除.
將VarUtils從DataMod.pas 文件interface 處的uses 部分中移除
*注意如果你想你的項目還能同時在Win32下編繹, 你可能更願意將VarUtils單元放置在一對{$IFDEF WIN32} .... {$ENDIF}區塊中, 而不是簡單的將它從uses 子句中移除掉.
如果你決定采用IFDEF的解決方案, 可以象下面一樣修改uses clause 子句:
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
DB, IBQuery, IBCustomDataSet, IBTable, IBDatabase, IB, Variants
{$IFDEF WIN32}, VarUtils {$ENDIF};
按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目
現在的結果是出現3個提示和2個錯誤
[Error] EDCUST.PAS(54): E2010 Incompatible types: 'Variant' and 'Double'
[Fatal Error] BrCstOrd.pas(48): F2063 Could not compile used unit 'EDCUST.PAS'
這個包含引起類型不兼容代碼錯誤的討厭函數如下所示:
procedure TEdCustForm.Edit(CustNo: Double);
begin
MastData.Cust.Open;
MastData.Cust.Locate('CustNo', CustNo, []);
ShowModal;
end;
這個錯誤信息是提示參數CustNo在MastData.Cust.Locate不匹配引起. 它的類型是Double, 但函數要求的是一個Variant類型. 這樣寫應該沒問題, 但是需要將Variants這個單元增加到uses子句中, 編繹器才能通過編繹.
增加Variants單元到Edcust.pas文件中implementation部分的uses子句中
按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目
現在會得到3個提示和1 個錯誤信息.
[Fatal Error] EDORDERS.PAS(10): F1026 File not found: 'DBLookup.dcuil'
這個指出DBLookup單元已經不存在VCL for .NET中了—或者需要在這個項目中引用它. 我們可以簡單將它移除了解決這個錯誤.
從Edorders.pas.的interface部分在uses 子句中將DBLookup單元移除.
*注意,如果你想你的項目還能和Win32兼容, 你可以將DBLookup單元放在{$IFDEF WIN32} .... {$ENDIF}區塊中, 而不是簡單的將其從uses子句刪除.
如果你決定采用IFDEF的解決方法, 你可以象下面一樣修改代碼:
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Dialogs, Forms, StdCtrls, DBGrids, DBCtrls, DB,
Buttons, Grids, {$IFDEF WIN32} DBLookup, {$ENDIF} ExtCtrls, Mask;
P按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目.
現在會得到3個提示, 還有4個錯誤.
[Error] SrchDlg.pas(54): E2010 Incompatible types: 'Variant' and 'Double'
[Error] SrchDlg.pas(64): E2010 Incompatible types: 'Variant' and 'Double'
[Error] SrchDlg.pas(98): E2010 Incompatible types: 'Variant' and 'TCaption'
[Fatal Error] EDORDERS.PAS(76): F2063 Could not compile used unit 'SrchDlg.pas'
前三個錯誤和我們剛才解決的錯誤非常相似, 同樣可以通過在uses子句中增加Variants單元來解決.
在SrchDlg.pas單元的implementation部分下的uses子句中增加Variants單元
按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目
現在出現3個提示, 1個警告,還有2個錯誤信息.
[Error] EDORDERS.PAS(105): E2010 Incompatible types: 'Variant' and 'Double'
[Warning] EDORDERS.PAS(229): W1050 WideChar reduced to byte char in set expressions
[Fatal Error] BrCstOrd.pas(48): F2063 Could not compile used unit 'EDORDERS.PAS'
現在我們已經知道錯誤的原因, 還有解決方法了. 警告信息部分, 將會在接下來得到處理—還是讓我們先集中精力處理掉所有的編繹錯誤.
給Edorders.pas單元的implementation部分下的uses 子句增加Variants單元.
按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目
現在還有3個提示, 1個警告, 和3個錯誤信息
給
BrCstOrd.pas單元的implementation部分下的uses 子句增加Variants單元.
按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目
現在會得到3個提示, 1個警告, 和1個錯誤信息
將DBLookup從Edparts.pas 的(interface 下)uses子句中刪除, 或者將DBLookup單元放置到一個{$IFDEF WIN32}的區塊中, 如下所示:
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs, DB, StdCtrls, ExtCtrls, Mask, DBCtrls,
{$IFDEF WIN32} DBLookup, {$ENDIF} Buttons;
按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目
現在會得到3個提示, 1個警告, 和2個錯誤信息
給Edparts.pa單元的implementation部分下的uses 子句增加Variants單元.
按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目
現在會得到3個提示, 1個警告, 和2個錯誤信息
給
Brparts.pas單元的implementation部分下的uses 子句增加Variants單元.
按Shift+F2保存項目的所有文件, 然後按Shift+F9來重新編繹項目
如果你運行的是已經陞級過(安裝過補丁)的Delphi 2005版本, 那麼現在你的程序已經能夠通過編繹和鏈接了, 你可以直接參考本文的"運行野生海產入口登記程序(Running the Marine Adventure Order Entry Application)"部分. 如果你發現還是遇到錯誤, 那可接著往下看.
現在會得到3個提示, 1個警告, 和1個嚴重錯誤信息
[Hint] DataMod.pas(244): H2443 Inline function 'ExpandFileName' has not been expanded
because unit 'System.IO' is not specified in USES list
[Hint] DataMod.pas(743): H2443 Inline function 'FileExists' has not been expanded because
unit 'System.IO' is not specified in USES list
[Hint] DataMod.pas(748): H2443 Inline function 'ExtractFileName' has not been expanded
because unit 'System.IO' is not specified in USES list
[Warning] EDORDERS.PAS(229): W1050 WideChar reduced to byte char in set expressions
[Fatal Error] CustRpt.pas(6): F1026 File not found: 'Quickrpt.dcuil'
在這個時候, 你還會遇到一個運行時錯誤對話框提示當Delphi 2005 VCL設計器試圖顯示CustRpt單元時無法找到對應屬性.
未完侍續