Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Gemeinsame OnClick - Behandlung (https://www.delphipraxis.net/12834-gemeinsame-onclick-behandlung.html)

Doc F 4. Dez 2003 19:58


Gemeinsame OnClick - Behandlung
 
Hi there,

Also, ich habe da min. zwei Gruppen von sagen wir mal, TButtons . BtnFirst1, BtnPrior1,BtnNext1... und BtnFirst2... Schön, natürlich könnte ich jetzt für jeden Button eine eigene OnClick-Routine schreiben, aber das artet ja aus, zumal BtnFirst1, BtnFirst2 etc. ja eigenlich das selbe tun.
OK, ich kann über:

Delphi-Quellcode:
procedur NavBtnClick(Sender : TObject);
var
  name : String;
  id  : Integer;

begin
  name := (Sender AS TButton).name;
  id := name(length(name));
  ...
aber zB.

Delphi-Quellcode:
  BtnFirst[id].enabled := True;
erzeugt bei meinem Compiler höchstens ein hönisches Grinsen. :angle:

Ist das so überhaupt irgendwie machbar ?


Thanks a lot

Doc F

Zitat:

Nicht jeder ist so egoistisch, das er sich selbst Gedanken macht.

himitsu 4. Dez 2003 20:15

Re: Gemeinsame OnClick - Behandlung
 
Ein Hallöle von http://www.FrankNStein.de/Smiley-Wolke.gif und herzlich willkommen in unserer DP-Gemeinde,

also, es gibt verschiedene Möglichkeiten.

Abfragen ob Sender ein bestimmtes Objekt ist:
Delphi-Quellcode:
If Sender is Button1 Then ...
Den Namen des Senders abfragen:
Delphi-Quellcode:
If TButton(Sender).Name = 'Button1' Then ...
Der Eigenschaft TAG der verschiedenen Objekte verschiedene Werte zuweisen und diese abfragen:
Delphi-Quellcode:
Case TButton(Sender).Tag of
  1: ...
  2: ...
  ...
End;
Direkt Sender was zuweisen:
Delphi-Quellcode:
TButton(Sender).Enabled := True;
...

( "TButton(Sender)" und "(Sender as TButton)" kommt auf's Selbe raus )

http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif

mr2 4. Dez 2003 20:20

Re: Gemeinsame OnClick - Behandlung
 
Hallo,

wie Du schon an der Syntaxhervorhebung erkennen kannst, solltest Du lokale Variablen nie "name" nennen, das führt nur zu Verwechslungen mit TComponent.Name und dessen Nachfahren.

Wenn Du allen Buttons den selben Eventhandler zuweist, kannst Du sie über die Eigenschaft "Tag" auseinanderhalten.
Einfach für jeden Button einen anderen Tag einstellen.
Delphi-Quellcode:
procedure ButtonClick(Sender : TObject);
begin
  if (Sender is TButton) then begin
    case TButton(Sender).Tag of
      1: ShowMessage('Erster Button!');
      2: ShowMessage('Zweiter Button!');
      3: ShowMessage('Dritter Button!');
      4: ShowMessage('Vierter Button!');
      else ShowMessage('Anderer Button!');
    end;
  end else ShowMessage('Kein Button!');
end;
mr2
[edit]Da war mal wieder jemand schneller :lol: [/edit]

Doc F 4. Dez 2003 20:32

Re: Gemeinsame OnClick - Behandlung
 
Wow, seid ihr aber schnell.

War nur gerade kurz was anderes am suchen, und schon...

Ok, name war kein gutes Beispiel, zugegeben, aber 's ging ja eher ums Prinzip.

Super, was die Buttons angeht, war ich ja doch ein wenig begriffsstutzig.

Delphi-Quellcode:
TButton(Sender).Enabled := True;
trifft's genau, autsch.

So weit, so gut. Wie aber nun, wenn nicht nur Buttons angesprochen werden müssen.
Bin ich fies, wenn ich da auch noch zB. TTable reinmenge ?

Ansonsten schon mal dankeschön, habt mir schon geholfen.

Doc F

Zitat:

Nicht jeder ist so egoistisch, das er sich selbst Gedanken macht.

himitsu 4. Dez 2003 21:08

Re: Gemeinsame OnClick - Behandlung
 
:oops: Ausverseh'n 'Edit' an statt 'Zitat'
(weiß aber nicht mehr genau was hier stand, dashalb nicht wundern)

Vorher halt den Typ abfragen:
Delphi-Quellcode:
If Sender.ClassType = TButton Then Begin
  TButton(Sender).Enabled := True;
End Else If Sender.ClassType = TBitBtn Then Begin
  TBitBtn(Sender).Enabled := True;
End Else If Sender.ClassType = TEdit Then Begin
  TEdit(Sender).Enabled := True;
End Else If Sender.ClassType = TMemo Then Begin
  TMemo(Sender).Enabled := True;
End;
http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif

Doc F 5. Dez 2003 04:04

Re: Gemeinsame OnClick - Behandlung
 
Danke für die Hilfe,

Himitsu hat mich zum Schluss war falsch verstanden : Sender ist immer TButton, der diverse andere Sachen steuern soll.

Trotzdem war die Lösung in euren Antworten enthalten. :love:

Doc F

Bernd Ua 5. Dez 2003 07:34

Re: Gemeinsame OnClick - Behandlung
 
Moin,Moin

Zitat:

( "TButton(Sender)" und "(Sender as TButton)" kommt auf's Selbe raus )
Das mag ich so nicht stehen lassen. TButton(Sender) ist ein unsicherer Typecast ( zumindest bis Delphi 7)
und führt im günstigesten Fall zu Schutzverletzungen, wenn die Annahme nicht stimmt. Hier ist alles erlaubt
was dieselbe Grösse hat. d.h.
Delphi-Quellcode:
TButton(4).Caption := 'Bumm';
wird anstandlos kompiliert !
(Sender as TButton) ist dagegen ein sicherer Typecast und erzeugt eine Exception
EInvalidCast, wenn die Annahme mal falsch war, weil man das Ereignis mal woanders angeklemmt hat.

Ergo TButton(Sender) nur verwenden, wenn zumindest vorher mit is geprüft wurde
(BTW is ist besser als xxx.ClassType= yyy, auch wenn es minimal anders arbeitet).

Die Spagetti-if-else Geschichte :

Delphi-Quellcode:
If Sender.ClassType = TButton Then Begin
  TButton(Sender).Enabled := True;
End Else If Sender.ClassType = TBitBtn Then Begin
  TBitBtn(Sender).Enabled := True;
End Else If Sender.ClassType = TEdit Then Begin
  TEdit(Sender).Enabled := True;
End Else If Sender.ClassType = TMemo Then Begin
  TMemo(Sender).Enabled := True;
End;
kann man deutlich kürzen, wenn man sich auf den kleinsten gemeinsamen
Nenner der Klassen/Eigenschaften besinnt ( in diesem Fall TControl) und
mit is statt ClassType arbeitet.

Delphi-Quellcode:
if Sender is TControl then
    TControl(Sender).Enabled := false;
  else
    ...

SCNR , Bernd

himitsu 5. Dez 2003 08:45

Re: Gemeinsame OnClick - Behandlung
 
Das mit dem BOOM: Dafür ist natürlich der Programierer verantwortlich. (Wenn es knallt, ist er/sie halt selber Schuld)

OK, für Enabled ist das schon etwas übertrieben, aber bei Komponententypischen Eigenschaften (z.B.
Delphi-Quellcode:
If Sender.ClassType = TButton Then Begin
  TButton(Sender).Caption := 'Text';
...
) ist mit TControl(Sender).Caption nichts mehr los.

http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif

choose 5. Dez 2003 09:00

Re: Gemeinsame OnClick - Behandlung
 
Zitat:

Zitat von himitsu
[...] für Enabled ist das schon etwas übertrieben, aber bei Komponententypischen Eigenschaften [...] ist mit TControl(Sender).Caption nichts mehr los.

Hi himitsu,

bei selbstgeschriebenen Klassen mit Interfaces, für die "dreckige Lösung" mit RTTI und für den OO-Entwickler mit einem Visitor, lässt sich das Problem ohne n Fallunterscheidungen (die mit der Wahrscheinlichkeit p immer 0<m<=n Fehlerhaben, bei denen die Übersicht gegen 1/n^2 strebt und die Wartbeikeit bei n! liegt ;)) lösen.

Bernd Ua 5. Dez 2003 09:03

Re: Gemeinsame OnClick - Behandlung
 
2 mal Einspruch

Zitat:

(Wenn es knallt, ist er/sie halt selber Schuld)
Eben - das merkt man leider vielen Programmen an. Mal eben nach nem halben Jahr ne Änderung eingebaut und ...
Da ist für mich der Unterschied zwischen "rumcoden" und programmieren

Zitat:

[...]ist mit TControl(Sender).Caption nichts mehr los.
Deswegen habe ich kleinsten gemeinsamen Nenner geschrieben <g>
Mit dem man (TControl/TwinControl) im übrigen schon ne ganze Menge reissen kann.

Mit Caption get es übrigens auch - zumindest wenn man zugegebenermassen etwas unsauber
in den protected Bereich einbricht

Delphi-Quellcode:
type
  TControlCracker = class(TControl);

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Sender is TControl then
    TControlCracker(Sender).Caption := 'Geht nich - gibbs nich'
  else
    ShowMessage(sender.Classname);
end;

Bernd

choose 5. Dez 2003 09:19

Re: Gemeinsame OnClick - Behandlung
 
Ohne Pointer zu programmieren ist also wie Safersex, Bernd, und was sind dann CrackerClasses, Pfui ;)

@Doc F: Weder CrackerClasses noch Konstruckte der Form
Delphi-Quellcode:
asm
  mov [Sender+$42], eax
end;
sind Lösungen, die "sicher" funktionieren (obgleich Crackerclasses bedingt auch in D8 funktioneren sollen... *grummel*)
Ich habe schon Komponenten gesehen, die zwar von TControl erben, die Getter und Setter der Eigenschaft Caption jedoch nicht über TControl.GetText sondern über aggregierte Objekte implementiert worden sind. Nicht zuletzt in diesen Fällen würden die Zugriffe über Pointer oder CrackerClasses (die im Wesentlichen nichts anderes tun, weil sie von einem statischen Offset der Exemplarvariablen, der VMT oder einer "unbekannten" festen Methodenadresse mit einer "hingemauschelten Referenz" als impliziten Parameter ausgehen) nicht funktionieren... Abgesehen davon widerspricht dieser Ansatz dem Geheimnisprinzip der OOP!

Bernd Ua 5. Dez 2003 09:36

Re: Gemeinsame OnClick - Behandlung
 
Zitat:

Ohne Pointer zu programmieren ist also wie Safersex, Bernd, und was sind dann CrackerClasses, Pfui
Crackerklasse = Seitensprung ?????? :oops:

Zitat:

(obgleich Crackerclasses bedingt auch in D8 funktioneren sollen... *grummel*)
Dagegen hilft dann aber die neue Sichtbarkeit strictly protected in Delphi 8.

Zitat:

Ich habe schon Komponenten gesehen, die zwar von TControl erben, die Getter und Setter der Eigenschaft Caption jedoch nicht über TControl.GetText sondern über aggregierte Objekte implementiert worden sind.
Hmmmmhh - wie soll das gehen, wo doch GetText und SetText private sind ? Da hat doch wohl niemand eine Property selben Namens redeklariert, wo allgemein bekannt ist, dass Properties nicht polymorph sind ?

Aber du hast ja recht - safer programming ist ne Crakcer Class nicht - können wir uns dann auf diese Variante einigen

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  if Sender is TControl then
    TControl(Sender).SetTextBuf('Geht nich - gibbs nich');
end;
( sag jetzt nicht nein - sonst komme ich mit TWinControl und WM_SetText , oder noch besser EnumWindows ...<g>)

Bernd

choose 5. Dez 2003 09:55

Re: Gemeinsame OnClick - Behandlung
 
Zitat:

Zitat von Bernd Ua
Crackerklasse = Seitensprung ??????

:D

Zitat:

Zitat von Bernd Ua
[...] können wir uns dann auf diese Variante einigen [...] ( sag jetzt nicht nein - sonst komme ich mit TWinControl und WM_SetText , oder noch besser EnumWindows ...<g>)

Probleme wird es dann geben, wenn es sich nicht um "Standardeigenschaften" handeln sollte. Hier sollte IMHO eine sichere, wartbare und übersichtliche Lösung gewählt werden.
Für "die schnelle Nummer zwischendruch" ist die RTTI bei Published Properties aber durchaus eine gute Wahl, zb so (nur mit D7 getestet, ggf gibt es die easy accessors in anderen Versionen nicht in dieser Form)
Delphi-Quellcode:
uses
  TypInfo;

//...

procedure SetStrPropIfPossible(const AnInstance: TObject;
  const APropName, AValue: string);
begin
  Assert( Assigned(AnInstance) );

  if IsPublishedProp(AnInstance, APropName) and
    (PropType(AnInstance, APropName) in [tkWChar, tkLString, tkWString]) then
      SetStrProp(AnInstance, APropName, AValue);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetStrPropIfPossible(Sender, 'Caption', 'What about RTTI?');
end;

Bernd Ua 5. Dez 2003 10:27

Re: Gemeinsame OnClick - Behandlung
 
Hi choose,

bei nicht Standardeigenschaften kann ich Dir bzgl RTTI nur zustimmen.
Die easy Accessors sind schon einige Versionen dabei (mind D5) -
aber wesentlich umständlicher wars in D1 auch nicht

Grüsse Bernd

himitsu 5. Dez 2003 10:34

Re: Gemeinsame OnClick - Behandlung
 
Der arme Doc weiß jetzt eventuell nicht mehr was hier abgeht.

Und ich bleibe dann wohl doch beim alten (kommt ja bei mir selten genug vor),
da weiß/sehe ich wenigstens noch besser was dort passieren soll. :nerd:

Zitat:

Zitat von (me)
Delphi-Quellcode:
If Sender.ClassType = TButton Then Begin
  TButton(Sender).Enabled := True;
End Else If Sender.ClassType = TBitBtn Then Begin
  TBitBtn(Sender).Enabled := True;
End Else If Sender.ClassType = TEdit Then Begin
  TEdit(Sender).Enabled := True;
End Else If Sender.ClassType = TMemo Then Begin
  TMemo(Sender).Enabled := True;
End;

http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif http://www.FrankNStein.de/Smiley-Spinne.gif http://www.FrankNStein.de/Smiley-Winken.gif

Nalincah 5. Dez 2003 10:41

Re: Gemeinsame OnClick - Behandlung
 
Zitat:

Zitat von himitsu
:oops: Ausverseh'n 'Edit' an statt 'Zitat'
(weiß aber nicht mehr genau was hier stand, dashalb nicht wundern)

Vorher hat den Typ abfragen:
Delphi-Quellcode:
If Sender.ClassType = TButton Then Begin
  TButton(Sender).Enabled := True;
End Else If Sender.ClassType = TBitBtn Then Begin
  TBitBtn(Sender).Enabled := True;
End Else If Sender.ClassType = TEdit Then Begin
  TEdit(Sender).Enabled := True;
End Else If Sender.ClassType = TMemo Then Begin
  TMemo(Sender).Enabled := True;
End;
http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif

Vielleicht hab ich was nicht mitgekriegt, beim lesen des Threads, aber wie geht sowas?

Wie kann man auf was klicken was enabled := false hat?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender:TObject);
begin
  If Sender.ClassType = TButton Then Begin
    TButton(Sender).Enabled := True;
end;
Wenn da Enabled auf True gesetzt wird, geh ich davon aus das es vorher auf false stand. Wie kann man also darauf klicken?

Bernd Ua 5. Dez 2003 10:47

Re: Gemeinsame OnClick - Behandlung
 
Hi

Zitat:

Wenn da Enabled auf True gesetzt wird, geh ich davon aus das es vorher auf false stand.
Na ja - muss ja nicht so sein.

Zitat:

Wie kann man also darauf klicken?
Mit der Maus - passiert zwar nix- aber klicken kann man <bg>

Aber mal inm Ernst - war ja nur irgendein theorisches Beispiel. Abgesehen davon So ein Ergeinishandler kann ja auch am
OnChange oder sonstwo hängen. Der Name ist ja schall und Rauch. Oder Du rufst den Ereignishandler
"zu Fuss" auf

Delphi-Quellcode:
...
Button1Click(ListBox1);
...
Bernd

choose 5. Dez 2003 10:54

Re: Gemeinsame OnClick - Behandlung
 
Zitat:

Zitat von himitsu
Und ich bleibe dann wohl doch beim alten (kommt ja bei mir selten genug vor),
da weiß/sehe ich wenigstens noch besser was dort passieren soll. :nerd:

Hi himitsu,

ich habe meine ad hoc-Lösung ein bisschen überarbeitet
Delphi-Quellcode:
type
  TTypeKinds = set of TTypeKind;

