浅谈控件(组件)制作方法一(附带一delphi导出数据到Excel的组件实例)(原创)
来自:http://blog.csdn.net/zhdwjie/article/details/1490741
-------------------------------------------------------------------
从99年学习delphi开始,我就被它的快速开发迷上了,那时候刚接触编程,对可视化开发特别来劲,原因嘛,不外乎是比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的,纯方法而已,并没有声明为事件。
通过上面的学习,大家是不是已经知道控件的属性和方法是如何写的和调了的了呢?
不过,一个真正意义上的控件是离不开事件的,而事件的调用必须通过消息来驱动,这将在我的下一篇中介绍。
一个功能强大的控件的属性和方法也不是这么容易的,还需要大家多实践,多应用。
下面附带了我写的一个DBGridToExcel控件,功能是把DBGrid中的数据导出到Excel中。大家可以学习一下,做为参考。为个控件中包括了使用属性,方法和我们将在下一篇中讲到的“事件”。
附1: 安装自制控件的方法:
(1).在Component菜单中,选择"Install Component...".
(2).在Unit File name 后面单击“...",选择"*.pas"控件的单元文件,再点击OK。在出现的窗口中单击"install",即安装完毕。
新装的控件即出现在你的面板中。
附2: TDBGridToExcel控件的全部源码,把它拷贝到记事本中,存为.pas文件即可。
unit DBGridToExcel;
{***********************************************************************}
{* *}
{* Export Grid To Word VCL Control for D5 & D6 *}
{* Copyright(C) xiangding 2003.10.1 All rights reserved *}
{* Bug Report: 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
Windows, StdCtrls, ComCtrls, Messages, DBGrids, Graphics, ExtCtrls,
Forms, DB, ComObj, Controls, SysUtils, Classes;
ResourceString
SPromptExport = '请等待,正在导出数据……';
SConnectExcel = '正在启动Excel,请稍候……';
SConnectExcelError= '连接Excel失败,可能没有安装Excel,无法导出.';
SCancel = '取消(&C)';
SError = '错误';
SConfirm = '真的要终止数据的导出吗?';
SCaption = '确认';
SGridError = '没有指定数据集,请指定数据集控件!';
type
TDBGridToExcel = class(TComponent)
private
ProgressForm: 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: TObject);
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?}
ProgressForm := 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.
以上为作者写的一个小控件,有兴趣的朋友可以来信一起学习。
作者Email: boyxd@163.net
浅谈控件(组件)制作方法一(附带一delphi导出数据到Excel的组件实例)(原创)的更多相关文章
- Delphi 导出数据至Excel的7种方法【转】
一; delphi 快速导出excel uses ComObj,clipbrd; function ToExcel(sfilename:string; ADOQuery:TADOQuery): ...
- Delphi 导出数据至Excel的7种方法
一; delphi 快速导出excel uses ComObj,clipbrd; function ToExcel(sfilename:string; ADOQuery:TADOQuery):bool ...
- django django中的HTML控件及参数传递方法 以及 HTML form 里的数据是怎么被包成http request 的?如何在浏览器里查看到这些数据?
https://www.jb51.net/article/136738.htm django中的HTML控件及参数传递方法 下面小编就为大家分享一篇django中的HTML控件及参数传递方法,具有很好 ...
- silverlight visifire控件图表制作——silverlight 后台方法页面事件
1.返回事件 (1.返回silverlight页面,2.返回web页面) private void button_ClickBack(object sender, RoutedEventArgs e) ...
- silverlight visifire控件图表制作——silverlight 后台方法ControlChart.xaml.cs
一.构造方法ControlChart 1.前台页面控件赋值 //时间下拉框赋值,下拉框赋选定值 for (int ii = DateTime.Today.Year; ii ...
- [Swift通天遁地]二、表格表单-(4)使用系统自带的下拉刷新控件,制作表格的下拉刷新效果
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- winform利用ImageList控件和ListView控件组合制作图片文件浏览器
winform利用ImageList控件和ListView控件组合制作图片文件浏览器,见图,比较简单,实现LISTVIEW显示文件夹图片功能. 1.选择文件夹功能代码: folderBrowserDi ...
- [原创]浅谈H5页面性能优化方法
[原创]浅谈H5页面性能优化方法 前阶段公司H5页面性能测试,其中测试时也发现了一些性能瓶颈问题,接下来我们在来谈谈H5页面性能优化,仅仅是一些常用H5页面性能优化措施,其实和Web页面性能优化思路大 ...
- monkeyrunner之坐标或控件ID获取方法(六)
Monkeyrunner的环境已经搭建完成,现在对Monkeyrunner做一个简介. Monkeyrunner工具提供了一套API让用户/测试人员来调用,调用这些api可以控制一个Android设备 ...
随机推荐
- DFS:POJ1190-生日蛋糕(基础搜索)
生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K 描述 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. ...
- 图学java基础篇之并发
概述 并发处理本身就是编程开发重点之一,同时内容也很繁杂,从底层指令处理到上层应用开发都要涉及,也是最容易出问题的地方.这块知识也是评价一个开发人员水平的重要指标,本人自认为现在也只是学其皮毛,因此本 ...
- B树、B-树、B+树、B*树之间的关系
https://blog.csdn.net/u013411246/article/details/81088914
- pycharm中某些方法被标黄的原因及解决办法
在编辑python文件时,会遇到上图所示,函数方法被标黄的问题,但是不影响使用. 引起原因:,如果不报错说明,这是因为你配置的python解释器中有该方法,但是pycharm没有找到这个方法,即加载失 ...
- day02_05.除数与被除数
第5题 除数与被除数 编程需要一定数学能力,在这看看你找到了几个有用条件, 又该如何来运用他们呢? 学习是互通的 题目:两个自然数相除,商3余10,被除数,除数,商,余数的和是163,求被除数,除数. ...
- Halcon18 Mac os 下载
Halcon18 Mac os 下载地址:http://www.211xun.com/download_page_15.html HALCON 18 是一套机器视觉图像处理库,由一千多个算子以及底层的 ...
- caffe-dnnh实验
下面是我在做基于深度哈希的大规模图像检索中的一个实验,相关文档介绍给大家,具体内容查看提供的相关链接,总结的很到位了,我就不再赘述. 实践cvpr2015年的深度哈希图像检索论文:Simultaneo ...
- PHP中create_function的用法总结
在php中,函数create_function主要用来创建匿名函数,有时候匿名函数可以发挥它的作用. 1.测试一 测试一主要用来循环替换数组中多个值的<与>,我们用array_map加上c ...
- 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树
题目描述 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x<2^31) ...
- 亚瑟王(arthur)
亚瑟王(arthur) 题目描述 小K不慎被LL邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑.他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚瑟王是一个 ...