Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Objecte zwischenspeichern (https://www.delphipraxis.net/120779-objecte-zwischenspeichern.html)

EWeiss 16. Sep 2008 14:51


Objecte zwischenspeichern
 
Hab ein problem mit dem auffinden meiner auf ein DesignerPanel gelegten Objecte

Wie kann man die am besten zwischenspeichern damit man sie wiederfindet wenn man drauf klickt?

irgendwie stoße ich da an meine grenzen ..
Finden kann ich sie über meine Node im TreeView aber
wenn ich ein anderes anklicke auf den Panel ändert sich der eintrag im TreeView ja nicht

Addiere ich die zu einer Stringlist bringt das auch nichts da ich nur den Namen
vom eintrag im TreeView der Liste hinzu füge um das Object zu identifizieren.

Wenn ich auf ein Object klicke könnte ich zwar den gespeicherten namen im TreeView suchen
dazu muss ich aber in der Funktion die Node initialisieren und die liegt ja bekanntlich noch auf
dem alten eintrag.

Drehe mich da irgendwie im Kreis.

gruss Emil

HenKst 16. Sep 2008 15:04

Re: Objecte zwischenspeichern
 
Ich hab ja jetzt nicht genau verstanden was du meinst, aber guck dir mal TTreenode.Data an :)

EWeiss 16. Sep 2008 15:20

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von HenKst
Ich hab ja jetzt nicht genau verstanden was du meinst, aber guck dir mal TTreenode.Data an :)

Es geht nicht um das TreeView sondern um die Objecte welche ich auf mein DesignerPanel lege.
Diese muss ich wenn ein klick drauf erfolgt identifizieren können.
Mein Problem ist mit fällt nicht ein mit was.

TreeView fällt flach da der eintrag sich nicht von alleine neu selektiert wenn ich nicht weis welches
Object angeklickt wurde.

gruss EMil

HenKst 16. Sep 2008 15:32

Re: Objecte zwischenspeichern
 
Was legst du denn für Objecte drauf?
Wenn die ein Onclick haben sollte der meist auch einen Sender haben. Da steht der Pointer aufs Object eindeutig drin.

EWeiss 16. Sep 2008 15:49

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von HenKst
Was legst du denn für Objecte drauf?
Wenn die ein Onclick haben sollte der meist auch einen Sender haben. Da steht der Pointer aufs Object eindeutig drin.

Der ist mir nicht bekannt weil das object zur laufzeit erstellt wird.

Delphi-Quellcode:
procedure TMainForm.JvDesignPanelSelectionChange(Sender: TObject);
snip..

end;
Ich lege 3 objecte drauf .. 2 TImages und ein TLabel
Wird diese funktion aufgerufen und das object nicht hundertpro identifiziert
hat dies zur folge das falsche werte des objects die nicht enthalten sind in den Inspector addiert werden.
Dann kommt es zur Fehlermeldung.

Beispiel TLabel hat kein Bitmap
Habe ich also zuletzt ein Image addiert dann übergebe ich dessen eigenschaften auf das Label wenn ich das Object nicht richtig identifiziert habe.
Das führt unweigerlich zum crash.

gruss Emil

nahpets 16. Sep 2008 17:24

Re: Objecte zwischenspeichern
 
Hallo,

schau Dir mal die TypInfo.pas aus \Delphi\Source\Rtl\Common an, eventuell enthält die Funktionen, mit denen Du den Type ermitteln kannst oder zumindest prüfen kannst, ob es ein bestimmtes Attribut oder eine bestimmte Methode gibt.

Stephan

EWeiss 16. Sep 2008 18:00

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von nahpets
Hallo,

schau Dir mal die TypInfo.pas aus \Delphi\Source\Rtl\Common an, eventuell enthält die Funktionen, mit denen Du den Type ermitteln kannst oder zumindest prüfen kannst, ob es ein bestimmtes Attribut oder eine bestimmte Methode gibt.

Stephan

HI Stefan
Werd mal schaun hab die Unit ja schon eingebunden
Glaube aber nicht das mir das bei meinen Problem hilft...

gruss Emil

nahpets 17. Sep 2008 09:11

Re: Objecte zwischenspeichern
 
Hallo Emil,

könnte Dir das helfen?

Delphi-Quellcode:
{ Die Funktion prüft, ob die übergebene Klasse ein Attribut mit dem angege-    }
{ benen Namen hat.                                                            }
Function HasProperty(AClass : TObject; APropertyName : String) : Boolean;
Var
         MyPropInfo : PPropInfo;
Begin
  MyPropInfo := GetPropInfo(AClass.ClassInfo, APropertyName);
  Result := MyPropInfo <> NIL;
End;
PPropInfo wird in TypInfo definiert.

Über die TypInfo sollte es Dir gelingen, eine vollständige Dokumentation Deiner Klassen/Objekte zu erstellen. Es ist allerdings etwas kryptisch.

Delphi-Quellcode:
GetPropInfos(AClass.ClassInfo, PropList);
liefert Dir eine Liste aller Properties, hier kannst Du z. B. den Typ abfragen

Delphi-Quellcode:
PropList[i]^.PropType^.Kind
über

Delphi-Quellcode:
GetPropValue(AClass,PropList[i]^.Name,True)
bekommst Du den der Eigenschaft zugewiesenen Wert, ohne die Klasse/das Objekt zu kennen.

Schau doch einfach mal da http://www.montefiore.ulg.ac.be/~lat...unitsse82.html, ob Du was brauchbares findest, eventuell hilft Dir auch das http://www.swissdelphicenter.ch/torr...de.php?id=1084 weiter.

Stephan

EWeiss 17. Sep 2008 10:02

Re: Objecte zwischenspeichern
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke dir das sind auf jedenfall verwertbare informationen

Ich versuche nochmal mein problem zu schildern.
Ich hab festgelegte Elemente das wären
Delphi-Quellcode:
TCAVEElementType = (stBackground, stText, stButton, stNone);
TCAVEElementTotals: array[TCAVEElementType] of Integer;
Beim ersten start der Anwendung geht erst mal nix ohne das VST(TreeView)

Beim klick auf den Eintrag Background wird diese Funktion aufgrufen
Delphi-Quellcode:
procedure TMainForm.PaletteStdButtonClick(Sender: TObject);
var
  Data : PTreeData;
  Node : PVirtualNode;

const
  cClasses: array[0..1] of string = ('TImage', 'TLabel');

begin

  StickyClass := (GetKeyState(VK_SHIFT) < 0);

  // Selectierte Node Initialisieren
  Node := FSkinTree.GetFirstSelected;
  Data := FSkinTree.GetNodeData(Node);

  // Hole die Data.Category vom Top Level der ausgewählten Node
  Data.Category := SkinManagerInterface.GetSelectedCategory(FScreensObj, FSkinTree);

  // Objecte angzeigen abhängig vom Index des cClasses Array
  case Data.Category of
    stBackground:
      // TImage
      DesignClass := cClasses[0];
    stText:
      // TLabel
      DesignClass := cClasses[1];
    stButton:
      // TImage
      DesignClass := cClasses[0];
  end;


end;
Der Toplevel des gewählten Eintrag wird nun gesucht und das Element zugewiesen
Delphi-Quellcode:
function TCAVESkinManager.GetSelectedCategory(ScreensObj: TStringList; TreeView: TBaseVirtualTree): TCAVEElementType;
var
  Node: PVirtualNode;
  Data: PTreeData;
  IntI: Integer;

begin
  Node := TreeView.GetFirstSelected;

  // Bestimme die Kategorie für den ausgewählten Knoten
  while (Node <> nil) and (TreeView.GetNodeLevel(Node) > 1) do
    Node := Node.Parent;

  Data := TreeView.GetNodeData(Node);
  if Data <> nil then
    for IntI := 0 to ScreensObj.Count - 1 do
      if ScreensObj.Strings[IntI] = Data.FCaption then
        Data.Category := TCAVEElementType(IntI);

    Result := Data.Category;
end;
ScreensObj ist die Stringlist in der die Knoten beim start zugewiesen wurden
abhängig vom Elementtyp um diesen über den VST zu Identifizieren.
Klicke ich nun in das Panel wird das Object abhängig vom ELementTyp auf dem abgelegt.
In dem Fall TImage.

Wenn nun alle Objecte abgelegt und ich auf irgendeins davon klicke muss ich vergleichen können
welches das ist und zwar abhängig vom ElementType da es sonst unweigerlich zum crash kommt.
Das geht aber in dem Fall nicht über das TreeView.
Und das ist mein problem hab keine Idee wie oder wo ich da abfangen soll :wall:
welches object das ist um den ElementTyp korrekt zuweisen zu können.

Ja ist schwer zu erklären ;)
Wie kann ich also die aofgesetzen objecte sinnvoll zwischenspeichern
damit ich sie wieder finde ?
Zitat:

TStringList ?
Classe ?
Oder wie sonst ..am besten mit allen geänderten eigenschaften damit diese auch gleich
wieder im Inspector aktualisiert werden.

gruss Emil

nahpets 17. Sep 2008 10:29

Re: Objecte zwischenspeichern
 
Hallo Emil,

ich versteh' das nicht:

Heißt das, Du hast hier Dein Problem?

Delphi-Quellcode:
procedure TMainForm.JvDesignPanelSelectionChange(Sender: TObject);
bumm???
end;
Dann müsstest Du für meine Begriffe mit Hilfe der TypInfo herausbekommen können, was denn da bitte jetzt genau in Sender steckt.

Hiermit solltest Du z. B. herausbekommen, in welcher Unit Deine Klasse definiert ist:
Delphi-Quellcode:
{ Die Funktion liefert den Namen der Unit, in der die übergebene Klasse defi-  }
{ niert wurde.                                                                }
function GetUnitName(AClass : TObject) : String;
var
  ClassTypeInfo : PTypeInfo;
  ClassTypeData : PTypeData;
begin
  ClassTypeInfo := AClass.ClassInfo;
  ClassTypeData := GetTypeData(ClassTypeInfo);
  Result       := ClassTypeData.UnitName;
end;
Das sollte Dir eine Liste der Vorfahren Deiner Klasse bringen:
Delphi-Quellcode:
{ Die Prozedur ermittelt die Vererbungsstruktur des übergebenen Objektes und  }
{ gibt die Struktur in der Stringliste zurück.                                }
procedure GetClassAncestry(AClass: TObject);
var
  AncestorClass : TClass;
begin
  AncestorClass := AClass.ClassParent;
  { Iteriert durch die Parentklassen, beginnend mit dem übergebenen Objekt,   }
  { bis kein Vorfahre mehr vorhanden ist.                                     }
  GlobaleStringListe.Add('Class Ancestry');
  while AncestorClass <> nil do begin
    GlobaleStringListe.Add(AncestorClass.ClassName));
    AncestorClass := AncestorClass.ClassParent;
  end;
end;
Es müsste doch damit und ggfls. weiteren Funktionen möglich sein, herauszubekommen, was für ein Objekt da jetzt ankommt und zu entscheiden, das nehme ich oder das nehme ich nicht an oder das behandle ich so oder eben anders oder auch garnicht.

Wenn Du nun nur TImage und TLabel hast, müsste doch ein

Delphi-Quellcode:
If HasProperty(Sender, 'Picture') Then
anstelle von "bumm???" reichen, um festzustellen, ob es ein TImage ist oder nicht? Oder bin ich hier momentan auf dem falschen (Rhein)-Dampfer.

Stephan

HenKst 17. Sep 2008 10:48

Re: Objecte zwischenspeichern
 
:wiejetzt:
Wo werden die Objecte denn Kreiert/Platziert?
Da kannst doch auch zur Laufzeit die OnClick events und eine eindeutige Identifizierung (z.B. im tag) zuweisen.

Dann machst du im OnClick sowas wie
Delphi-Quellcode:
if (sender as TComponent).tag = PusteKuchen then begin
  add(Pustekuchen);
end;
und feddich;

Oder hab ich irgendwie total verpennt worums hier geht? :gruebel:

EWeiss 17. Sep 2008 10:51

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von HenKst
:wiejetzt:
Wo werden die Objecte denn Kreiert/Platziert?
Da kannst doch auch zur Laufzeit die OnClick events und eine eindeutige Identifizierung (z.B. im tag) zuweisen.

Delphi-Quellcode:
if (sender as TControl).tag = PusteKuchen then begin
  add(Pustekuchen);
end;
Oder hab ich irgendwie total verpennt worums hier geht? :gruebel:

Wie soll ich den Tag zuweisen wenn das object noch nicht existiert
das wird doch zur Laufzeit erstellt und über die ElementType (gleichzusetzen mit Tag)
Identifiziert aber nur vom TreeView und nicht wenn ich drauf klicke.

gruss Emil

EWeiss 17. Sep 2008 10:59

Re: Objecte zwischenspeichern
 
Hallo Stefan

Delphi-Quellcode:
procedure TMainForm.JvDesignPanelSelectionChange(Sender: TObject);
bumm??? 
end;
Nein hier ...
Delphi-Quellcode:
procedure TMainForm.AddControls(ATree : TBaseVirtualTree; aCtrl: TControl; DisplayName: string);
var
  Data    : PTreeData;
  Node    : PVirtualNode;
  UIObject : TCAVEUIObject;
begin


  UIObject  := TCAVEUIObject.Create;

  Node := ATree.GetFirstSelected;
  Data := ATree.GetNodeData(Node);

  case SkinManagerInterface.ActiveScreen of
    skSplash:
    begin

    case Data.Category of
      stBackground:
      begin
        // zeigt das ausgewählte Object TImage im FInspector
        UIObject.ShowSelProperties(FInspector,aCtrl,
          ['Autosize' ,'Width', 'Height', 'Picture'], 'Background Picture');
        // zeigt Object Informationen im FInspector an
        UIObject.ShowUserObjectInfo(FInspector, FCAVEUserObject, 'Identity');
      end;
      stText:
      begin
        // zeigt das ausgewählte Object TLabel im FInspector
        UIObject.ShowSelProperties(FInspector,aCtrl,
          ['Autosize' ,'Width', 'Height',
           'Left', 'Top', 'Alignment', 'Font', 'Transparent'], 'Text');
        // zeigt Object Informationen im FInspector an
        UIObject.ShowUserObjectInfo(FInspector, FCAVEUserObject, 'Identity');
      end;
      stButton:
      begin
        // zeigt das ausgewählte Object TImage im FInspector
        UIObject.ShowSelProperties(FInspector,aCtrl,
          ['Left', 'Top', 'Width', 'Height', 'Center', 'Picture'], 'Button Picture Strip');
          Data.Image := TImage(aCtrl);
        // zeigt Object Informationen im FInspector an
        UIObject.ShowUserObjectInfo(FInspector, FCAVEUserObject, 'Identity');
      end;
     end;
     FCAVEUserObject.Name := Data.FCaption;
  end;

  end;

  // addiere Control ClassName und Name zur ComboBox
  cbObject.items.add(aCtrl.Name + ': ' + aCtrl.ClassName);

end;
und zwar dann wenn die falsche Category übergeben wird
Die kann ich aber nur auslösen bzw.. finden wenn der richtige Knoten im Tree aktiviert ist.
Ich kann den aber nicht aktivieren da ich ihn nicht kenne wenn ich auf ein object klicke.

gruss Emil

HenKst 17. Sep 2008 11:06

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von EWeiss

Wie soll ich den Tag zuweisen wenn das object noch nicht existiert
das wird doch zur Laufzeit erstellt und über die ElementType (gleichzusetzen mit Tag)
Identifiziert aber nur vom TreeView und nicht wenn ich drauf klicke.

gruss Emil

Und warum nicht?
Erstellst du das Object nicht selbst?

Ich muss zugeben ich bin durch deinen Code nicht ganz durchgestiegen ;)

EWeiss 17. Sep 2008 11:12

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von HenKst
Zitat:

Zitat von EWeiss

Wie soll ich den Tag zuweisen wenn das object noch nicht existiert
das wird doch zur Laufzeit erstellt und über die ElementType (gleichzusetzen mit Tag)
Identifiziert aber nur vom TreeView und nicht wenn ich drauf klicke.

gruss Emil

Und warum nicht?
Erstellst du das Object nicht selbst?

Hmm einen zusätzlichen Tag zu addieren sehe da keinen Sinn drin
da meine objecte über die Elemente identifiziert werden was macht das für einen
unterschied ob das nun über ein Array oder einen Tag geschieht.

Zitat:

Ich muss zugeben ich bin durch deinen Code nicht ganz durchgestiegen
Warum zu schlecht zu verstehen ? ;)
Ist doch dokumentiert was wo geschieht und welche aktionen ausgeführt werden.

Mein problem ist halt die schlechte Dokumentation (oder keine) von den Jedi Komponenten
Muss mir alles aus den Units saugen um zu verstehen was da abgeht
das funktioniert aber nicht immer wenn man die eigenschaften nicht kennt.

gruss Emil

HenKst 17. Sep 2008 11:26

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von EWeiss
Hmm einen zusätzlichen Tag zu addieren sehe da keinen Sinn drin
da meine objecte über die Elemente identifiziert werden was macht das für einen
unterschied ob das nun über ein Array oder einen Tag geschieht.

Der Unterschied ist dass der Tag eindeutig zu einem Object gehört.
Wenn du also nach dem Kreieren(da weisst du ja hoffentlich noch um welches Element es grade geht^^) einen Tag und ein OnClick zuweist, weisst du über den Tag immer genau welches object du grade hast.
Du kannst ja auch den ElementType ins Tag schreiben ;)
Ein weiterer Vorteil vom Tag ist, dass den fast alles hat was nicht direkt von TObject abgeleitet ist. Den gibts von TComponent abwärts :)
Zitat:

Zitat von EWeiss
Warum zu schlecht zu verstehen ? ;)
Ist doch dokumentiert was wo geschieht und welche aktionen ausgeführt werden.

Mein problem ist halt die schlechte Dokumentation (oder keine) von den Jedi Komponenten
Muss mir alles aus den Units saugen um zu verstehen was da abgeht
das funktioniert aber nicht immer wenn man die eigenschaften nicht kennt.

gruss Emil

Mein problem ist halt dass ich die Jedi Komponenten garnicht kenne:)
Darum ist für mich nicht klar wo die Elemente kreiert werden.

EWeiss 17. Sep 2008 11:38

Re: Objecte zwischenspeichern
 
Zitat:

HenKst: Du kannst ja auch den ElementType ins Tag schreiben
Das wäre eine möglichkeit werd es mal versuchen
Die frage nur was mache ich wenn ich unter stBackgound( Bitmap) mehrere Dateien stehen habe
dann hab ich den Typ aber immer noch nicht das Object(Image1, Image2 usw..).

Ist also nicht so einfach.

gruss Emil

HenKst 17. Sep 2008 11:56

Re: Objecte zwischenspeichern
 
Auf die schnelle fällt mir da ein record ein den du in den Tag schreibst.

Delphi-Quellcode:
TEnumTypeInfo = record
  TypeInfo: PTypeInfo;
  Index: Integer;
end;
Im TypeInfo steht die TypeInfo(wow...) und im Index der index des jeweiligen Elements.
Könntest dir dann nen globalen Zähler machen der immer incrementiert wird wenn ein Image kreiert wird.
Ich behaupte das wäre immernoch praktischer als ein array dessen indizes du nicht weisst^^

EWeiss 17. Sep 2008 12:18

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von HenKst
Auf die schnelle fällt mir da ein record ein den du in den Tag schreibst.

Delphi-Quellcode:
TEnumTypeInfo = record
  TypeInfo: PTypeInfo;
  Index: Integer;
end;
Im TypeInfo steht die TypeInfo(wow...) und im Index der index des jeweiligen Elements.
Könntest dir dann nen globalen Zähler machen der immer incrementiert wird wenn ein Image kreiert wird.
Ich behaupte das wäre immernoch praktischer als ein array dessen indizes du nicht weisst^^

Hmmm ;)
Gut gemeinter Ratschlag was soll ich damit machen?
Bekomme dann nur das Kind übergeben was mir aber nichts bringt.

Delphi-Quellcode:
type
  TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,
    tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,
    tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray);
Trotzdem Danke..

Gruss Emil

nahpets 17. Sep 2008 12:22

Re: Objecte zwischenspeichern
 
Hallo Emil,

einen hab ich noch :wink:

Es besteht wohl ein Konflikt zwischen

Delphi-Quellcode:
procedure TMainForm.AddControls(ATree : TBaseVirtualTree; aCtrl: TControl; DisplayName: string);
und
Delphi-Quellcode:
Node := ATree.GetFirstSelected;
Data := ATree.GetNodeData(Node);
aCtrl muss nicht zwingend identisch sein mit dem selektierten Node.

Also ein Versuch:

Den Baum und seine Knoten von oben her durcharbeiten und suchen, welcher Node vom gleichen Typ wie aCtrl ist. Diesem Node den Fokus geben, dann sollte es gehen.

Hierüber könnte es doch möglich sein, die Objekte zu vergleichen, wenn eine IF-Kaskade mit IS und AS nicht ausreicht:
Delphi-Quellcode:
{ Die Prozedur ermittelt Basis-Laufzeit-Informationen zum übergebenen Objekt  }
{ und gibt die Informationen in einer Stringliste zurück.                     }
procedure GetBaseClassInfo(AClass: TObject);
var
  ClassTypeInfo : PTypeInfo;
  ClassTypeData : PTypeData;
  EnumName     : String;
begin
  ClassTypeInfo := AClass.ClassInfo;
  ClassTypeData := GetTypeData(ClassTypeInfo);
  with sl Do Begin
    Add(Format('Class Name:    %s ', [ClassTypeInfo.Name]));
    EnumName := GetEnumName(TypeInfo(TTypeKind), Integer(ClassTypeInfo.Kind));
    Add(Format('Kind:          %s ', [EnumName]));
    Add(Format('Size:          %d ', [AClass.InstanceSize]));
    Add(Format('Defined in:    %s.pas ', [ClassTypeData.UnitName]));
    Add(Format('Num Properties: %d ',[ClassTypeData.PropCount]));
  End;
end;
Wenn hier der Typ festgestellt werden kann, müsste (über ein entsprechendes Cast?) ja auch der Name des Objektes zu finden sein, um das dann im Tree zu selektieren.

Wenn nicht, dann weiß ich auch nicht weiter :cry:

Stephan

EWeiss 17. Sep 2008 12:30

Re: Objecte zwischenspeichern
 
Danke schön werd es mal testen und bescheid geben ob ein Erfolg zu verzeichnen ist.

gruss Emil

EWeiss 17. Sep 2008 17:27

Re: Objecte zwischenspeichern
 
Hab jetzt eine lösung gefunden na ja nicht das aller beste aber es funktioniert
Dank an HenKst hab es mit dem Tag und unter Hilfe von Stephan doch noch geschaft.

Delphi-Quellcode:
function TCAVESkinManager.GetSelectedCategory(ObjectList: TStringList; TreeView: TBaseVirtualTree; Obj: TObject): TCAVEElementType;
var
  Data       : PTreeData;   // Zeiger auf die Structur
  SearchData : PTreeData;   // Zeiger auf die Structur
  Tag        : Integer;     // wird addiert zum Object wenn erstellt

begin
  // Daten zurücksetzen
  Data := nil;

  // raus hier wenn kein Tag im Object vorhanden
  if TControl(Obj).tag = 0 then
  begin
    Result := stNone;
    exit;
  end;

  New(SearchData);

  Tag := TControl(Obj).tag;
  // Index out of bound von ObjectList verhindern
  dec(Tag);

  begin
    // Caption übergeben ermittelt über ObjectList.Index
    // verglichen mit dem im Obj übergebenen Tag
    SearchData^.FCaption := ObjectList.strings[Tag];
    FFoundNode := nil;
    // Callback IterateSubTree aufrufen
    TreeView.IterateSubTree (nil, FSkinTreeCallBack, pointer(SearchData));
    // Eintrag gefunden .. CategoryNode zuweisen
    if Assigned(FFoundNode) then
    begin
      // Node an die class TCAVESkinManager übergeben
      CategoryNode := FFoundNode;
      // Structur Daten aktualisieren
      Data := TreeView.GetNodeData(CategoryNode);
    end;
  end;

  Result := Data.Category;

end;
Um nicht einen neuen Thread zu erstellen eine Frage hinterher ;)
Wie kann ich jetzt übergreifend für alle Obj ein MouseEvent übergeben
Das existiert ja nicht bei der erstellung zur Laufzeit.

übergreifend (für alle die gleiche)
Oder sollte man das aufteilen ?

gruss Emil

nahpets 18. Sep 2008 09:57

Re: Objecte zwischenspeichern
 
Hallo Emil,

hat Dein Objekt ein OnMouseDown?

Dann beim Erstellen des Objektes diesem Attribut eine Methode zuweisen. Die musst Du irgendwo implementieren, wievielen Objekten Du sie letztlich zuweist, ist dabei vollkommen schnuppe.

Sowas in der Art könnte Dir helfen:

Delphi-Quellcode:
type
  TfmMain = class(TForm)
...
    procedure miBerichteClick(Sender: TObject);
...
  private
...

implementation
...

procedure TfmMain.miBerichteClick(Sender : TObject);
Begin
  If Sender Is tMenuItem Then With Sender As tMenuItem Do Begin
    ShowMessage(Name + ' ' + Caption + ' ' + IntToStr(Tag));
  End;
End;

...

  Obj.Create(wieauchimmer);
...
  // Ereignisroutine zuweisen
  Obj.OnMouseDown := fmMain.miBerichteClick;
...
Stephan

EWeiss 18. Sep 2008 11:18

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von nahpets
Hallo Emil,

hat Dein Objekt ein OnMouseDown?

Dann beim Erstellen des Objektes diesem Attribut eine Methode zuweisen. Die musst Du irgendwo implementieren, wievielen Objekten Du sie letztlich zuweist, ist dabei vollkommen schnuppe.

Sowas in der Art könnte Dir helfen:

Delphi-Quellcode:
type
  TfmMain = class(TForm)
...
    procedure miBerichteClick(Sender: TObject);
...
  private
...

implementation
...

procedure TfmMain.miBerichteClick(Sender : TObject);
Begin
  If Sender Is tMenuItem Then With Sender As tMenuItem Do Begin
    ShowMessage(Name + ' ' + Caption + ' ' + IntToStr(Tag));
  End;
End;

...

  Obj.Create(wieauchimmer);
...
  // Ereignisroutine zuweisen
  Obj.OnMouseDown := fmMain.miBerichteClick;
...
Stephan

Super wie du mir bei meinen problemen hilfst ;)
Denk das kann ich genause für Move und Down verwenden lediglich das Click Event auf down und move verändern

gruss Emil

HenKst 18. Sep 2008 11:47

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von EWeiss
Denk das kann ich genause für Move und Down verwenden lediglich das Click Event auf down und move verändern

Versteh ich jetz nich.
Das OnClick kannst du doch genauso zuweisen.
Haben TPicture und TLabel, soweit ich mich erinnere, beide ;)

Zitat:

Dank an HenKst
biddeschön :D

EWeiss 18. Sep 2008 12:02

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von HenKst
Zitat:

Zitat von EWeiss
Denk das kann ich genause für Move und Down verwenden lediglich das Click Event auf down und move verändern

Versteh ich jetz nich.
Das OnClick kannst du doch genauso zuweisen.
Haben TPicture und TLabel, soweit ich mich erinnere, beide ;)

Zitat:

Zitat von "EWeiss
Dank an HenKst

biddeschön :D

ich meine so ;)
Delphi-Quellcode:
Obj.OnMouseDown := fmMain.miBerichteMouseDown;
Obj.OnMouseMove := fmMain.miBerichteMouseMove;
Obj.OnMouseUp := fmMain.miBerichteMouseUp;

procedure miBerichteMouseDown(Sender: TObject.. bla bla); //was halt noch zu dem Event MouseDown gehört
usw...

haben uns da wohl falsch verstanden ..

Gruss Emil

nahpets 18. Sep 2008 12:09

Re: Objecte zwischenspeichern
 
Hallo Emil,

nä, lieber nicht.
So würde beim Drücken der Maustaste das Ereignis ausgelöst, beim Festhalten und beim Loslassen.
Okay, aller Guten Dinge sind drei, aber hier ist das wohl übertrieben. Du musst schon entscheiden, wann die Anwendung des Ereignisses vom Programmablauf her sinnvoll ist.

Klickst Du eine Komponente an, um sie zu verschieben, muss das Ereignis eventuell noch nicht ausgelöst werden, sondern erst, wenn das Objekt an der neuen Stelle ist, weil Du z. B. seine neue Position wissen möchtest.
Wenn es sich um die TLabels und TImages handelt, dann ist eventuell auch die Benutzung von onDoubleClick sinnvoller, kommt halt auf die Aufgabe an.

Stephan

EWeiss 18. Sep 2008 12:31

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von nahpets
Hallo Emil,

nä, lieber nicht.
So würde beim Drücken der Maustaste das Ereignis ausgelöst, beim Festhalten und beim Loslassen.
Okay, aller Guten Dinge sind drei, aber hier ist das wohl übertrieben. Du musst schon entscheiden, wann die Anwendung des Ereignisses vom Programmablauf her sinnvoll ist.

Klickst Du eine Komponente an, um sie zu verschieben, muss das Ereignis eventuell noch nicht ausgelöst werden, sondern erst, wenn das Objekt an der neuen Stelle ist, weil Du z. B. seine neue Position wissen möchtest.
Wenn es sich um die TLabels und TImages handelt, dann ist eventuell auch die Benutzung von onDoubleClick sinnvoller, kommt halt auf die Aufgabe an.

Stephan

Nein, nein
Ich benötige diese ereignisse ;)
Jedoch nicht im Design mode wenn du ein object verschiebst oder änderst.
Nur wenn Preview eingeschaltet ist werden diese Events ausgelößt.

Ich prüfe also vorher im MouseMove oder anderen Event ob
Delphi-Quellcode:
JvDesignPanel.Active := Active1.Checked;
Ich brauche die teile da ich ein ImageStrip einlade das nachher mit den Events
geblittet wird.
Ich hoffe das es funktioniert :)

gruss Emil

EWeiss 19. Sep 2008 18:37

Re: Objecte zwischenspeichern
 
@Stephan

habe das mal getestet beomme aber das von dir benannte event nicht
weder onMouseMove ,Down noch ein anderes.

kann es also aObj nicht zuweisen.
Delphi-Quellcode:
procedure TCAVEUIObject.ShowSelProperties(Inspector: TJvInspector;
  aObj: TObject; Props: array of string; NodeText: string);
var
  i      : integer;
  Category: TJvInspectorCustomCategoryItem;

begin
  Inspector.Root.Clear;

  Category := TJvInspectorCustomCategoryItem.Create(Inspector.Root, nil);
  Category.DisplayName := NodeText;
  Inspector.Root.SortKind := iskNone;

  for i:=Low(Props) to High(Props) do
    TJvInspectorPropData.New(Category, aObj, GetPropInfo(aObj, Props[i]));

  if aObj.classname = 'TImage' then
    tmpImage := TImage(aObj);

  Category.Expanded := True;
end;
gruss Emil

HenKst 22. Sep 2008 12:24

Re: Objecte zwischenspeichern
 
Mal zum Verständis.

Du Rufst im OnMouseDown Event TCAVEUIObject.ShowSelProperties(bla, sender, bla,bla) auf?
Aber im Event kommst du garnicht erst an?

Parent und alles richtig gesetzt? (Das is meistens bei mir das problem wenn objecte nicht da sind^^)

Ich habs grade getestet und hab(nachdem ich dann endlich auch den parent richtig gesetzt hatte :D ) wunderbar ein zur laufzeit erzeugtes TImage übers Onclick wieder gefreet, indem ich den sender im OnMouseDown einer free prozedur übegeben habe.

Wüsste also nicht wieso das bei dir nicht klappen sollte.
Es sei denn du hast halt den Parent nicht gesetzt^^
Vielleicht ist dir das ja nicht aufgefallen.
TImage und TLabel sind ja beide nicht zu sehen solange nichts drin ist :D

EWeiss 22. Sep 2008 12:47

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von HenKst
Mal zum Verständis.

Du Rufst im OnMouseDown Event TCAVEUIObject.ShowSelProperties(bla, sender, bla,bla) auf?
Aber im Event kommst du garnicht erst an?

Parent und alles richtig gesetzt? (Das is meistens bei mir das problem wenn objecte nicht da sind^^)

Ich habs grade getestet und hab(nachdem ich dann endlich auch den parent richtig gesetzt hatte :D ) wunderbar ein zur laufzeit erzeugtes TImage übers Onclick wieder gefreet, indem ich den sender im OnMouseDown einer free prozedur übegeben habe.

Wüsste also nicht wieso das bei dir nicht klappen sollte.
Es sei denn du hast halt den Parent nicht gesetzt^^
Vielleicht ist dir das ja nicht aufgefallen.
TImage und TLabel sind ja beide nicht zu sehen solange nichts drin ist :D

Du weist sicherlich das ich das obj zur Laufzeit erstelle.
Im code kann ich aber das Event nicht zuweisen da es innerhalb der IDE nicht bekannt ist
weil kein reales TImage oder TLabel sich auf der Form befindet.

Wie kann ich also aObj ein event zuweisen das innerhalb der IDE nicht bekannt ist ?

gruss Emil

HenKst 22. Sep 2008 12:59

Re: Objecte zwischenspeichern
 
Genauso wie du es getan hast.
Delphi-Quellcode:
Object.Event:= meinEvent;
Ob sich ein Object auf dem Form graphisch platziert, oder zur Laufzeit erzeugt wurde ist dabei doch egal.

Was heisst "weil kein reales TImage oder TLabel sich auf der Form befindet." ?

Nach
Delphi-Quellcode:
 aObj:= TImage.Create(owner);
sind die Objekte so real als hättest du sie von Hand in der IDE platziert.
Der einzige unterschied ist das sie noch nicht dargestellt werden.
Das musst du natürlich dann im Code machen.
Wichtig ist dabei halt den Parent nicht zu vergessen, sonst werden sie nicht gezeichnet und kriegen auch keine events mit.

EWeiss 22. Sep 2008 13:07

Re: Objecte zwischenspeichern
 
Zitat:

Zitat von HenKst
Genauso wie du es getan hast.
Delphi-Quellcode:
Object.Event:= meinEvent;
Ob sich ein Object auf dem Form graphisch platziert, oder zur Laufzeit erzeugt wurde ist dabei doch egal.

Was heisst "weil kein reales TImage oder TLabel sich auf der Form befindet." ?

Nach
Delphi-Quellcode:
 aObj:= TImage.Create(owner);
sind die Objekte so real als hättest du sie von Hand in der IDE platziert.
Der einzige unterschied ist das sie noch nicht dargestellt werden.
Das musst du natürlich dann im Code machen.
Wichtig ist dabei halt den Parent nicht zu vergessen, sonst werden sie nicht gezeichnet und kriegen auch keine events mit.

Werd das nochmal überprüfen danke für die Infos.

gruss Emil


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:14 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