procedure SetPropIfPossible(const AnInstance: TObject;
  const APropName: string; const ANeededTypes: TTypeKinds;
  const AValue: Variant); overload;
begin
  Assert( Assigned(AnInstance) );

  if IsPublishedProp(AnInstance, APropName) and
    (PropType(AnInstance, APropName) in ANeededTypes) then
      SetPropValue(AnInstance, APropName, AValue);
end;

procedure SetPropIfPossible(const AnInstance: TObject;
  const APropName, AValue: string); overload;
begin
  SetPropIfPossible(AnInstance, APropName, [tkWChar, tkLString, tkWString],
    AValue);
end;

procedure SetPropIfPossible(const AnInstance: TObject;
  const APropName: string; const AValue: Boolean); overload;
begin
  SetPropIfPossible(AnInstance, APropName, [tkEnumeration], AValue);
end;

procedure SetPropIfPossible(const AnInstance: TObject;
  const APropName: string; const AValue: Integer); overload;
begin
  SetPropIfPossible(AnInstance, APropName, [tkInteger], AValue);
end;
so dass man die Lösung relativ simpel anwenden kann (vielleicht will sich jmd mal die Mühe machen, das ganze zu erweitern und in die Code-Library zu stellen?)
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  SetPropIfPossible(Sender, 'Width', 200);
  SetPropIfPossible(Sender, 'Enabled', False);
  SetPropIfPossible(Sender, 'Caption', 'What about RTTI?');
