?? 054.htm
字號:
<p>begin</p>
<p>ReadSignature;</p>
<p>Component := ReadComponent(nil);</p>
<p>Proc(Component);</p>
<p>end;</p>
<p>FixupReferences;</font><font face="宋體" lang="ZH-CN"></p>
<p></font><font face="Arial">finally</font><font face="宋體" lang="ZH-CN"></p>
<p></font><font face="Arial">EndReferences;</p>
<p>end;</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> </font><font face="Arial">ReadComponents</font><font face="宋體" lang="ZH-CN">首先用</font><font
face="Arial">AOwner</font><font face="宋體" lang="ZH-CN">和</font><font face="Arial">AParent</font><font
face="宋體" lang="ZH-CN">參數給</font><font face="Arial">Root,Owner</font><font
face="宋體" lang="ZH-CN">和</font><font face="Arial">Parent</font><font face="宋體"
lang="ZH-CN">賦值,用于重建各部件的相互引用。然后用一個</font><font
face="Arial">While</font><font face="宋體" lang="ZH-CN">循環讀取部件并用由</font><font
face="Arial">Proc</font><font face="宋體" lang="ZH-CN">傳入的方法進行處理。在重建引用關系時,用了</font><font
face="Arial">BeginReferences</font><font face="宋體" lang="ZH-CN">、</font><font
face="Arial">FixUpReferences</font><font face="宋體" lang="ZH-CN">和</font><font
face="Arial">EndReferences</font><font face="宋體" lang="ZH-CN">嵌套模式。</p>
<p> </font><font face="Arial">ReadRootComponent</font><font face="宋體"
lang="ZH-CN">方法從</font><font face="Arial">Reader</font><font face="宋體"
lang="ZH-CN">對象的流中將部件及其擁有的部件全部讀出。如果</font><font
face="Arial">Component</font><font face="宋體" lang="ZH-CN">參數為</font><font
face="Arial">nil</font><font face="宋體" lang="ZH-CN">,則創建一個相同類型的部件,最后返回該部件:</p>
<p> </p>
<p></font><font face="Arial">function TReader.ReadRootComponent(Root: TComponent):
TComponent;</p>
<p></font> <font face="Arial"></p>
<p>function FindUniqueName(const Name: string): string;</p>
<p>begin</p>
<p></font><font face="宋體" lang="ZH-CN">…</p>
<p></font><font face="Arial">end;</p>
<p> </p>
<p>var</p>
<p>I: Integer;</p>
<p>Flags: TFilerFlags;</p>
<p>begin</p>
<p>ReadSignature;</p>
<p>Result := nil;</p>
<p>try</p>
<p>ReadPrefix(Flags, I);</p>
<p>if Root = nil then</p>
<p>begin</p>
<p>Result := TComponentClass(FindClass(ReadStr)).Create(nil);</p>
<p>Result.Name := ReadStr;</p>
<p>end else</p>
<p>begin</p>
<p>Result := Root;</p>
<p>ReadStr; { Ignore class name }</p>
<p>if csDesigning in Result.ComponentState then</p>
<p>ReadStr else</p>
<p>Result.Name := FindUniqueName(ReadStr);</p>
<p>end;</p>
<p>FRoot := Result;</p>
<p>if GlobalLoaded <> nil then</p>
<p>FLoaded := GlobalLoaded else</p>
<p>FLoaded := TList.Create;</p>
<p>try</p>
<p>FLoaded.Add(FRoot);</p>
<p>FOwner := FRoot;</p>
<p>Include(FRoot.FComponentState, csLoading);</p>
<p>Include(FRoot.FComponentState, csReading);</p>
<p>FRoot.ReadState(Self);</font><font face="宋體" lang="ZH-CN"></p>
<p></font><font face="Arial">Exclude(FRoot.FComponentState, csReading);</font><font
face="宋體" lang="ZH-CN"></p>
<p></font><font face="Arial">if GlobalLoaded = nil then</p>
<p>for I := 0 to FLoaded.Count - 1 do TComponent(FLoaded[I]).Loaded;</p>
<p>finally</p>
<p>if GlobalLoaded = nil then FLoaded.Free;</p>
<p>FLoaded := nil;</p>
<p>end;</p>
<p>GlobalFixupReferences;</p>
<p>except</p>
<p>RemoveFixupReferences(Root, '');</p>
<p>if Root = nil then Result.Free;</p>
<p>raise;</p>
<p>end;</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> </font><font face="Arial">ReadRootComponent</font><font face="宋體"
lang="ZH-CN">首先調用</font><font face="Arial">ReadSignature</font><font face="宋體"
lang="ZH-CN">讀取</font><font face="Arial">Filer</font><font face="宋體" lang="ZH-CN">對象標簽。然后在</font><font
face="Arial">try</font><font face="宋體" lang="ZH-CN">…</font><font face="Arial">except</font><font
face="宋體" lang="ZH-CN">循環中執行讀取任務。如果</font><font face="Arial">Root</font><font
face="宋體" lang="ZH-CN">參數為</font><font face="Arial">nil</font><font
face="宋體" lang="ZH-CN">,則用</font><font face="Arial">ReadStr</font><font
face="宋體" lang="ZH-CN">讀出的類名創建新部件,并以流中讀出部件的</font><font
face="Arial">Name</font><font face="宋體" lang="ZH-CN">屬性;否則,忽略類名,并判斷</font><font
face="Arial">Name</font><font face="宋體" lang="ZH-CN">屬性的唯一性。最后用</font><font
face="Arial">Root</font><font face="宋體" lang="ZH-CN">的</font><font face="Arial">ReadState</font><font
face="宋體" lang="ZH-CN">方法讀取屬性和其擁有的擁有并處理引用關系。</p>
<p> </font><font face="Arial">7. SetName</font><font face="宋體" lang="ZH-CN">方法和</font><font
face="Arial">OnSetName</font><font face="宋體" lang="ZH-CN">事件</p>
<p> 因為在</font><font face="Arial">OnSetName</font><font face="宋體"
lang="ZH-CN">事件中,</font><font face="Arial">Name</font><font face="宋體"
lang="ZH-CN">參數是</font><font face="Arial">var</font><font face="宋體" lang="ZH-CN">型的,所以可以用</font><font
face="Arial">OnSetName</font><font face="宋體" lang="ZH-CN">事件處理過程修改所讀部件的名字。而</font><font
face="Arial">OnSetName</font><font face="宋體" lang="ZH-CN">事件處理過程是在</font><font
face="Arial">SetName</font><font face="宋體" lang="ZH-CN">方法中實現的。</p>
<p> </p>
<p></font><font face="Arial">procedure TReader.SetName(Component: TComponent; var Name:
string);</p>
<p>begin</p>
<p>if Assigned(FOnSetName) then FOnSetName(Self, Component, Name);</p>
<p>Component.Name := Name;</p>
<p>end;</p>
<p></font> <font face="Arial"></p>
<p>SetName</font><font face="宋體" lang="ZH-CN">方法和</font><font face="Arial">OnSetName</font><font
face="宋體" lang="ZH-CN">事件在動態</font><font face="Arial">DFM</font><font
face="宋體" lang="ZH-CN">文件的編程中有很重要的作用。</p>
<p> </font><font face="Arial">8. TReader</font><font face="宋體" lang="ZH-CN">的錯誤處理</p>
<p> </font><font face="Arial">TReader</font><font face="宋體" lang="ZH-CN">的錯誤處理是由</font><font
face="Arial">Error</font><font face="宋體" lang="ZH-CN">方法和</font><font
face="Arial">OnError</font><font face="宋體" lang="ZH-CN">事件的配合使用完成的。</font><font
face="Arial">OnError </font><font face="宋體" lang="ZH-CN">事件處理過程的</font><font
face="Arial">Handled</font><font face="宋體" lang="ZH-CN">參數是</font><font
face="Arial">var</font><font face="宋體" lang="ZH-CN">型的布爾變量,通過將</font><font
face="Arial">Handled</font><font face="宋體" lang="ZH-CN">設為</font><font
face="Arial">True</font><font face="宋體" lang="ZH-CN">或</font><font face="Arial">False</font><font
face="宋體" lang="ZH-CN">可影響</font><font face="Arial">TReader </font><font
face="宋體" lang="ZH-CN">的錯誤處理。</font><font face="Arial">OnError</font><font
face="宋體" lang="ZH-CN">事件處理過程是在</font><font face="Arial">Error</font><font
face="宋體" lang="ZH-CN">方法中調用的。</p>
<p> </p>
<p></font><font face="Arial">function TReader.Error(const Message: string): Boolean;</p>
<p>begin</p>
<p>Result := False;</p>
<p>if Assigned(FOnError) then FOnError(Self, Message, Result);</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> </font><font face="Arial">9. FindMethod</font><font face="宋體" lang="ZH-CN">和</font><font
face="Arial">OnFindMethod</font><font face="宋體" lang="ZH-CN">事件</p>
<p> 有時,在程序運行期間,給部件的方法指針</font><font
face="Arial">(</font><font face="宋體" lang="ZH-CN">主要是事件處理過程</font><font
face="Arial">)</font><font face="宋體" lang="ZH-CN">動態賦值是很有用的,這樣就能動態地改變部件響應事件的方式。在流中讀取部件捍做到一點就要利用</font><font
face="Arial">OnFindMehtod</font><font face="宋體" lang="ZH-CN">事件。</font><font
face="Arial">OnFIndMethod</font><font face="宋體" lang="ZH-CN">事件是在</font><font
face="Arial">FindMethod</font><font face="宋體" lang="ZH-CN">方法中被調用的。</p>
<p> </p>
<p></font><font face="Arial">function TReader.FindMethod(Root: TComponent;</p>
<p>const MethodName: string): Pointer;</p>
<p>var </p>
<p>Error: Boolean;</p>
<p>begin</p>
<p>Result := Root.MethodAddress(MethodName);</p>
<p>Error := Result = nil;</font><font face="宋體" lang="ZH-CN"></p>
<p></font><font face="Arial">if Assigned(FOnFindMethod) then FOnFindMethod(Self,
MethodName, Result, </p>
<p>Error);</p>
<p>if Error then PropValueError;</p>
<p>end;</p>
<p></font> <font face="宋體" lang="ZH-CN"></p>
<p> </font><font face="Arial">OnFindMethod </font><font face="宋體" lang="ZH-CN">方法除了可以給部件的</font><font
face="Arial">MethodName</font><font face="宋體" lang="ZH-CN">所指定的方法指針動態賦值外,還可修改</font><font
face="Arial">Error</font><font face="宋體" lang="ZH-CN">參數來決定是否處理</font><font
face="Arial">Missing Method</font><font face="宋體" lang="ZH-CN">錯誤。方法中調用的</font><font
face="Arial">MehtodAddress </font><font face="宋體" lang="ZH-CN">方法定義在</font><font
face="Arial">TObject</font><font face="宋體" lang="ZH-CN">中,它是個很有用的方法,它可以得到對象中定義的</font><font
face="Arial">public</font><font face="宋體" lang="ZH-CN">方法的地址。</font><font
face="Arial">FindMethod</font><font face="宋體" lang="ZH-CN">方法和</font><font
face="Arial">OnFindMethod</font><font face="宋體" lang="ZH-CN">事件在動態</font><font
face="Arial">DFM</font><font face="宋體" lang="ZH-CN">的編程中有很重要的作用。</p>
<p> </p>
<p> </font><font face="Arial"></p>
<p>20.3 Delphi</font><font face="宋體" lang="ZH-CN">對象式數據管理應用實例</p>
<p> </p>
<p> </font><font face="Arial">Delphi 2.0</font><font face="宋體" lang="ZH-CN">無論是其可視化設計工具,還是可視化部件類庫</font><font
face="Arial">(VCL)</font><font face="宋體" lang="ZH-CN">,都處處滲透了對象存儲技術,本節將從</font><font
face="Arial">Delphi</font><font face="宋體" lang="ZH-CN">可視化設計內部機制、</font><font
face="Arial">VCL</font><font face="宋體" lang="ZH-CN">中的數據存儲、</font><font
face="Arial">BLOB</font><font face="宋體" lang="ZH-CN">數據操作和動態生成部件的存儲幾方面介紹對象存儲功能的實例應用。</p>
<p> </font><font face="Arial"></p>
<p>20.3.1 Delphi </font><font face="宋體" lang="ZH-CN">動態</font><font face="Arial">DFM</font><font
face="宋體" lang="ZH-CN">文件及部件的存取在超媒體系統中的應用</p>
<p> </p>
<p> </font><font face="Arial">Delphi</font><font face="宋體" lang="ZH-CN">的可視化設計工具是同其部件類庫緊密結合在一起的。</p>
<p> 每個部件只有通過一段注冊程序并通過</font><font face="Arial">Delphi</font><font
face="宋體" lang="ZH-CN">的</font><font face="Arial">Install Component</font><font
face="宋體" lang="ZH-CN">功能,才能出現在</font><font face="Arial">Component
Palette</font><font face="宋體" lang="ZH-CN">上;部件的屬性才有可能出現在</font><font
face="Arial">Object Inspector</font><font face="宋體" lang="ZH-CN">窗口中;部件的屬性編輯器才能被</font><font
face="Arial">Delphi</font><font face="宋體" lang="ZH-CN">環境使用。因為這種渾然天成的關系,</font><font
face="Arial">DFM</font><font face="宋體" lang="ZH-CN">文件存取必然得到</font><font
face="Arial">VCL</font><font face="宋體" lang="ZH-CN">在程序上的支持。</p>
<p> </font><font face="Arial">DFM</font><font face="宋體" lang="ZH-CN">文件的部件存取是</font><font
face="Arial">Delphi</font><font face="宋體" lang="ZH-CN">可視化設計環境中文件存取的中心問題。因為</font><font
face="Arial">Delphi</font><font face="宋體" lang="ZH-CN">可視化
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -