![]() |
TCollection = not TCollection ?
Erst mal vorab habe noch keine Erfahrungen mit TCollection in Delphi gesammelt.
Erst mal was code
Delphi-Quellcode:
Ich enumeriere alle Komponente die sich in der Anwendung befinden.
for ICtrl := 0 to FParentObj.ComponentCount - 1 do
begin Ctrl := FParentObj.Components[ICtrl]; sCtrl := Ctrl.ClassName; If (sCtrl = 'TComboBox') or (sCtrl = 'TComboBoxEx') or (sCtrl = 'TDBLookupCombo') or (sCtrl = 'TDriveComboBox') then begin CtrHwnd := FindWindowEx(FParentObj.Handle, 0, PWideChar(sCtrl), nil); end; end; Da ich nicht ohne weiteres an das Handle der Combo komme hole ich es unter verwendung von FindWindowEx erst ein. Nun möchte ich dieses einer Collection hinzufügen. (erste bzw. Aktuelle Idee) Aber eine TCollection in Delphi kennt keine Identifikationsnummer bei der verwendung von Add Ist es überhaupt sinnvoll dafür TCollection zu verwenden?Oder einfach über ne einfache Liste..
Delphi-Quellcode:
Ich wollte quasi die Combos anhand der Nummer später identifizieren.
CtrlType: TCollection;
CtrlType.Add(1, CtrHwnd);// <<< schade geht nicht! gruss |
AW: TCollection = not TCollection ?
TCollection lohnt sich hauptsächlich dafür, wenn sie zu einer Komponente gehört deren Kindelemente ebenfalls im OI bearbeitet werden sollen.
|
AW: TCollection = not TCollection ?
Zitat:
Das ist auch noch eins meiner problem da ich ja so ohne weiteres nicht an die Hintergrundfarbe komme bzw.. setzen kann. Daher wollte ich über TCollection gehen um die Eigenschaften der Combo verändern zu können. So wie ich gelesen habe beinhalten diese ja selbst Collection ... oder hab ich da was falsch verstanden? So wie hier von Luckie schon gesagt Zitat:
gruss |
AW: TCollection = not TCollection ?
Kann es sein, dass du das mit Property-Editoren verwechselst?
Beispiel Property-Editor: TForm.Color Beispiel Collection: TListView.Columns |
AW: TCollection = not TCollection ?
Zitat:
Manchmal wenn ich eine Idee habe und diese nicht umsetzbar ist (Delphi) vergleiche ist das schon mal gerne mit meiner Muttersprache (VB) Hehehehee.... :thumb: :) Meine also nicht den Property Editor. Was eine Collection ist ist mir also schon klar. Aber so wie es ausschaut macht es dann wohl keinen sinn :? Muss diese idee dann wohl verwerfen. Danke. gruss |
AW: TCollection = not TCollection ?
Kann es sein, dass du eigentlich eine Hashmap/Dictionary suchst? Neuere Delphi-Versionen mit Generics haben glaube ich von Haus aus eine Implementierung dabei (TDictionary wenn ich mich nicht irre), bei älteren Versionen musst du selbst was basteln oder finden (von mir schwirrt hier im Forum glaube ich auch noch eine Hashmap herum).
|
AW: TCollection = not TCollection ?
Zitat:
Hab mir gestern mal ein handbuch mit TDictionary von Embarcadero runtergeladen wurde aber nicht so recht schlau daraus. EDIT: Hmm ..
Delphi-Quellcode:
procedure Add(const Key: TKey; const Value: TValue);
Sieht danach aus als wenn es das ist was ich suche bzw. umsetzen möchte. Muss mich noch schlau machen wie das funktioniert. Von dir habe ich leider nichts gefunden gruss |
AW: TCollection = not TCollection ?
TCollection.Add erzeugt eine neue Instanz von der Klasse, die du beim TCollection.Create angegeben hast.
|
AW: TCollection = not TCollection ?
Zitat:
|
AW: TCollection = not TCollection ?
Zitat:
![]() |
AW: TCollection = not TCollection ?
Delphi-Quellcode:
Und falls auch die Nachfahren der Kombonenten mit erwischt werden sollten, dann
for ICtrl := 0 to FParentObj.ComponentCount - 1 do
begin Ctrl := FParentObj.Components[ICtrl]; If (Ctrl = TComboBox) or (Ctrl = TComboBoxEx) or (Ctrl = TDBLookupCombo) or (Ctrl = TDriveComboBox) then begin CtrHwnd := FindWindowEx(FParentObj.Handle, 0, PChar(Ctrl.ClassName), nil); end;
Delphi-Quellcode:
statt
is
Delphi-Quellcode:
.
=
PS: Zitat:
oder FindWindowExW + PWideChar + WideString/UnicodeString PSS: ![]() |
AW: TCollection = not TCollection ?
Zitat:
Delphi-Quellcode:
.
Ctrl.Classtype=...
Delphi-Quellcode:
ist aber sauberer imo.
is
|
AW: TCollection = not TCollection ?
Zitat:
gruss |
AW: TCollection = not TCollection ?
Zitat:
Um was geht's ? Ich bekomme bei meiner abfrage das korrekte Handle. und das geht gar nicht.
Delphi-Quellcode:
Dann müßte ich nämlich die Controls bzw.. dazugehörige Units mit einbinden.
for ICtrl := 0 to FParentObj.ComponentCount - 1 do
begin Ctrl := FParentObj.Components[ICtrl]; If (Ctrl = TComboBox) or (Ctrl = TComboBoxEx) or (Ctrl = TDBLookupCombo) or (Ctrl = TDriveComboBox) then begin CtrHwnd := FindWindowEx(FParentObj.Handle, 0, PChar(Ctrl.ClassName), nil); end; Ich befinde mich in einer DLL und die Controls in der Anwendung. gruss |
AW: TCollection = not TCollection ?
Zitat:
Delphi-Quellcode:
uses
Generics.Collections; |
AW: TCollection = not TCollection ?
na gut hast mich überzeugt :)
gruss |
AW: TCollection = not TCollection ?
usp, ja
Delphi-Quellcode:
or
Ctrl.ClassType = TIrgendwas
Delphi-Quellcode:
PS: Nur weil Klassen den gleichen Namen haben, müssen sie nicht die selben Klassen-Deklarationen besitzen.
Ctrl is TIrgendwas
Geh mal raus und frage so lange, bis du einen "Frank" gefunden hast ... mit etwas Glück bin ich das. |
AW: TCollection = not TCollection ?
Zitat:
Ist bestimmt bekannter zumindest nicht 1 zu ner million bis ich dich finde. Komme auf keinen grünen zweig da ich nicht auf die Objekte der Form direkt zugreifen kann. gruss |
AW: TCollection = not TCollection ?
Es handelt sich doch um Komponenten einer Form der eigenen Anwendung?
Wenn ja, dann siehe PSS in #11. PS: Von Delphi automatisch erzeugt form haben immer Application als Owner, weswegen sie sich auch über Application.Components finden lassen. Alle anderen delphieigenen TopLevel-Forms sind nochmal über Screens.Forms aufzufinden. Ach ja, die Variante über den ClassType hat noch den vorteil der Quellcodevervollständigung, beim Schreiben der Namen und das Ganze wird dann auch nochmal über den Kompiler validiert, wärend man sich bei den Strings nur mal verschreiben braucht (sei es uch nur in der Groß-/Kleinschreibung) und schon wird der Vergleich schnell Mal was von FALSE behaupten. Abgesehn davon, daß ein Integervergleich ein klein bissl optimaler ist, als ein Stringvergleich. |
AW: TCollection = not TCollection ?
Zitat:
Die werden in einer DLL ausgewertet. Das bereitet probleme. Sagte ja schon ich sende SELF aber das was in Self(eigene Anwendung) steht kommt in der DLL nicht an. Dann wäre es alles kein problem. So wie hier von Luckie schon gesagt Zitat:
EDIT: Zitat:
gruss. |
AW: TCollection = not TCollection ?
"self" ist auch nur ein Pointer auf die aktuelle Instanz, im eigenen Adressraum. Für die DLL ist das, bestenfalls, ungültiger Speicher, oder eben zufällige Daten im Irgendwo.
|
AW: TCollection = not TCollection ?
Zitat:
Wenn ich self übergebe habe ich ja das gültige Handle der Anwendung aber nicht die Komponenten dieser. Und sag mir nicht das wäre jetzt irgendein handle.. Die kann ich schon vergleichen :) Ich glaube da muss ich langsam passen Oder aber die Komponenten direkt übergeben wie bei der Scrollbar wenn es anders nicht geht. Das gleich in VB sind 4 Zeilen dann habe ich alles was ich brauche. Übersetzung von Delphi nach VB
Code:
Und schon habe ich zugriff auf alle Objekte die sich auf der Form befinden.
Public Property Get ParentObj() As Object
Dim TempObj As Object If m_ParentObj = 0 Then Set ParentObj = Nothing Else CopyMemory TempObj , m_ParentObj, 4 Set ParentObj = TempObj CopyMemory TempObj, 0, 4 End If End Property Warum ist das nur sooooo kompliziert in Delphi. PS: Aber wir kommen vom Thema ab. ;) gruss |
AW: TCollection = not TCollection ?
sorry push..
Bei der Übergabe der Combobox direkt funktioniert es aber ich will alle gleichzeitig verarbeiten können. Warum geht das nicht? Das will ich vermeiden
Delphi-Quellcode:
und an stelle dessen!
ComboHook := HookedCombo_Create;
if assigned(ComboHook) then begin ComboHook.ComboImg := ScrbMemoHook.CreateImageFromFile(FilePath + 'ScrollBarSkin\Combo.png'); ComboHook.FrameColor := $FCAC65; ComboHook.FrameHighLite := $FFE9D6; ComboHook.SetComboParentObj(ComboBox1); ComboHook.Connect; end; ComboHook2 := HookedCombo_Create; if assigned(ComboHook2) then begin ComboHook2.ComboImg := ScrbMemoHook.CreateImageFromFile(FilePath + 'ScrollBarSkin\Combo.png'); ComboHook2.FrameColor := $FCAC65; ComboHook2.FrameHighLite := $FFE9D6; ComboHook2.SetComboParentObj(ComboBox2); ComboHook2.Connect; end;
Delphi-Quellcode:
ComboHook := HookedCombo_Create;
if assigned(ComboHook) then begin ComboHook.ComboImg := ScrbMemoHook.CreateImageFromFile(FilePath + 'ScrollBarSkin\Combo.png'); ComboHook.FrameColor := $FCAC65; ComboHook.FrameHighLite := $FFE9D6; ComboHook.SetComboParentObj(self); ComboHook.Connect; end; verwenden um alle Comboboxen der Anwendung innerhalb der DLL zu enumerieren/verwalten.. |
AW: TCollection = not TCollection ?
Sekunde... Wessen self übergibst du, und warum ist das auf einmal ein Handle? :gruebel: Wenn du nicht gerade eine BPL (statt DLL) hast, und keinen Speicher rummappst, dann hast du in der DLL keinerlei Zugriff auf den Adressraum deiner Anwendung, und folglich auch keinen auf die Dinge, die die VCL so inne hat. Es mag sein, dass VB hier implizit mit COM Interfaces hantiert, so dass das alles rosig ausschaut, aber so ein Kissen hast du in Delphi nicht - zumindest nicht von Hause aus. Du könntest bestenfalls das (tatsächliche) Windows-Handle deines Formulares übergeben, und mittels FindWindowsEx() (also nackter WinAPI) die ChildControls durchgehen und an diesen, wiederum mit nackter WinAPI, Dinge tun. Aber die hübsche VCL Sicht wirst du so ohne Weiteres nicht in deine DLL geschoben bekommen.
Mir fehlt aber generell ein wenig "Vorarbeit" zu dem, was hier so insgesamt überhaupt alles passiert. DLL ist ja auch nicht immer gleich DLL. Hier scheint nen Hook zu sein, derer es auch wieder verschiedene Arten gibt. Was, wie, wer und vor allem gegen wen? :) |
AW: TCollection = not TCollection ?
Also wenn ich hier ein Self übergebe
Delphi-Quellcode:
ComboHook.SetComboParentObj(self);
Ist es für mich ersichtlich das es sich nur um die MainForm handeln kann. Da auf dieser die ganzen Komponenten aufgesetzt sind.
Delphi-Quellcode:
Das ParentHandle wäre also dann FParentObj.Handle
procedure THookedCombo.SetComboParentObj(Ctrl: TWinControl);
begin FParentObj := Ctrl; end; Mit diesem hole ich mir dann die Handles der auf self(MainForm) befindlichen Comboboxen über FindWindowExW Aber wie gesagt es kommt nur die Hälfte von Self in der DLL an. Das will irgendwie keiner so richtig verstehen was ich meine. Zitat:
Will ich auch nicht sondern nur das was in der Liste von Self steht :) Du siehst aber das es geht ansonsten würdest du die Bitmaps nicht in den Comboboxen sehen können. (Ohne Hook) gruss |
AW: TCollection = not TCollection ?
Dann nimm eben keine DLL, sondern eine BPL.
Schon hast du überall die gleiche RTTI, den gleichen Speichermanager und diesbezüglich keinerlei Probleme mehr. |
AW: TCollection = not TCollection ?
Zitat:
Und habe auch keinerlei erfahrung damit. gruss |
AW: TCollection = not TCollection ?
Zitat:
Self ist kein Handle, sondern Idendisch mit z.B. dem, was ein TMyClass.Create() zurück liefert, und somit einfach eine Adresse auf den Heap, der wiederum im für nur deinen gerade aktiven Prozesses gemappten Speicher liegt, wo von aussen (ohne Tricks) keiner dran kommt. DLLs bekommen ihren eigenen Heap zugewiesen, und kommen an den der benutzenden Applikation nicht dran, ausser man kümmert sich von Hand darum, ooooder nutzt BPLs, wo sich ein von Delphi mit geliefertes "Framework" automatisch darum kümmert. Ohne dies kennt die DLL die Struktur hinter dem gelieferten Pointer nicht (TForm ist eine Klasse der VCL, und all ihre Felder liegen ebenfalls im Adressraum der Anwendung), und selbst wenn man TForm der DLL bekannt machen würde und darauf casted, ist es noch immer ein ungültiger Pointer auf zufällige Daten im Adressraum der DLL. Du musst zwischen Pointern und Handles unterschieden, ich glaube daher kommt deine Verwirrung. Das ist bei der VCL auch etwas gemischt, da hier Windows-Controls, die ein Systemhandle haben, mit VCL-eigenen Properties und Methoden gekapselt wird. Man kommt also via VCL Methoden (TForm.XXX()) ran, als auch über WinAPI Funktionen (SetWindowLong(MyForm.Handle, ...)). Erstere Möglichkeit fällt eben weg, wenn du den Adressraum deiner Anwendung verlässt. |
AW: TCollection = not TCollection ?
Ich habe das jetzt verworfen und übergebe die Komponenten direkt.
Delphi-Quellcode:
Die Funktion ist dadurch gegeben wenn auch nicht so elegant wie ich es ursprünglich implementieren wollte.
for IComb := 0 to Form1.ComponentCount - 1 do
begin Ctrl := Form1.Components[IComb]; sCtrl := Ctrl.ClassName; If (sCtrl = 'TComboBox') or (sCtrl = 'TFilterComboBox') or (sCtrl = 'TDriveComboBox') then begin ComboHook := HookedCombo_Create; if assigned(ComboHook) then begin ComboHook.SetComboParentObj(TWinControl(Ctrl)); ComboHook.ComboImg := ScrbMemoHook.CreateImageFromFile(FilePath + 'ScrollBarSkin\Combo.png'); ComboHook.FrameColor := $FED3AC; ComboHook.FrameHighLite := $666666; ComboHook.FrameStyle := FrameFlat; ComboHook.Connect; end; end; end; Danke für deine Erklärungen. PS: Zitat:
Wenn es so ist wie du sagst. Müßte die Übergabe so wie sie jetzt von statten geht das gleiche sein. So.. Dann erkläre mir mal warum ich hier die richtigen Handles bekomme ? Wenn dem nicht so wäre würden sich die Bitmaps ja auf Irreguläre Positionen setzen und keinerlei Events der Button funktionieren. Auch hier bin ich außerhalb des Adressraums meiner Anwendung;) gruss gruss |
AW: TCollection = not TCollection ?
Zitat:
Wenn man sie statisch läd, dann braucht man nichtmal die Prozeduren/Funktionen exprotieren/importieren ... macht alles Delphi für einen. Man indet nur über Uses die Units ein, welche man möchte und sobald die Anwendung mit Laufzeitpackages kompiliert wird und dieses Package mit angegeben wurde, dann werden die Units nicht mehr in die EXE eingebunden, sondern werden nur automatisch mit der BPL verlinkt. |
AW: TCollection = not TCollection ?
Zitat:
![]() Was eine DLL angeht, so müsstest du als Parameter auch Interfaces, z.B. abgeleitet von IUnknown, übergeben können. Denn die werden via COM verwaltet. Also so ca., ungetestet:
Delphi-Quellcode:
library xyz;
uses MyInterface; procedure DoIt(AObject: ITest); stdcall; begin MessageBox(0, AObject.GetMsg, 'test', MB_ICONINFORMATION or MB_OK); AObject.ShowMsg('Hallo'); end; exports DoIt;
Delphi-Quellcode:
Benutzung:
unit MyInterface;
interface type ITest = interface(IUnknown) procedure ShowMsg(Value: PWideChar); stdcall; function GetMsg: PWideChar; stdcall; procedure SetMsg(Value: PWideChar); stdcall; end;
Delphi-Quellcode:
uses
MyInterface; type TTest = class(TInterfacedObject, ITest) private FTest: string; public procedure ShowMsg(Value: PWideChar); stdcall; function GetMsg: PWideChar; stdcall; procedure SetMsg(Value: PWideChar); stdcall; end; procedure DoIt(AObject: ITest); stdcall; external 'xyz.dll'; implementation function TTest.GetMsg: PWideChar; begin Result := PWideChar(FTest); end; procedure TTest.SetMsg(Value: PWideChar); begin FTest := Value; end; procedure TTest.ShowMsg(Value: PWideChar); begin ShowMessage(Value); end;
Delphi-Quellcode:
Vielleicht hilft dir das ja dabei das so zu kapseln oder so. ;-)
var
Test: ITest; begin Test := TTest.Create; Test.SetMsg('Hallöchen'); DoIt(Test); Test := nil; // explizite Freigabe, nur nötig, wenn sonst der Scope zu groß wäre // EDIT: Also ich denke da an so etwas wie ein Interface, das du der DLL übergibst und das in der Anwendung die Daten abruft und in Interface-Objekten der DLL liefert ;-) |
AW: TCollection = not TCollection ?
Danke für eure Infos werde es mir mal anschauen.
gruss |
AW: TCollection = not TCollection ?
Statt dem PWideChar kann man im Interface auch WideString nehmen, denn dieses wird auch über das COM-Zeugs verwaltet.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz