淺談控制元件(元件)製作方法一(附帶一delphi匯出資料到Excel的元件例項)(原創) (轉)
從99年學習開始,我就被它的開發迷上了,那時候剛接觸,對視覺化開發特別來勁,原因嘛,不外乎是比C更快的實現啦,這幾年來,從delphi的C/S到三層B/S,大大小小也寫過一些,自認為這delphi也就這麼些功能吧,自從最近偶得一本Com本質論,研究了一下VCL原始碼,才發現它真的神通廣大(我也不知道用什麼詞來形容),最近有些許突破,就在此於大家分享,有不對之處還請指點一二。
說白了,只包括二類成員: 屬性和方法(我所說的方法包括了事件)
分屬於四個部分:
private
protected
public
published
上面四部分的意思在一般的視覺化開發書籍當中都會有介紹,這裡只相對於delphi作簡單概述。
private: 所有私有的成員都放在這裡,只能被類自身的方法所訪問,而不能被子類訪問,對子類透明。也可說只能被單元本身的方法訪問。
protected:除了可以被子類繼承外,其餘和private一樣。不能被外界訪問。
public: 公有的,在此間宣告的屬性和方法能被。
published: 出現在delphi開發環境屬性欄中。
首先我們來做一個最簡單的,不到五分鐘,你就會明白delphi的元件皮膚上的元件是如何製作的了。
新建->New->Component 回車。
然後在Ancestor type:中選擇你要繼承的父類,這裡我們選TComponent.表示繼承TComponent的所有屬性和方法。
Class Name:中輸入將要製作的元件的類名。(我們輸入TShowText)
Palette Page:元件將要到delphi的哪個皮膚上。(我們選擇Samples,你也可以輸入一個新的名字)
下面的就不用我說了吧。
點選OK按鈕,delphi自動生成了一個基本的繼承自TComponent的控制元件了,也可以這樣理解,我們已經開發了一個與TComponent功能一樣強大的控制元件,不過這不是我們需要的,下面我們繼續。
下面說明一下元件本身私有變數的讀寫方法:
比如我們寫了下面一小段:
private
FText : String;
....
/*私有變數不是允許被外界使用的,那麼要如何才能對這個FText字串變數進行操作呢?*/
我們還要在Published後面新增這麼一段:
property Text: String read FText write FText;
這裡的意思就是指,這個Text屬性會出現在delphiSDK的屬性欄中,使用者修改屬性欄中的Text實際上都是在修改FText這個字串變數。read表示使用者讀取Text屬性實際上讀取FText,write當然就表示使用者為Text賦值則存在FText字串變數中啦。
如果在這時候儲存,並在delphi中安裝.那麼我們這個最基本的元件就製作完了。(安裝元件方法在最後有介紹)
哈哈,是不是很簡單呢?只不過我們的這個元件沒有實現什麼具體用處罷了。
剛才這裡我們介紹了屬性,下面我們繼續增加功能,來介紹一下方法的使用。
我們在Public後面新增如下:
procedure ShowText();
然後按Ctrl + Alt +C,自動為你新增了些方法的實現程式碼。
接下來我們在寫:
procedure TShowText.ShowText();
begin
ShowMessage(FText);
end;
看到了,上面的ShowMessage顯示的就是類私有變數的值,到這裡大家應該明白了,只有在類本事的方法才能訪問私有的變數。這裡必須在uses 後面加上Dialogs單元,因為ShowMessage包含在Dialogs單元中,否則通不過。
當然,上面的事件只能在控制元件中使用,去不能在屬性框中的事件欄中出現,為什麼呢?因為這裡聲名的方法只是Public的,純方法而已,並沒有宣告為事件。
透過上面的學習,大家是不是已經知道控制元件的屬性和方法是如何寫的和調了的了呢?
不過,一個真正意義上的控制元件是離不開事件的,而事件的呼叫必須透過訊息來,這將在我的下一篇中介紹。
一個功能強大的控制元件的屬性和方法也不是這麼容易的,還需要大家多實踐,多應用。
下面附帶了我寫的一個GridTo控制元件,功能是把DBGrid中的資料匯出到Excel中。大家可以學習一下,做為參考。為個控制元件中包括了使用屬性,方法和我們將在下一篇中講到的“事件”。
附1: 安裝自制控制元件的方法:
(1).在Component選單中,選擇"Install Component...".
(2).在Unit File name 後面單擊“...",選擇"*.pas"控制元件的單元,再點選OK。在出現的視窗中單擊"install",即安裝完畢。
新裝的控制元件即出現在你的皮膚中。
附2: TDBGridToExcel控制元件的全部原始碼,把它複製到記事本中,存為.pas檔案即可。
unit DBGridToExcel;
{***********************************************************************}
{* *}
{* Export Grid To VCL Control for D5 & D6 *}
{* Copyright(C) xiangding .10.1 All rights reserved *}
{* Report: to:boyxd@163">boyxd@163.net *}
{* Author : 小熊 *}
{* *}
{***********************************************************************}
{* *}
{* This is a Simple Version *}
{* *}
{***********************************************************************}
{* *}
{* Install: *}
{* Please Save as file GridToExcel.pas then open the file *}
{* Click the menu item [Component] --> [Install Component] *}
{* Click [Install] button in the Install Component dialog *}
{* after install ,you can find the control at component *}
{* page [sample] *}
{* *}
{***********************************************************************}
{* *}
{* 安裝: *}
{* 把附件儲存,然後用Delphi開啟這個GridToExcel.Pas檔案, *}
{* 選擇Delphi選單--〉Component-->Install Component, *}
{* 然後選擇Install即可。安裝之後,在控制元件皮膚的Samples頁面上面, *}
{* 熟悉之後,你可以試著設定一些複雜的屬性,其他的自己摸索吧, *}
{***********************************************************************}
interface
uses
, StdCtrls, ComCtrls, Messages, DBGrids, Graphics, ExtCtrls,
Forms, DB, ComObj, Controls, SysUtils, Classes;
ReString
SPromptExport = '請等待,正在匯出資料……';
nnectExcel = '正在啟動Excel,請稍候……';
SConnectExcelError= '連線Excel失敗,可能沒有安裝Excel,無法匯出.';
SCancel = '取消(&C)';
SError = '錯誤';
SConfirm = '真的要終止資料的匯出嗎?';
SCaption = '確認';
SGrrror = '沒有指定資料集,請指定資料集控制元件!';
type
TDBGridToExcel = class(TComponent)
private
Progresorm: TForm;
FShowProgress: Boolean;
ExcelApp : Variant;
FTitle: String;
Quit: Boolean;
FOnProgress: TNotifyEvent;
FGrid: TDBGrid; {The Source Grid}
ProgressBar: TProgressBar;
Prompt: TLabel;
FAutoExit: Boolean;
FAutoSize: Boolean;
FDBGrid: TDBGrid;
procedure SetShowProgress(const Value: Boolean);
procedure CreateProgressForm;
procedure ButtonClick(Sender: T);
Function ConnectToExcel: Boolean;
procedure ExportDBGrid;
{ Private declarations }
protected
{ Protected declarations }
public
Constructor Create(AOwner: TComponent); override;
Destructor Destroy(); override;
Procedure ExportToExcel; {Export Grid To Excel}
{ Public declarations }
published
{ Published declarations }
property DBGrid: TDBGrid read FDBGrid write FDBGrid;
property Title: String read FTitle write FTitle;
property ShowProgress: Boolean read FShowProgress write SetShowProgress;
property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TDBGridToExcel]);
end;
{ TDBGridToExcel }
procedure TDBGridToExcel.ButtonClick(Sender: TObject);
begin
Quit := MessageBox(ProgressForm.Handle, pchar(SConfirm), pchar(SCaption),
MB_OKCANCEL + MB_ICONINFORMATION) = IDOK;
end;
function TDBGridToExcel.ConnectToExcel: Boolean;
begin
Result := true;
Try
ExcelApp := CreateOleObject('Excel.Application');
ExcelApp.Visible := False;
if Title<>'' then ExcelApp.Caption := Title;
ExcelApp.WorkBooks.Add;
except
MessageBox(GetActiveWindow,PChar(SConnectExcelError),PChar(SError),Mb_OK+MB_IconError);
result := false;
end;
end;
constructor TDBGridToExcel.Create(AOwner: TComponent);
begin
inherited;
FShowProgress := True; {Default value was Show the Progress}
FAutoExit := False;
FAutoSize := True;
end;
procedure TDBGridToExcel.CreateProgressForm;
var
Panel : TPanel;
Button : TButton;
begin
if Assigned(ProgressForm) then exit; {Aready Create?}
ProgressFo:= TForm.Create(Owner);
With ProgressForm do
begin
Font.Name := '宋體';
Font.Size := 10;
BorderStyle := bsNone;
Width := 280;
Height := 120;
BorderWidth := 1;
Color := clBackground;
Position := poOwnerFormCenter;
end;
Panel := TPanel.Create(ProgressForm);
with Panel do { Create Panel }
begin
Parent := ProgressForm;
Align := alClient;
BevelInner := bvNone;
BevelOuter := bvRaised;
Caption := '';
end;
Prompt := TLabel.Create(Panel);
with Prompt do { Create Label }
begin
Parent := Panel;
Left := 20;
Top := 25;
Caption := SConnectExcel;
end;
ProgressBar := TProgressBar.Create(panel);
with ProgressBar do { Create ProgressBar }
begin
Step := 1;
Parent := Panel;
Smooth := true;
Left := 20;
Top := 50;
Height := 18;
Width := 260;
end;
Button := TButton.Create(Panel);
with Button do { Create Cancel Button }
begin
Parent := Panel;
Left := 115;
Top := 80;
Caption := SCancel;
OnClick := ButtonClick;
end;
ProgressForm.Show;
ProgressForm.Update;
end;
destructor TDBGridToExcel.Destroy;
begin
inherited;
end;
procedure TDBGridToExcel.ExportDBGrid;
var
Data : TDataSet;
ADBGrid: TDBGrid;
i, j : integer;
CurrentPoint : Pointer;
OldBeforeScroll, OldAfterScroll: TDataSetNotifyEvent;
begin
Screen.Cursor := crHourGlass;
try
try
TForm(Owner).Enabled := False;
ExcelApp.DisplayAlerts := false;
ExcelApp.ScreenUpdating := false;
Quit := false;
if ShowProgress then Prompt.Caption := SPromptExport;
ADBGrid := DBGrid;
Data := ADBGrid.DataSource.DataSet;
with ADBGrid do { Insert Table Header }
for i := 1 to Columns.Count do
if Columns[i - 1].Visible then
ExcelApp.Cells[1,i].Value :=Columns[i - 1].Title.Caption;
CurrentPoint := Data.GetBookmark; {Save Current Position}
OldBeforeScroll := Data.BeforeScroll; { Save Old Before Scroll Event handle }
OldAfterScroll := Data.AfterScroll; { Save Old After Scroll Event Handle }
Data.DisableControls; { Disable Control }
Data.BeforeScroll := nil;
Data.AfterScroll := nil;
if ShowProgress then ProgressBar.Max := Data.RecordCount;
i := 2;
Data.First;
while not Data.Eof do { Process All record }
begin
with ADBGrid do { Process one record }
for j := 1 to Columns.Count do
if Columns[j - 1].Visible then
ExcelApp.Cells[i,j].Value := Columns[j - 1].Field.DisplayText;
Inc(i);
Data.Next;
if Assigned(FOnProgress) then FOnProgress(Self);
if ShowProgress then { Update Progress UI }
begin
ProgressBar.StepIt;
Application.ProcessMessages;
if Quit then exit;
end;
end;
except
MessageBox(GetActiveWindow,PChar(SConnectExcelError),Pchar(SError),MB_OK+MB_ICONERROR);
end;
ExcelApp.Visible := False;
TForm(Owner).Enabled := True;
Screen.Cursor := crDefault;
if ShowProgress then FreeAndNil(ProgressForm); { Free Progress Form }
ExcelApp.DisplayAlerts := True;
ExcelApp.ScreenUpdating := True;
finally
Data.BeforeScroll := OldBeforeScroll; { Restore Old Event Handle }
Data.AfterScroll := OldAfterScroll;
Data.GotoBookmark(CurrentPoint);
Data.FreeBookmark(CurrentPoint);
Data.EnableControls;
Screen.Cursor := crDefault;
end;
end;
procedure TDBGridToExcel.ExportToExcel;
begin
if DBGrid= nil then raise Exception.Create(SGridError); {No DataSource, then Error}
if ShowProgress then CreateProgressForm; {Whether or not Show the ProgressForm}
if not ConnectToExcel then { Exit when error occer }
begin
if ShowProgress then FreeAndNil(ProgressForm); {release form}
exit;
end;
ExportDBGrid; {begin Export Data}
end;
procedure TDBGridToExcel.SetShowProgress(const Value: Boolean);
begin
FShowProgress := Value;
end;
end.
以上為作者寫的一個小控制元件,有興趣的朋友可以來信一起學習。
作者:
下一篇將主要講術元件事件的寫法和技巧。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-963122/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 改良控制元件-Delphi自帶控制元件Bug的消除 (轉)控制元件
- 使用DevExpress匯出GridControl控制元件資料到excel檔案devExpress控制元件Excel
- 對Delphi控制元件的一點改良 (轉)控制元件
- 對Delphi控制元件的一點改良(二) (轉)控制元件
- delphi 控制元件的拿來主義(一) (轉)控制元件
- 對Delphi控制元件的一點改良(三) (轉)控制元件
- 用delphi製作無介面的activex控制元件控制元件
- 在Delphi中編寫控制元件的基本方法 (轉)控制元件
- Delphi釋出ActiveX控制元件 製作CAB包 數字簽名相關控制元件
- 在Delphi中編寫控制元件的基本方法(1) (轉)控制元件
- 原來的控制元件delphi7裡何處尋? (轉)控制元件
- C#快速匯出百萬級資料到Excel方法C#Excel
- [C#] (原創)一步一步教你自定義控制元件——05,Label(原生控制元件)C#控制元件
- 一個delphi控制元件的破解 (12千字)控制元件
- Delphi的元件讀寫機制(一) (轉)元件
- PHP匯出大量資料到excel表格PHPExcel
- 在Delphi中使用IP控制元件 (轉)控制元件
- 在delphi中使用flash控制元件 (轉)控制元件
- 分享:一個基於NPOI的excel匯入匯出元件(強型別)Excel元件型別
- WPF閃爍預警動畫的控制元件製作及winform呼叫WPF控制元件的方法動畫控制元件ORM
- 【原創】淺談指標(一)指標
- Delphi製作帶圖示的彈出式選單 (轉)
- 相當於delphi的日曆控制元件 (轉)控制元件
- Delphi控制元件的拿來主義(二) (轉)控制元件
- Delphi控制元件的拿來主義(三) (轉)控制元件
- poi--excel --匯出例項Excel
- DELPHI 使用dbexpress控制元件連線MySQL資料庫方法Express控制元件MySql資料庫
- Vue匯出資料到Excel電子表格VueExcel
- 【Mysql】匯出資料到excel檔案中MySqlExcel
- 元件技術的本質COM例項分析一 (轉)元件
- Delphi Open Tools Api例項研究(一) (轉)API
- Data-Browse型Data-Aware控制元件的製作 (轉)控制元件
- mac下dashboard小控制元件開發例項(附原始碼)Mac控制元件原始碼
- 使用 dataview 元件製作一覽表View元件
- CS系統中分頁控制元件的製作控制元件
- delphi 控制元件 LssCalendar V2.0 (支援農曆的月曆控制元件)控制元件
- 基本控制元件(一)控制元件
- C#自定義控制元件製作篇C#控制元件