Ereignis Auswahl beim Doppelklicken in der Entwurfsphase

Rund um die LCL und andere Komponenten

Ereignis Auswahl beim Doppelklicken in der Entwurfsphase

Beitragvon siro » 13. Dez 2017, 19:37 Ereignis Auswahl beim Doppelklicken in der Entwurfsphase

Einen schönen guten Abend,
ich habe mal eine generelle Frage zu Komponenten in der Entwurfsphase:

Wenn ich eine Komponente auf das Formular ziehe und dann doppelt drauf klicke,
wird automatisch ein OnXXXX Ereignis erzeugt.
Zum Beispiel beim Button OnClick
Beim Editfeld OnChange, obwohl es hier ja auch OnClick gibt.

Wer bestimmt eigentlich welches Ereigniss beim Doppelklick erzeugt wird ?
Kann ich das in meinen Komponenten irgendwie steuern ?

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
siro
 
Beiträge: 290
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

Beitragvon Michl » 15. Dez 2017, 11:34 Re: Ereignis Auswahl beim Doppelklicken in der Entwurfsphase

Das wird per DefaultComponentEditor bestimmt. Dabei wird das best mögliche Event genutzt, was für die Komponente zur Verfügung steht. Reihenfolge: OnCreate (default), OnClick, OnChange.

Siehe:
http://wiki.freepascal.org/How_To_Write_Lazarus_Component#Property_editors

oder \components\ideintf\componenteditors.pas ca. Zeile 132:
Code: Alles auswählen
  The default component editor (TDefaultEditor) implements Edit to searches the
  properties of the component and generates (or navigates to) the OnCreate,
  OnChanged, or OnClick event (whichever it finds first).

Oder per Code ( \components\ideintf\componenteditors.pas):
Code: Alles auswählen
procedure TDefaultComponentEditor.EditProperty(const Prop: TPropertyEditor;
  var Continue: Boolean);
...
begin
  if not Assigned(FFirst) and (Prop is TMethodPropertyEditor) then
    FFirst := Prop;
  PropName := Prop.GetName;
  BestName := '';
  if Assigned(FBest) then
    BestName := FBest.GetName;
  // event priority is hardcoded:
  // first priority has FBestEditEvent (default: OnCreate), then OnClick and OnChange is the last
  if CompareText(PropName, FBestEditEvent) = 0 then
    ReplaceBest
  else
  if CompareText(BestName, FBestEditEvent) <> 0 then
    if CompareText(PropName, 'ONCHANGE') = 0 then
      ReplaceBest
    else
    if CompareText(BestName, 'ONCHANGE') <> 0 then
      if CompareText(PropName, 'ONCLICK') = 0 then
        ReplaceBest;
end;   
Zuletzt geändert von Michl am 15. Dez 2017, 13:12, insgesamt 1-mal geändert.
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2243
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon siro » 15. Dez 2017, 12:50 Re: Ereignis Auswahl beim Doppelklicken in der Entwurfsphase

Oh supi Michl,
vielen Dank für die "reichenhaltigen" Informationen.

Dann gibt das jetzt langsam Sinn.
Bei meinen Componenten, die keinen OnChange bzw. OnClick haben,
nimmt der PropertyEditor das erste verfügbare Ereignis, hab ich grad ausprobiert,
wobei die Ereignissortierung wohl stets alphabetisch ist. (kann man das eigentlich ändern)

Es ist also direkt im PropertyEditor verankert.
Ich dachte man könnte es evtl. mit einem Schlüsselwort hinter der Methode (Eigenschaft) festlegen...
Einen separaten PropertyEditor wollte ich jetzt nicht schreiben, obwohl ich das in
Delphi 3 schon mal angefangen hatte.

Aber die Grundlage ist nun da und mein Verständnis dazu wächst.

Hab vielen Dank für deine Mühe
und ein schönes Wochenende.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
siro
 