end;
Ich muss sagen, dass ich die Lösung deutlich Übersichtlicher finde, als zB diese:
Delphi-Quellcode:
If Sender.ClassType = TButton Then Begin
  TButton(Sender).Enabled := True;
  TButton(Sender.Width:= 200;
  Tbutton(Sender).Caption:= 'What about RTTI?';
End Else If Sender.ClassType = TBitBtn Then Begin
  TBitBtn(Sender).Enabled := True;
  TBitBtn(Sender.Width:= 200;
  TBitBtn(Sender).Caption:= 'What about RTTI?';
End Else If Sender.ClassType = TEdit Then Begin
  TEdit(Sender).Enabled := True;
  TEdit(Sender).Width:= 200;
End Else If Sender.ClassType = TMemo Then Begin
  TMemo(Sender).Enabled := True;
  TMemo(Sender).Width:= 200;
End;
Darüber hinaus funktioniert sie mit jeder Delphi-Komponente, die im OI die entsprechenden Eigenschaften besitzt...

himitsu 5. Dez 2003 11:16

Re: Gemeinsame OnClick - Behandlung
 
@General2003: Ich hatte damit nur das Beispiel vom Anfang fortgesetzt und wie Bernd schon sagte war es halt nur eine theorisches Beispiel.
Zitat:

Zitat von Der Doc
Code:
BtnFirst[id].enabled := True;

@choose: OK, wenn das so aussieht, sieht es einfacher aus.
Werd' mir das wohl mal für gleiche Teile merken, allerdings habe ich da auch meistens noch Code, der nicht bei allen Typen vorhanden ist, und das läßt sich ja leider nicht auf so eine Weise einbinden. Da bleibt also nur meine alte Variante.

http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif

choose 5. Dez 2003 11:54

Re: Gemeinsame OnClick - Behandlung
 
Zitat:

Zitat von himitsu
OK, [...] allerdings habe ich da auch meistens noch Code, der nicht bei allen Typen vorhanden ist, und das läßt sich ja leider nicht auf so eine Weise einbinden.

Was hältst Du von einem Parameter, dem Du die auszusparenden bzw. zu verwendenen Klassen angibst?
Delphi-Quellcode:
SetPropIfPossibleAndIsInstanceOf(Sender, [TButton, TPanel], 'Width', 200);
bzw
Delphi-Quellcode:
SetPropIfPossibleAndIsNotInstanceOf(Sender, [TEdit, TMemo], 'Visible', True);
Vielleicht sollte man das wirklich einmal in einer Unit zusammenfassen :gruebel:

himitsu 5. Dez 2003 12:16

Re: Gemeinsame OnClick - Behandlung
 
@choose,
das hört sich ja langsam nach einem Beitag für die CodeLib an.



Zitat:

OK, [...] allerdings habe ich da auch meistens noch Code, der nicht bei allen Typen vorhanden ist, und das läßt sich ja leider nicht auf so eine Weise einbinden.
Mit diesem Satz meinte ich aber Code, der nicht mit dem Objekt selbst in Verbindung steht.

z.B. wird mal eine Prozedur oder andere Codezeilen nur abgearbeitet, wenn das Ereignis von einem Button ausgelöst wird, aber nicht, wenn es von einer CheckBox kommt ...

http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif

Doc F 7. Dez 2003 00:16

Re: Gemeinsame OnClick - Behandlung
 
Hi, Leute,

hier fühl ich mich wohl, ihr seid lustig !

Sorry, das ich mich jetzt erst wieder melde, hab flach gelegen.
Hier stehen ja wirklich viel tolle Sachen die einem Anregungen liefern, aber im Prinzip trifft alles nicht das, was ich eigentlich wollte, nämlich mit einem Button-Click div. andere Buttons steuern. Nehmen wir als Beispiel mal den DBNavigator, den ich nicht mag. Oder zwei identische Buttonleisten, die zwei verschieden Audioquellen steuern sollen.
Ich hab mich gerade ein wenig in Datenbanken eingearbeitet, und brauchte zwei DBNavigatoren.
Wie gestagt, die sind blöd, denn ich bin Designfreak und wollte es mir vorbehalten, wohin ich welchen Button setzte. Schön und gut, ist ja kein Problem und am Anfang hab ich auch erst mal schön für jeden Button seine eigen OnClick-Routine geschrieben und Ruck-Zuck ein ellenlangen QuälText :shock: gehabt, der meinen Augen fürchterlich missfiel und ausserdem schrecklich unübersichtlich war, deswegen meine Frage mit der einen (Na ja, bei mir sind schlussendlich dann vier geworden, der Übersichtlickkeit halber) Event-Routine.

Hier nun meine Lösung zur Diskussion (wie schon vorher geschrieben, waren gleich am Anfang von diesem Forumsbeitrag ein paar gutte Tips dabei):

Delphi-Quellcode:
const
// NavButton enabled Status

  nbNextLast    = 3; // binär 1100
  nbNewDel      = 6; //   "  0110
  nbStoreCancel = 9; //   "  1001
  nbFirstPrior  = 12; //   "  0011
  nbNoBtn       = 15; //   "  1111

  NavBtnNames : Array[1..8] of ShortString =
    ('BtnFirst', 'BtnPrior', 'BtnNext', 'BtnLast', 'BtnNew',
     'BtnStore', 'BtnCancel', 'BtnDel');

procedure TForm2.NavBtnClick(Sender: TObject);
var
  BtnAction, BtnID : String;
  BtnNr, NavGroup : Integer;
begin
  BtnAction := TSpeedButton(Sender).Hint;
  BtnID := IntToStr(TSpeedButton(Sender).Tag);
  NavGroup := StrToInt(BtnID[1]);
  BtnNr := StrToInt(BtnID[2]);
  case BtnNr of
    1    : SetNavBtn(NavGroup, nbFirstPrior, BtnNr);
    2..3 : SetNavBtn(NavGroup, nbNoBtn, BtnNr);
    4    : SetNavBtn(NavGroup, nbNextLast, BtnNr);
    5    : SetNavBtn(NavGroup, nbNewDel, BtnNr);
    6..8 : SetNavBtn(NavGroup, nbStoreCancel, BtnNr);
  end;
  DoBtnAction(NavGroup, BtnNr);
end;

function TForm2.GetComponentID(CoName : String) : Integer; // <-- Worum's mir eigentlich ging
var
  comp : TComponent;
begin
  comp := TComponent(FindComponent(CoName));
  result := comp.ComponentIndex;
end;

procedure TForm2.SetNavBtn(NavGroup, BtnState, BtnNr : Integer);
var
  comp : TComponent;
  compId, mask, i : Integer;
begin
  case BtnNr of
    1..4 : begin
             for i := 0 To 3 do
             begin
               compID := GetComponentID(NavBtnNames[i+1] +
                                          IntToStr(NavGroup));
               mask := 1 shl i;
               TSpeedButton(Components[compID]).enabled :=
                                          (BtnState AND mask) = mask;
             end;
           end;
    5..6 : begin
             for i := 0 To 3 do
             begin
               compID := GetComponentID(NavBtnNames[i+5] +
                                          IntToStr(NavGroup));
               mask := 1 shl i;
               TSpeedButton(Components[compID]).enabled :=
                                          (BtnState AND mask) = mask;
             end;
           end;
  end;
  if NavGroup = 1 then SetNavBtn(2, nbFirstPrior, 1);
end;

procedure TForm2.DoBtnAction(NavGroup, BtnNr : Integer);
begin
  case NavGroup of
    1 : ..

    // Anweisungsblock

  end;
end;
Ich hoffe, dieser lange Schrieb sprengt jetzt nicht das Forum.

Danke an alle für die Hilfe.

Doc F

[edit=Christian Seehase]Delphi-Tags korrigiert. Mfg, Christian Seehase[/edit]

Doc F 7. Dez 2003 00:19

Re: Gemeinsame OnClick - Behandlung
 
Ups, sorry, meine Formatierungen sin im Nirwana verschwunden. Keine Absicht.

Doc F

mr2 7. Dez 2003 17:58

Re: Gemeinsame OnClick - Behandlung
 
Hallo,

ich glaube für Dein Problem sind Actions am besten geeignet.
Einfach eine ActionList auf das Formular ziehen.
Dann per Doppelclick auf die ActionList den ListEditor öffnen und über den kleinen schwarzen Pfeil links oben eine neue Standardaktion einfügen. Jetz nach unten scrollen und unter der Rubrik DataSet TDataSetFirst, TDataSetNext etc. auswählen. In der Action kannst Du dann einstellen für welche DataSource die Action zuständig ist.
Anschließend einfach dem oder den entsprechenden Button(s) die Action als Action zuweisen.

Und schon hast Du erreicht was Du wolltest und das ohne eine Zeile Code zu schreiben.

mr2

Doc F 8. Dez 2003 20:55

Re: Gemeinsame OnClick - Behandlung
 
Hallo mr2,

Prima, danke für den Tipp, funzt ja prima. Na ja, wenigstens hab ich bei meinem Versuchen einiges gelernt.

Jetzt nur noch eine Frage (hoffe ich):

Da gibt es zwar Aktion DatSetInsert, aber nix für append. (Hät ich aber gerne ... :wall: )
Und ausserdem funzt des zwar für für Datenbanke, aber nicht zB. für meinen momentan auf Eis gelegt Audio-Player.

Kann ich da irgendwie Standarteinträge selbst erzeugen ? Hab mich schon drin versucht, mir ist aber noch nicht so ganz klar, was ich dazu alles brauch. (Nebenbei bemerkt, Objektvererbung is schon toll, sonst müsste man das ja kpl. neu schreiben).

Vielleicht hat da jemand für eine vom

Delphi-Quellcode:
Type
  TProgramiere = MöchtegernHobbyProgrammierer(Class)
noch ne verständliche Antwort parat.

Danke

Doc F

mr2 9. Dez 2003 20:12

Re: Gemeinsame OnClick - Behandlung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
Zitat:

Zitat von Doc F
Delphi-Quellcode:
Type
  TProgramiere = MöchtegernHobbyProgrammierer(Class)

soll vermutlich
Delphi-Quellcode:
type
  TProgramierer = class(TMoechtegernHobbyProgrammierer)
bedeuten :lol:

Aber nun zu Deinem eigentlichen Problem.
Insert und Append sind prinzipiell identisch und führen nur bei Paradox oder ähnlich veralteten Datenbanken zu unterschiedlichen Ergebnissen. Du kannst natürlich trotzdem Deine eigene ActionKlasse schreiben:
Delphi-Quellcode:
type
  TDataSetAppend = class(TDataSetInsert)
  public
    procedure ExecuteTarget(Target: TObject); override;
  end;

implementation

procedure TDataSetAppend.ExecuteTarget(Target: TObject);
begin
  GetDataSet(Target).Append;
end;
Ich weiß nicht welche Erfahrungen Du bisher mit selbstgeschriebenen Komponenten hast.
Jedenfalls muss die Action in Delphi registriert werden. Im Anhang siehst Du wie das am besten gemacht wird (Datei U_MyActionsReg.pas). Das Beispiel ist für Delphi 6 und muss für Versionen darunter vermutlich angepass werden.
Einfach die Datei MyActions.dpk in Delphi öffnen und die Schaltfläche "Installieren" betätigen.
Weitere Hilfe findest Du auch in der Delphi-Hilfe unter "Komponentenentwicklung".

Viel Erfolg.

mr2

Doc F 9. Dez 2003 20:36

Re: Gemeinsame OnClick - Behandlung
 
Hallo mr2,

Super, jetzt wird programmiert, bis die (System-)Fetzen fliegen. :party:

Übrigens hattest du recht mit Paradox, aber irgendwo muß man ja anfangen. Und da ich keine Client-Server-Datenbanken zu schreiben gedenke, sondern einfach nur 'just for fun' oder zum eigenen Bedarf Programme schreibe, reicht das ja (für den Anfang). Welche Datenbank würdet ihr den für den Hausgebrauch empfehlen ?

Danke

Doc F

PS. Hab meinem PC mal ne neue Tastatur gegönnt, die vielen fehlenden Buchstaben sind ja schon
peinlich. Merke: Tastatur + Cola = Autsch!!!

mr2 15. Dez 2003 18:50

Re: Gemeinsame OnClick - Behandlung
 
Hallo,

also was die Datenbank angeht, habe ich mit Access (per ADO) angefangen, um später auf Interbase, Oracle & MS SQL-Server zu wechseln. Interbase & die MSDE (das ist die Light-Version des SQL-Servers) kann man problemlos auf dem eigenen Rechner installieren - bei Oracle ist das etwas komplizierter :)
Aber such' doch mal im Forum nach Hier im Forum suchenWelche Datenbank da findest Du jede Menge Antworten.

CU mr2


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:45 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz