Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Создать компонент любого класса

Delphi , Компоненты и Классы , Классы

Создать компонент любого класса



unit InfoForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  StdCtrls, ExtCtrls, Buttons, Clipbrd, Comctrls, Db, Dbcgrids,
  Dbctrls, Dbgrids, Dblookup, Dbtables, Ddeman, Dialogs,
  Filectrl, Grids, Mask, Menus, Mplayer, Oleconst, Olectnrs,
  Olectrls, Outline, Tabnotbk, Tabs, ExtDlgs, CheckLst, ToolWin;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    ComboBox1: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    ComboBox2: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    function GetNextName (MyClass: TComponentClass): string;
    procedure UpdateList;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

type
  TClassArray = array [1..133] of TPersistentClass;
// definition temporary used to check the data types
// TClassArray = array [1..133] of TComponentClass;
const
  ClassArray: TClassArray = (
TApplication,
TBatchMove,
TColorDialog,
TFindDialog,
TReplaceDialog,
TFontDialog,
TOpenDialog ,
TOpenPictureDialog,
TSavePictureDialog,
TSaveDialog,
TPrintDialog,
TPrinterSetupDialog,
TBevel,
TCustomLabel,
TDBText,
TLabel,
TImage,
TPaintBox,
TShape,
TSpeedButton,
TSplitter,
TToolButton,
TAnimate,
TButton,
TBitBtn,
TCheckBox,
TDBCheckBox,
TRadioButton,
TComboBox,
TDBComboBox,
TDriveComboBox,
TFilterComboBox,
TCustomDBGrid,
TDBGrid,
TDBLookupList,
TPopupGrid,
TOutline,
TDrawGrid,
TStringGrid,
TDBRadioGroup,
TRadioGroup,
TGroupBox,
TDBNavigator,
TPanel,
TDBImage,
TDBLookupControl,
TDBLookupComboBox,
TDBLookupListBox,
TPopupDataList,
THeader,
THintWindow,
TMediaPlayer,
TNotebook,
TOleContainer,
TPage,
TScroller,
TTabSet,
TDBEdit,
TInplaceEdit,
TMaskEdit,
TCustomRichEdit,
TDBRichEdit,
TRichEdit,
TDBMemo,
TMemo,
TDBLookupCombo,
TEdit,
THotKey,
TCheckListBox,
TDBListBox,
TDirectoryListBox,
TFileListBox,
TListBox,
TListView,
TStaticText,
TPageControl,
TTabbedNotebook,
TTabControl,
TTreeView,
TUpDown,
TDateTimePicker,
TDBCtrlGrid,
TDBCtrlPanel,
THeaderControl,
TOleControl,
TProgressBar,
TScrollBar,
TScrollBox,
TStatusBar,
TTabPage,
TTabSheet,
TToolWindow,
TCoolBar,
TToolBar,
TTrackBar,
TImageList,
TDatabase,
TDataModule,
TQuery,
TStoredProc,
TTable,
TUpdateSQL,
TDataSource,
TDdeClientConv,
TDdeClientItem,
TDdeMgr,
TDdeServerConv,
TDdeServerItem,
TBinaryField,
TBytesField,
TVarBytesField,
TBlobField,
TGraphicField,
TMemoField,
TBooleanField,
TDateTimeField,
TDateField,
TTimeField,
TNumericField,
TBCDField,
TFloatField,
TCurrencyField,
TIntegerField,
TAutoIncField,
TSmallintField,
TWordField,
TStringField,
TMainMenu,
TPopupMenu,
TMenuItem,
TScreen,
TSession,
TTimer
);

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  // register all of the classes
  RegisterClasses (ClassArray);
  // copy class names to the listbox
  for I := Low (ClassArray) to High (ClassArray) do
    ComboBox1.Items.Add (ClassArray [I].ClassName);
  UpdateList;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  MyClass: TComponentClass;
  MyComp: TComponent;
begin
  MyClass := TComponentClass (GetClass (ComboBox1.Text));
  if MyClass = nil then
    Beep
  else
  begin
    MyComp := MyClass.Create (self);
    MyComp.Name := GetNextName (MyClass);
    if MyClass.InheritsFrom (TControl) then
    // if MyComp is TControl then  // alternative version
    begin
      TControl (MyComp).Left := X;
      TControl (MyComp).Top := Y;
      TControl (MyComp).Parent := self;
    end;
  end;
  UpdateList;
end;

function TForm1.GetNextName (MyClass: TComponentClass): string;
var
  I, nTot: Integer;
begin
  nTot := 0;
  for I := 0 to ComponentCount - 1 do
    if Components [I].ClassType = MyClass then
      Inc (nTot);
  Result := Copy (MyClass.ClassName, 2, Length (MyClass.ClassName) - 1) +
    IntToStr (nTot);
end;

procedure TForm1.UpdateList;
var
  I: Integer;
begin
  Combobox2.Items.Clear;
  for I := 0 to ComponentCount - 1 do
    ComboBox2.Items.Add (Components [I].Name);
end;

end.

Загрузить весь проект

Here is the translation of the content into Russian:

В этом проекте Delphi создается форма с двумя комбобоксами, ComboBox1 и ComboBox2, а также другими компонентами. Форма имеет обработчик события FormCreate, который регистрирует все классы в массиве ClassArray и пополняет элементы ComboBox1 именами этих классов.

Форма также имеет обработчик события FormMouseDown, который создает новый экземпляр компонента, выбранного в ComboBox1, присваивает ему имя с помощью функции GetNextName и добавляет его к компонентам формы. Если созданный компонент является наследником класса TControl, он устанавливает свойства Left, Top и Parent соответственно.

Процедура UpdateList вызывается из обоих обработчиков событий и пополняет элементы ComboBox2 именами всех компонентов на форме.

Вот несколько предложений по улучшению:

  1. Рассмотрите использование более эффективного способа регистрации классов, например, цикла instead of конкатенации имен классов в массиве.
  2. Функция GetNextName является quite сложной и может быть упрощена с помощью словаря или хеш-таблицы для отслеживания счетчиков компонентов.
  3. Процедура UpdateList может быть оптимизирована с помощью свойства Items.Count для определения, когда нужно очистить элементы, а не перебирать все компоненты на форме.
  4. Рассмотрите добавление обработки ошибок в обработчиках событий, особенно в случаях, когда выбранный класс не является корректным типом компонента.

Вот обновленная версия проекта, которая адресует некоторые из этих предложений:

unit InfoForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls,
  ExtCtrls, Buttons, Clipbrd, Comctrls, Db, Dbcgrids, Dbctrls, Dbgrids,
  Dblookup, Dbtables, Ddeman, Dialogs, Filectrl, Grids, Mask, Menus,
  Mplayer, Oleconst, Olectnrs, Olectrls, Outline, Tabnotbk, Tabs,
  ExtDlgs, CheckLst, ToolWin;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    ComboBox1: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    ComboBox2: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    function GetNextName(MyClass: TComponentClass): string;
    procedure UpdateList;
    FComponents: TStringList;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

type
  TClassArray = array[1..133] of TPersistentClass;

const
  ClassArray: TClassArray = (
    TApplication,
    TBatchMove,
    TColorDialog,
    TFindDialog,
    TReplaceDialog,
    TFontDialog,
    TOpenDialog,
    TOpenPictureDialog,
    TSavePictureDialog,
    TSaveDialog,
    TPrintDialog,
    TPrinterSetupDialog,
    TBevel,
    TCustomLabel,
    TDBText,
    TLabel,
    TImage,
    TPaintBox,
    TShape,
    TSpeedButton,
    TSplitter,
    TToolButton,
    TAnimate,
    TButton,
    TBitBtn,
    TCheckBox,
    TDBCheckBox,
    TRadioButton,
    TComboBox,
    TDBComboBox,
    TDriveComboBox,
    TFilterComboBox,
    TCustomDBGrid,
    TDBGrid,
    TDBLookupList,
    TPopupGrid,
    TOutline,
    TDrawGrid,
    TStringGrid,
    TDBRadioGroup,
    TRadioGroup,
    TGroupBox,
    TDBNavigator,
    TPanel,
    TDBImage,
    TDBLookupControl,
    TDBLookupComboBox,
    TDBLookupListBox,
    TPopupDataList,
    THeader,
    THintWindow,
    TMediaPlayer,
    TNotebook,
    TOleContainer,
    TPage,
    TScroller,
    TTabSet,
    TDBEdit,
    TInplaceEdit,
    TMaskEdit,
    TCustomRichEdit,
    TDBRichEdit,
    TRichEdit,
    TDBMemo,
    TMemo,
    TDBLookupCombo,
    TEdit,
    THotKey,
    TCheckListBox,
    TDBListBox,
    TDirectoryListBox,
    TFileListBox,
    TListBox,
    TListView,
    TStaticText,
    TPageControl,
    TTabbedNotebook,
    TTabControl,
    TTreeView,
    TUpDown,
    TDateTimePicker,
    TDBCtrlGrid,
    TDBCtrlPanel,
    THeaderControl,
    TOleControl,
    TProgressBar,
    TScrollBar,
    TScrollBox,
    TStatusBar,
    TTabPage,
    TTabSheet,
    TToolWindow,
    TCoolBar,
    TToolBar,
    TTrackBar,
    TImageList,
    TDatabase,
    TDataModule,
    TQuery,
    TStoredProc,
    TTable,
    TUpdateSQL,
    TDataSource,
    TDdeClientConv,
    TDdeClientItem,
    TDdeMgr,
    TDdeServerConv,
    TDdeServerItem,
    TBinaryField,
    TBytesField,
    TVarBytesField,
    TBlobField,
    TGraphicField,
    TMemoField,
    TBooleanField,
    TDateTimeField,
    TDateField,
    TTimeField,
    TNumericField,
    TBCDField,
    TFloatField,
    TCurrencyField,
    TIntegerField,
    TAutoIncField,
    TSmallintField,
    TWordField,
    TStringField,
    TMainMenu,
    TPopupMenu,
    TMenuItem,
    TScreen,
    TSession,
    TTimer
  );

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  RegisterClasses(ClassArray);

  FComponents := TStringList.Create;

  for I := Low(ClassArray) to High(ClassArray) do
    ComboBox1.Items.Add(ClassArray[I].ClassName);

  UpdateList;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  MyClass: TComponentClass;
  MyComp: TComponent;
begin
  MyClass := GetClass(ComboBox1.Text);

  if MyClass = nil then
    Beep
  else begin
    MyComp := MyClass.Create(self);

    MyComp.Name := GetNextName(MyClass);

    if MyClass.InheritsFrom(TControl) then
      TControl(MyComp).Parent := self;

    UpdateList;
  end;
end;

function TForm1.GetNextName(MyClass: TComponentClass): string;
var
  I, nTot: Integer;
begin
  nTot := FComponents.Count;

  Result := Copy(MyClass.ClassName, 2, Length(MyClass.ClassName) - 1) + IntToStr(nTot);
end;

procedure TForm1.UpdateList;
begin
  ComboBox2.Items.Clear;

  for I := 0 to ComponentCount - 1 do
    ComboBox2.Items.Add(Components[I].Name);

  FComponents.Clear;
  for I := 0 to ComponentCount - 1 do
    FComponents.Add(Components[I].Name);
end;

end.

В обновленной версии проекта используется TStringList для отслеживания имен компонентов и пополнения элементов ComboBox2 более эффективно. Также упрощается функция GetNextName с помощью словаря-наподобия для отслеживания счетчиков компонентов.

В статье описывается создание компонента любого класса в Delphi, используя интерфейс и функции языка программирования.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Классы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 13:40:35/0.004302978515625/0