Since learning Delphi in 1999, I have been fascinated by its rapid development. At that time, I had just come into contact with programming and I was particularly interested in visual development. The reason is that it can be implemented faster than C. In the past few years, from From delphi C/S to three-layer B/S, I have also written some software, large and small. , I think this Delphi only has these functions. Since I recently got a book "Com Essence" and studied the VCL source code, I found that it is really powerful (I don't know what words to use to describe it). Recently, it has some Breakthroughs are shared here with everyone. Please tell me if there are any mistakes.
To put it bluntly, components only include two types of members: properties and methods (the methods I am talking about include events)
It is divided into four parts:
PRivate
protected
public
published
The meanings of the above four parts will be introduced in general visual development books. Here is only a brief overview relative to Delphi.
Private: All private members are placed here and can only be accessed by the class's own methods, not by subclasses, and are transparent to subclasses. It can also be said that it can only be accessed by the methods of the unit itself.
protected: except that it can be inherited by subclasses, the rest is the same as private. Cannot be accessed by outsiders.
public: Public, the properties and methods declared here can be called by users.
published: appears in the property bar of the Delphi development environment.
First, let's make the simplest control. In less than five minutes, you will understand how the components on Delphi's component panel are made.
New->New->Component and press Enter.
Then select the parent class you want to inherit from in Ancestor type:. Here we choose TComponent. It means inheriting all properties and methods of TComponent.
Class Name: Enter the class name of the component to be made. (We enter TShowText)
Palette Page: Which panel in Delphi the component will be installed on. (We choose Samples, you can also enter a new name)
I don’t need to say the following.
Click the OK button, and Delphi automatically generates a basic control inherited from TComponent. It can also be understood that we have developed a control that is as powerful as TComponent, but this is not what we need. Let's continue.
The following explains the reading and writing methods of the private variables of the component itself:
For example, we wrote the following short paragraph:
private
FText: String;
....
/*Private variables are not allowed to be used by the outside world, so how can we operate this FText string variable? */
We also need to add this paragraph after Published:
property Text: String read FText write FText;
What this means here is that this Text property will appear in the property bar of delphiSDK. Users who modify the Text in the property bar are actually modifying the FText string variable. read means that the user reads the Text attribute and actually reads FText. Write, of course, means that the user assigns a value to Text and stores it in the FText string variable.
If you save it at this time and install it in Delphi, then our most basic component will be finished. (The method of installing components is introduced at the end)
Haha, isn’t it very simple? It's just that our component doesn't have any specific use.
We just introduced attributes here, now we will continue to add functions to introduce the use of methods.
We add the following after Public:
procedure ShowText();
Then press Ctrl + Alt +C, the system automatically adds the implementation code of some methods for you.
Next we are writing:
procedure TShowText.ShowText();
begin
ShowMessage(FText);
end;
As you can see, the ShowMessage above displays the value of the private variable of the class. By now you should understand that private variables can only be accessed in the method of the class itself. Here you must add the Dialogs unit after uses, because ShowMessage is included in the Dialogs unit, otherwise it will not pass.
Of course, the above events can only be used in the control and cannot appear in the event bar in the property box. Why? Because the method declared here is only Public, a pure method, and is not declared as an event.
Through the above study, do you already know how to write and adjust the properties and methods of controls?
However, a real control is inseparable from events, and the invocation of events must be driven by messages, which will be introduced in my next article.
The properties and methods of a powerful control are not so easy. It requires more practice and more applications.
Attached below is a DBGridToExcel control I wrote, whose function is to export data in the DBGrid to Excel. You can learn from it and use it as a reference. This control includes the use of properties, methods and "events" that we will talk about in the next article.
Appendix 1: How to install self-made controls:
(1). In the Component menu, select "Install Component...".
(2). Click "..." after Unit File name, select the unit file of the "*.pas" control, and then click OK. Click "install" in the window that appears, and the installation is complete.
The newly installed control appears in your panel.
Attachment 2: Copy the entire source code of the TDBGridToExcel control to Notepad and save it as a .pas file.
unit DBGridToExcel;
{************************************************ ************************}
{* *}
{* Export Grid To Word VCL Control for D5 & D6 *}
{* Copyright(C) xiangding 2003.10.1 All rights reserved *}
{* Bug Report: [email protected] *}
{* Author: Little Bear*}
{* *}
{************************************************ ************************}
{* *}
{* 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] *}
{* *}
{************************************************ ************************}
{* *}
{* Install: *}
{* Save the attachment, and then open the GridToExcel.Pas file with Delphi, *}
{* Select Delphi menu-->Component-->Install Component, *}
{* Then select Install. After installation, on the Samples page of the control panel, *}
{* After you are familiar with it, you can try to set some complex attributes and explore the others by yourself, *}
{************************************************ ************************}
interface
uses
Windows, StdCtrls, ComCtrls, Messages, DBGrids, Graphics, ExtCtrls,
Forms, DB, ComObj, Controls, SysUtils, Classes;
ResourceString
SPromptExport = 'Please wait, data is being exported...';
SConnectExcel = 'Starting Excel, please wait...';
SConnectExcelError= 'Failed to connect to Excel. Excel may not be installed and cannot be exported.';
SCancel = '&Cancel';
SError = 'error';
SConfirm = 'Do you really want to terminate the export of data? ';
SCaption = 'Confirm';
SGridError = 'No data set specified, please specify the data set control! ';
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 AfterScroll 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 occurs }
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.