Beiträge: 290
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

Beitragvon Michl » 15. Dez 2017, 13:09 Re: Ereignis Auswahl beim Doppelklicken in der Entwurfsphase

Ich hatte das eben nochmal getestet. Für eine eigene Komponente, wenn man wirklich nur einen anderen Default Event Handler haben will, genügt es, einen eigenen ComponentEditor zu erstellen und in dessen Contructor das BestEditEvent zu setzen. Diesen dann noch registrieren und fertig. Das ist sehr unkompliziert.

Zum Beispiel wird das so bei dem TTimerComponentEditor gemacht (siehe \components\ideintf\componenteditors.pas):
Code: Alles auswählen
  TTimerComponentEditor = class(TDefaultComponentEditor)
  public
    constructor Create(AComponent: TComponent;
      ADesigner: TComponentEditorDesigner); override;
  end;
...
constructor TTimerComponentEditor.Create(AComponent: TComponent;
  ADesigner: TComponentEditorDesigner);
begin
  inherited Create(AComponent, ADesigner);
  BestEditEvent := 'ONTIMER';
end
...
initialization
  RegisterComponentEditor(TCustomTimer, TTimerComponentEditor)


Eine weitere Möglichkeit wäre es, einen eigenen Komponenteditor zu erstellen (abgeleitet von TComponentEditor oder eines Abkömmlings). Dort kann man die Procedure Edit überschreiben und per CreateComponentEvent (Unit PropEdits) einen eigenen Default Event Handler erstellen lassen.

Siehe z.B. C:\32fpc304\LazTrunk\components\ideintf\actionseditor.pas (wobei hier der EventHandler per Doppelklick auf einen ListBox-Eintrag erstellt wird):
Code: Alles auswählen
procedure TActionListEditor.lstActionNameDblClick(Sender: TObject);
var
  CurAction: TContainedAction;
begin
  if lstActionName.GetIndexAtY(lstActionName.ScreenToClient(Mouse.CursorPos).Y) < 0
  then Exit;
  CurAction := GetSelectedAction;
  if CurAction = nil then Exit;
  // Add OnExecute for this action
  CreateComponentEvent(CurAction,'OnExecute');
end;
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2243
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon siro » 15. Dez 2017, 13:55 Re: Ereignis Auswahl beim Doppelklicken in der Entwurfsphase

Das wär ja simpel,
probier ich gleich mal aus

Juppi, nach einigen Anlaufschwierigkeiten funktioniert es nun.

Er hat TDefaultComponentEditor nicht gefunden.
Ich muss in die Uses Anweisung noch
ComponentEditors mit aufnehmen...

Und in das Package musste ich noch
IDEIntf
hinzufügen

Jetzt wird bei mir bei einem Doppelclick OnMouseUp aufgerufen.
Ist zwar Blödsinn, aber es funktioniert.

Code: Alles auswählen
 
 
uses .....ComponentEditors, .........;
 
Type TLAZ_SiroSliderComponentEditor = class(TDefaultComponentEditor)
  public
    constructor Create(AComponent: TComponent;
      ADesigner: TComponentEditorDesigner); override;
end;       
 
constructor  TLAZ_SiroSliderComponentEditor.Create(AComponent: TComponent;
  ADesigner: TComponentEditorDesigner);
begin
  inherited Create(AComponent, ADesigner);
  BestEditEvent := 'OnMouseUp';
end;
 
 
procedure Register;
begin 
  RegisterComponents('Laz_Siro', [TSliderHor]);           // die eigentliche Komponente
  RegisterComponentEditor(TSliderHor,TLAZ_SiroSliderComponentEditor);   // der Editor
end;             
 


Da hast Du mir SEHR weitergeholfen. Nochmals vielen Dank Michl.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
siro
 
Beiträge: 290
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

• Themenende •

Zurück zu Komponenten und Packages



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

porpoises-institution
accuracy-worried