Dobrý den, potřeboval bych si udělat vlastní událost komponenty např OnClick, ale nemůžu nikde najít řešení, nevím jak se to nazývá. Mohl by mi prosím někdo nastínit řešení této problematiky? Děkuji.
Fórum › Delphi
Vlastní údálost komponenty
To sa vola event. Ak mas vlastny komponent, zalezi od coho bol odvodeny. Na odchytavanie udalosti existujuceho komponentu vies pouzit metody, ktore overridnes - ak je to komponent, ktory si urobil odvodenim od nejakeho abstraktneho komponentu, musis si click odchytit cez message - pozri sa, ako sa to robi v inych kompontenotch, ved Delphi je distribuovane (ked sa dobre pamatam) so zdrojakmi.
Samotny event handler si urobis tak, ze si zadefinujes (alebo pouzijes existujuci) typ TMojEvent = function(Sender: ???, Args ???): Boolean;
a tento typ pouzijes ako published property: property OnMojEvent: TMojEvent read FOnMojEvent write FOnMojEvent;
potom zistis, ci komponent ma definovany event na mieste, kde ho chces volat if Assigned(OnMojEvent) then OnMojEvent(Self, ???);
Toto budes volat tam, kde si odchytis message. Delphi som uz nejaky ten rok nevidel, ale napr. KeyDown chytis tak, ze si zadefinujes napr. procedure CNKeyDown(var Message: TWMKeyDown); message CN_KEYDOWN;
telo fcie moze byt take:
procedure TMojKomponent.CNKeyDown(var Message: TWMKeyDown);
begin
if Message.CharCode = VK_RETURN then
???
inherited;
end;
ak das do vnutra volanie toho eventu (ale pred tym zisti, ci nie je nil) tak tvoj komponent ked dostane informaciu, ze na nom bola stlacena klavesa, zavola tvoj event.
Hore som ti popisal vseobecny postup tvordby eventov (ked potrebujes chytat message / signaly) z GUI.
Oprasil som moje starucke Delphi 7 uz zabudnute kdesy v Program Files ;) a vlastne som zistil, ze je to este jednoduchsie - ak chces konkretny klik.
Neviem od coho mas odvodeny tvoj kontrol a tak sa velmi tazko radi - pretoze neviem na co to chces pouzit, imho, desktopovo som uz nemyslel roky, ale ukazem ti v rychlosti ako na to:
1. Vytvor si triedu TMojControl a odvod ju od TPanel (daj do usingu ExtCtrls) - predpokladam, ze robime nad VCL (TMojControl = class(TPanel)).
2. Neviem ako nieco funguje, takze drzim CTRL a kliknem na TPanel. Uvidim, ze definuje v published event OnClick, ktory hladam. Definicia ktoru tam vidis je len vytiahnutim interface z predka - teda kod nedefinuje trieda TPanel ale je to zdedene. TPanel to len "publikuje". To je dobry zvyk vytvarat komponenty takto, pretoze ak niekto by chcel pouzit len cast z nasho komponentu, rozsirit ho, ale OnClick nie je pre neho relevantny, tak ho proste nebude publikovat.
Takze drzim CTRL a doklikam sa az ku definicii OnClick ktora je priamo na TComponent triede. Je definovana ako protected - tj. odvodena trieda tuto property vidi, ale instancia uz nie (preto najvrchnejsi panel vytiahol definiciu do published). Rozdiel medzi public a published je v dizajneri. Ten totiz enumeruje len published property (to co vidis v object inspectore).
Ako to funguje (ten click) sa mozes pozriet na komponente TComponent (popisal som to vyssie). Kedze chces vyuzit prave CLICK ktory uz bol definovane, tak velmi sa tomu rozumiet nemusis - pretoze uz to za teba odmakali v Borlande.
3. Takze viem, ze vsetky komponenty odvodene od TComponent uz maju odmakany klik, ja len potrebujem vytiahnut tu funkcnost vonku. Tak pre nas priklad si vytvorim komponent, ktory ma canvas - aby som vedel nieco namalovat - neviem co robi tvoj komponent, ale je to jedno - moj zobrazi krizik:
TMojControl = class(TGraphicControl)
protected
procedure Paint; override;
published
property OnClick;
end; // MojLabel
Ako si mozes vsimnut overriduje Paint metodu - to som vykradol z triedy TPanel (TCustomPanel) ked som hladal, ako sa vlastne vykresluje. Ja pouzijem len Canvas na ktory mozem malovat, z toho dovodu neodvadzam triedu od TCustomPanel ale priamo od TGraphicControl pretoze vlastnosti TPanelu vlastne nepotrebujem.
Ako si tiez mozes vsimnut vytahujem do published OnClick presne tak, ako to urobili s TPanelom.
Takto moze vyzerat telo Paint:
procedure TMojControl.Paint;
// ---------------------------------------------------------------------------
procedure LineXY(Canvas: TCanvas; X1, Y1, X2, Y2: Integer);
begin
if Assigned(Canvas) then
begin
with Canvas do
begin
MoveTo(X1, Y1);
LineTo(X2, Y2);
end; // WITH
end; // IF
end;
// ---------------------------------------------------------------------------
begin
Canvas.Pen.Color := clBlack;
LineXY(Canvas, 0, 0, Width, Height - 1);
LineXY(Canvas, 0, Height - 1, Width, 0);
end;
4. Idem vyskusat co som urobil. Tento komponent by si mal presunut do vlsatneho suboru, ktory bude sucastou nejakeho BPLka, ktore si naimportujes do Delphi, pridas na paletu a uvidis svoj komponent. Ale to uz asi vies.
Mne sa to robit neche (ani si to uz poriadne nepamatam) a tak si ho vytvorim v run-time. Urobim si novu aplikaciu, pridam odkaz na moj komponent v usingu, subor zaradim do projektu.
Vo FormCreate vytovrim moj komponent:
procedure TForm1.FormCreate(Sender: TObject);
begin
with TMojControl.Create(Self) do
begin
Top := 20;
Left := 30;
Width := 100;
Height := 50;
OnClick := Kliknutie;
Parent := Self;
end; // with
end;
Po prelozeni ti zahlasi chybu, ze neexistuje Kliknutie metoda, tak ju pridam do definicii triedy (je to event, takze podla logiky Delphi 7 by mala byt definovana priamo pod FormCreate (bez private / public / protected).
Ta metoda moze vyzerat takto:
procedure TForm1.Kliknutie(Sender: TObject);
begin
ShowMessage('Kukuk');
end;
Teraz ked niekto klikne na moj "krizik" tak sa mu zobrazi hlasenie.
Ak potrebujes odchytit kliknutie v komponente, znova si otvor TControl. Ako sme sa uz dozvedeli event OnClick vlastne je handler pre kliknutie z aplikacie. Ak si das v kode vyhladat toto: OnClick(Self) tam sa vola tvoj event, ked je definovany Assigned(FOnClick).
Ako vidis, je to metoda procedure TControl.Click; ked sa pozriet na jej interface CTRL+SHIFT+Sipka hore, zistis ze je dynamicka (to je v podstate ako virtual - nemusis to riesit v tomto stadiu skusenosti) - ale dolezity je fakt, ze ju vieme prepisat! Kto a ako ju vola nas opat nemusi zaujimat (staci nam cista logika na objavovanie tajov programovania, zvysok pride sam).
Vratime sa spat do svojho komponenty a overrideneme Paint metodu, kde zavolame invalidate. To sposobi, ze sa komponent "prekresli". Ucinok odchytenia eventu mozeme vyskusat tak, ze budeme generovat nahodne farbu ciary - podla toho si upravime OnPaint, konkretne riadok anvas.Pen.Color := nastavime na nahodnu farbu.
Teraz ked si spustis aplikaciu, tak pri kliknuti sa ti zacnu menit ciary - teda ich farba. Ak si vsak nechal v metode Click LEN invalidate, tak ako si mozes vsimnut, uz sa ti prestal spustat povodny event overridovany na formulari. To je preto, ze sme Click prekryli uplne novym telom a tak sa povodne nikdy uz nevykonalo. Aby sme to zabezpecili, musime ho zavolat (OOP) cez inherited metodu.
Vysledny kod moze vyzerat takto:
unit Unit2;
interface
uses
Controls, Graphics;
type
// *****************************************************************************
// *** TMojControl *************************************************************
// *****************************************************************************
TMojControl = class(TGraphicControl)
protected
procedure Paint; override;
procedure Click; override;
function GetLineColor: TColor;
published
property OnClick;
end; // MojLabel
implementation
uses
Windows;
// *****************************************************************************
// *** TMojControl *************************************************************
// *****************************************************************************
function TMojControl.GetLineColor: TColor;
begin
Result := TColor(Random(255));
end;
// *****************************************************************************
procedure TMojControl.Click;
begin
Invalidate; // Vykreslime objekt este raz
inherited Click; // Zavolame povodnu udalost, ktora vola event handler
end;
// *****************************************************************************
procedure TMojControl.Paint;
// ---------------------------------------------------------------------------
procedure LineXY(Canvas: TCanvas; X1, Y1, X2, Y2: Integer);
begin
if Assigned(Canvas) then
begin
with Canvas do
begin
MoveTo(X1, Y1);
LineTo(X2, Y2);
end; // WITH
end; // IF
end;
// ---------------------------------------------------------------------------
begin
Canvas.Pen.Color := GetLineColor; // Popytame si nahodnu farbu
// Nakreslime krizik
LineXY(Canvas, 0, 0, Width, Height - 1);
LineXY(Canvas, 0, Height - 1, Width, 0);
end;
// *****************************************************************************
// *** TMojControl *************************************************************
// *****************************************************************************
initialization
Randomize; // Aktivujeme generator nahodnych cisel
end.
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Vlastní událost — založil vigum
Tvorba vlastní komponenty — založil pavelll
QT-prekresleni komponenty — založil tom
Adresa komponenty — založil infomf
Instalace komponenty — založil Michal