熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

Delphi組件撰寫常問問題分析

2013-11-11 21:04:48  來源: Delphi編程 
此份文件的目的為何?
  這份文件的目的是為了解答有關撰寫 Delphi組件時常見或文件上找不到的問題我曾經花了一段很長的時間來了解探索 TDataLink 類別這讓我覺得應該將撰寫組件時常遇到的問題及經驗心得寫下來分享給大家不過我並不能保證寫在這份文件裡頭的解答完全正確如果你對其中的任何問題有更好的解決方法或認為有什麼信息適合放在這份文件裡的話請告知作者有任何錯誤或缺漏也歡迎指正
  除了再加上更多的問題及解答外我試著再補充兩個部分
  進階程序設計師喜愛的工具這也許跟組件設計沒有直接的關系但至少它們跟 Delphi有關系
  值得參考的文件刊物由於空間的關系這份文件不能放置太多的范例程序因此參考其它文件是十分需要的這不是一份教材式的文件我不會做太多條理式的說明但會試著將最具有參考價值的文獻列出
  如果你有任何意見或建議歡迎來信告訴我
  
  第二部份 整合環境
   在整合環境中如何找出組件所產生的問題?
  我發現唯一能找出問題的方法只有
  在 Delphi 整合環境的 Tools|Options 對話框的 Library 頁中將『Compile with debug info』選項打勾
  選 Component|Rebuild Library 重新編譯組件庫
  從 Turbo Debugger 中執行 Delphi
  選File|Change Dir移至包含組件程序代碼的目錄下
  如果你的組件發生GPF時就可以檢視堆棧然後得知到底是哪些發生問題了
  
   如何檢視 Delphi 所產生的匯編語言碼?
  Glen Boyd 的回答
  開啟登錄編輯程序(REGEDITEXE)接著到『HKEY_CURRENT_USER\Software\Borland\Delphi\\Debugging』下新增一個字符串機碼『EnableCPU』將它的字符串值設為『此後Delphi整合環境的View選單下就會多一個『CPU』選項它會開啟一個窗口來檢視目前程序指令的內存及匯編語言你可以在偵錯時利用單步追蹤或其它方法來觀察它
  
   我可以在執行時期動態建立組件但在設計時期就會發生錯誤為什麼?
  你的組件必須繼承自TComponent類別或其衍生類別
  你的組件建構函式及滅構函式宣告必須看起來像這樣
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override ;
  所有在published區段宣告的字段型態必須是ordinalsingledoubleextended compcurrencystringsmall set(譯注指元素編號不超過這個范圍的集合平常的集合可容許的范圍為method pointer或class其中一種如果你宣告了其它型態的字段Delphi編譯器並不會檢查出錯誤然而當你使用這個組件時依然會得到一個GPF
  如果你想讓TMyComponent組件可以在設計時期操作注意下面的宣告會引發十分嚴重的問題
  type TComplex = record
  RealPart: Double;
  ComplexPart: Double;
  end;
  class TMyComponent = Class(TComponent)
  private
  F: TComplex;
  published
  property P: TComplex read F write F;
  end;
  
   如何撰寫一個無法放置到表格上的組件?
  Ray Lischner 的回答
  如果你不想讓使用者將組件拉曳至表格上的話使用 RegisterNoIcon 及 RegisterClass 程序來注冊組件
  
   在程序代碼編輯器中快速切換程序區段最簡單的方法是什麼?
  Ray Konopka 的回答
  在探索 VCL 原始程序代碼時強烈建議你最好熟悉程序代碼編輯器裡的書簽功能使用方法很簡單CtrlShiftNN 是從 的數字用來設定一個書簽此後就可以使用 CtrlN 來跳躍至書簽處(譯注使用這項功能真的可以節省你許多來回卷動程序及找尋函式的時間別遲疑了快學吧!)
  
   如何使我的組件在按下鼠標右鍵時出現快速功能選單?
  你必須要建立一個組件編輯器組件編輯器決定了組件在設計時期時對鼠標鍵的反應及動作你可以為組件定義它自己的快速功能選單
  建立組件編輯器的步驟大致如下
  從 TComponentEditor 類別繼承一個新的類別
  改寫類別的 GetVerbCountGetVerb及 ExecuteVerb方法
  在 Register 程序中使用 RegisterComponentEditor 程序來注冊此組件編輯器
  有關組件編輯器這個主題在『Developing Delphi Components』這本書中有詳盡的解說及信息
  
   為什麼組件在設計時期會出現『I/O 』的錯誤?
  你可能在組件中使用了Writeln這個程序
  
   為什麼組件編輯器不會將組件屬性的變動儲存起來?
  我發現有時自制的組件編輯器不會將組件屬性儲存起來設計時期一切正常但是儲存起來再重新讀入後就有問題了
  原因是你很可能忘了在組件編輯器中呼叫此方法
  DesignerModified;
  如此一來Delphi才會知道你的組件編輯器更改過屬性值了
  
  第三部分在組件中使用其它組件
   如何在組件中加入滾動條組件並讓它在設計時期能動作?
  你的滾動條組件類別必須處理 CM_DESIGNHITTEST 組件訊息才行
  TMyScrollBar = class (TScrollBar)
  procedure CMDesignHitTest
  (var Message: TCMDesignHitTest); message CM_DESIGNHITTEST;
  end;
  
  procedure TMyScrollBarCMDesignHitTest( var Message: TCMDesignHitTest);
  begin
  MessageResult := ;
  end;
  
  你的組件必須以以下方法建立滾動條
  TMyScrollBarCreate(nil);
  而不是
  TMyScrollBarCreate(Self);
  
   如何建立Windows式樣的滾動條?
  你必須設定滾動條的頁面大小你可以用以下的程序代碼來做
  procedure SetPageSize(ScrollBar: TScrollBar; PageSize: Integer);
  var
  ScrollInfo: TScrollInfo;
  begin
  ScrollInfocbSize := Sizeof (ScrollInfo);
  ScrollInfofMask := SIF_PAGE;
  ScrollInfonPage := PageSize;
  SetScrollInfo (ScrollBarHandle SB_CTL ScrollInfo True);
  end;
  
  要取得目前頁面大小可用如下方法
  function GetpageSize (ScrollBar: TScrollBar): Integer;
  var
  ScrollInfo: TScrollInfo;
  begin
  if HandleAllocated then
  begin
  ScrollInfocbSize := SizeOf (ScrollInfo);
  ScrollInfofMask := SIF_PAGE;
  GetScrollInfo (ScrollBarHandle SB_CTL ScrollInfo);
  Result := ScrollInfonPage;
  end;
  end;
  
  第四部分 Bound Controls
   哪裡可以找得到有關 TDataLink 類別的說明文件?
  我可以大膽地說全世界有關 TDataLink 的說明文件只有一份就在這兒
  屬性 (Property) 介紹
  property Active: Boolean(只讀)
  當此 DataLink 連結至一個已開啟的 DataSource 時會傳回 True當 Active 狀態改變時會 觸發ActiveChanged方法
  property ActiveRecord: Integer(可擦寫)
  用來設定或取得 DataLink 緩沖區中目前所指向的記錄代碼代碼的范圍是 BufferCount 使用它來設定記錄代碼時必須小心不要超過這個范圍否則可能導致不可預期的錯誤
  property BufferCount: Integer(可擦寫)
  DataLink 擁有一個資料緩沖區而 BufferCount 屬性即用來設定或取得緩沖區大小緩沖區大小決定了一個dataset同時可以顯視的資料記錄筆數對大部分的資料感知組件來說BufferCount 的值是 但對 TDataGrid 來說BufferCount 代表它的可視列數目
  property DataSet: TDataSet(只讀)
  傳回此 DataLink 所連結的 DataSet其實就是 DataSourceDataSet
  property DataSource: TDataSource(可擦寫)
  傳回此DataLink所連結的DataSource
  property DataSourceFixed: Boolean(可擦寫)
  這個屬性可用來防止 DataSource 屬性被更改如果此屬性設為 True當我們試著改變 DataSource 屬性時會引發一個例外
  property Editing: Boolean(只讀)
  如果 DataLink 正處於編輯狀態則傳回 True
  property ReadOnly: Boolean(可擦寫)
  設定 DataLink 是否為只讀狀態這個屬性並不會影響所連結的 DataSet在只讀狀態下這個 DataLink 無法進入編輯狀態
  property RecordCount: Integer(只讀)
  傳回DataSet的資料記錄數目
  方法 (Method) 介紹
  function Edit: Boolean;
  讓所連結的DataSet進入編輯狀態傳回值 成功傳回 True 失敗傳回 False
  procedure UpdateRecord;
  我們不直接呼叫這個方法它是提供其它程序來呼叫的這個方法只有設定一個旗幟然後呼叫 UpdateData 方法
  虛擬方法 ( Virtual Method )
  要讓 TDataLink 對象與組件溝通必須改寫下列這些方法
  procedure ActiveChanged
  當連結的 DataSource 開啟狀態改變時會呼叫此方法使用 Active 屬性可以得知目前是否為開啟狀態
  procedure CheckBrowseMode
  數據庫有任何改變之後都會先呼叫這個方法
  procedure DataSetChanged;
  當下列任一事件發生時都會呼叫此方法
  移至DataSet的開頭
  移至DataSet的結尾
  在DataSet中插入或新增資料
  刪除DataSet的資料
  取消DataSet的編輯
  更新記錄
  如果不想改寫這個方法只要在其中呼叫

From:http://tw.wingwit.com/Article/program/Delphi/201311/8437.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.