![]() |
Ich finde keine ChildHandles beim TSaveDialog ...
Ich versuche nun schon eine ganze weile irgendwie an das Handle das Filename-Edit des Savedialogs zu kommen...
Ich habe es mit dieser unit versucht: ![]() wlist.EnumChildWindows(SaveDialog1.Handle); liefert jedoch immer nichts... es werden einfach keine Childs gefunden... P.S.: Ich hab auch schon div. andere Beispielcodes getestet, alle mit dem gleichen Effekt :gruebel: |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Such dir mit einem Tool die ID des Edits und dann benutzt du
![]() |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Zitat:
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
:oops: jetzt hab ich die ID doch mit XSpy gefunden :) ...
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
:x Zu früh gefreut...
Das Handle bekomme ich trotz ItemId nicht :roll:
Delphi-Quellcode:
wnd := GetDlgItem(SaveDialog1.Handle, 1148);
if wnd <> 0 then begin showmessage(IntToStr(wnd)); end; |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
hast du schon mal geschaut welchen Wert das Handle deines SaveDialogs hat? Ich hab mal das ganze mit dem Opendialog probieren wollen und musste feststellen das, das Handle vom Dialog 0 war.
Es kommt also darauf an, zu welchem Zeitpunkt du das ganze versuchst zu performane. Wenn du es zum Beispiel im OnShow des Dialogs machst ist ein Handle vorhanden, wenn der Dialog jedoch nicht mehr eingeblendet ist, so ist auch das handle wieder 0. |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Mein SaveDialog hat ein Handle, denn ich mache das ganze OnSelectionChange ;)
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
habs grad beim probieren mitbekommen das es irgendwie bei mir auch nicht geht. Was mir aber auch aufgefallen ist - das handle von Dialog.Handle ist nicht das gleiche Handle wie das des sichtbaren Dialog-Fensters.
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Hallo,
Mein WinSpy liefert folgenden Code und findet das File Name Edit:
Delphi-Quellcode:
var
wnd: HWND; begin wnd := FindWindow('#32770',nil); // oder was auch immer... wnd := FindWindowEx(wnd, 0, 'ComboBoxEx32', nil); wnd := FindWindowEx(wnd, 0, 'ComboBox', nil); wnd := FindWindowEx(wnd, 0, 'Edit', nil); if wnd <> 0 then begin // ....gefunden! end; end. Edit: Ansonsten mal hier schauen: ![]() |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
@toms: Zum problem wird es nur wenn es noch einen weiteren Dialog gibt, denn dann ist nicht mehr sicher das man auch den eigenen findet. Daher finde ich den Lösungsversuch über das Handle des Dialogs zu gehen bedeutend besser.
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
So, jetzt hab ich die verschiednen Tips kombiniert und hab die IMHO beste Lösung gewfunden ;)
Delphi-Quellcode:
Der Vorteil wenn man über die ItemID geht liegt darin, dass man jetzt sogar die Captions der Buttons und Labels ändern kann ;)
wnd := FindWindow('#32770',PChar(SaveDialog1.Title));
wnd := GetDlgItem(wnd, 1148); if wnd <> 0 then begin showmessage('// ....gefunden!'); end; |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
@Frifra: Wer sagt dir aber dass, das handle was dir findwindow zurück gibt auch wirklich von deinem dialog ist und nicht das handle eines fensters aus einer anderen anwendung?
wenn ich folgendes auf meinem Rechner ausführe bekomme ich 4 handles in meiner Listbox was also auch heißt das es 4 Fenster mit dem Classname gibt. Somit wäre deine Variante nicht sehr zuverlässig.
Delphi-Quellcode:
bei der variante von Toms ist es auch nicht anders, da kann es ganauso passieren das man entweder kein handle zurück bekommt oder das von einem anderen dialog.
var LHandle: Cardinal;
LStr: PChar; begin LStr := StrAlloc(255); LHandle := FindWindow('#32770', nil); while (LHandle <> 0) do begin GetClassName(LHandle, LStr, 254); if LStr = '#32770' then ListBox1.Items.Add(inttostr(LhANDLE)); LHandle := GetWindow(LHandle, GW_HWNDNEXT); end; StrDispose(LStr); end; Wenn du das ganze wie folgt erweiterst kannst du wenigstens sicherstellen dass, das gefundene Fenster zu deiner Anwendung gehört:
Delphi-Quellcode:
var LHandle: Cardinal;
LStr: PChar; begin LStr := StrAlloc(255); LHandle := FindWindow('#32770', nil); while (LHandle <> 0) do begin GetClassName(LHandle, LStr, 254); if LStr = '#32770' then begin if GetWindow(LHandle, GW_OWNER) = Application.Handle then EnumChildWindows(LHandle, @EnumProc, 0); end; LHandle := GetWindow(LHandle, GW_HWNDNEXT); end; StrDispose(LStr); end; |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Zitat:
Delphi-Quellcode:
Ich hab aber gerade festgestellt, das es beim Überschreiben der Buttoncaptions Probleme gibt...
wnd := FindWindow('#32770',PChar(SaveDialog1.Title));
Delphi-Quellcode:
Mache ich das ganze im onShow, wird die Caption von Windows sofort wieder überzeichnet... lagere ich das ganze in einen Timer mit kurzem Interval aus, so hat mam bei jeder Dateiauswahl (-> Neuzeichnen des gesamten Dialoges) ein "lustiges Blinkespiel", weil jedesmal wieder kurz die Originalcaption zu sehen ist :roll:
var
wnd: HWND; Tmp: string; Buffer: array[0..MAX_PATH] of Char; n: integer; begin wnd := FindWindow('#32770', PChar(SaveDialog1.Title)); wnd := GetDlgItem(wnd, 1); if wnd <> 0 then begin GetWindowText(wnd, Buffer, MAX_PATH); Tmp := 'Teest'; if StrPas(Buffer) <> Tmp then SetWindowText(wnd, PChar(Tmp)); end; |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
reicht es nicht das du einmal die caption setzt und dann den timer abschaltest?
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Nein, sobald man z.B. eine Datei auswählt, werden alle Buttoncaptions neu gezeichnet... natürlich wieder mit den originalwerten :x
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
da du die handles der Buttons hast könntest du die Windowproc umlenken und die messages zum setzen der Caption einfach verwerfen
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Und wie mach ich das?
Wenn ich das hinbekäme könnte ich endlich mal alle Captions der Standardialoge ändern, was für mehrsprachige Anwendungen sehr gut ist ;) |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
komich, ich hab grad mal die buttoncaption für "öffnen" geändert und diese wurde nicht zurück geändert als ich eine Datei gewählt habe oder den Ordner gewechselt. Wie man die Windowproc umbiegt - ich bastels mal schnell zamm
[Edit] So wirds gemacht
Delphi-Quellcode:
in der NewWindowProc kannst du dann wm_settext verwerfen bzw. abändern
//variable für die alte windowproc
var GOldProc: function(AHandle: Cardinal; uMsg: Cardinal; AWPARAM: wParam; ALPARAM: lParam): LResult; Stdcall; //unsere neue Windowproc function NewWindowProc(AHandle: Cardinal; uMsg: Cardinal; AWPARAM: wParam; ALPARAM: lParam): LResult; Stdcall; begin result := GOldProc(AHandle, uMsg, AWParam, ALParam); end; [...] //umbiegen auf neue windowproc und sichern der alten für inherited call Integer(@GOldProc) := SetWindowLong(LHandle, GWL_WNDPROC, Integer(@NewWindowProc)); [...] |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Bei "Integer(@NewWindowProc)" kommt bei mir immer der Fehler "Variable erforderlich"...
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
dann versuch mal ob es geht wenn du das "@" wegmachst, unter d5 ging es ohne "@" wenn ich mich recht entsinne, mein Delphi7 hingegen meckert rum. Ansonsten kannst du den Cast auch um den anderen Teil machen (also auf den Proceduretype casten)
also so:
Delphi-Quellcode:
type
TWindowproc = function(AHandle: Cardinal; uMsg: Cardinal; AWPARAM: wParam; ALPARAM: lParam): LResult; Stdcall; [...] var GOldProc: TWindowProc; [...] GOldProc := TWindowProc(SetWindowLong(LHandle, GWL_WNDPROC, Integer(@NewWindowProc))); |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
|
Re: Ich finde keine ChildHandles beim TSaveDialog ...
also in meinem D2005 funktionierts. Hier mal die komplette unit:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TWindowproc = function(AHandle: Cardinal; uMsg: Cardinal; AWPARAM: wParam; ALPARAM: lParam): LResult; TForm1 = class(TForm) Button1: TButton; SaveDialog1: TSaveDialog; procedure Button1Click(Sender: TObject); procedure SaveDialog1Show(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} var GOldProc: TWindowProc; function NewWindowProc(AHandle: Cardinal; uMsg: Cardinal; AWPARAM: wParam; ALPARAM: lParam): LResult; Stdcall; begin result := GOldProc(AHandle, uMsg, AWParam, ALParam); end; procedure TForm1.SaveDialog1Show(Sender: TObject); begin GOldProc := TWindowProc(SetWindowLong(SaveDialog1.Handle, GWL_WNDPROC, Integer(@NewWindowProc))); end; procedure TForm1.Button1Click(Sender: TObject); begin SaveDialog1.Execute(); end; end. |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Liste der Anhänge anzeigen (Anzahl: 2)
Ist schon pracktisch solch ein Thema zu finden, welches gleich in doppelter Hinsicht passt :)
eigentlich wollte ich ja erst sowas sagen,
Delphi-Quellcode:
aber inzwischen hat sich hier einiges geändert, bei mir funktionier das mit dem Übersetzen auch ganz gut und ich benötige dafür nur eine Zeile ^^
Ich würde mal versuchen rauszubekommen, wie das z.B. Notepad macht, denn der hat auch seine eigene Beschriftung und ohne das es flackert.
Bei meinem Notepad steht [b]Dateiname[/b] und [b]Dateityp[/b], aber in den originalen Open-/Save-Dialogen steht bei mir [b]Objektname[/b] und [b]Objekttyp[/b] (im SaveDialog allerdings [b]Dateityp[/b] :gruebel: )
Delphi-Quellcode:
Im Brunde bräuchtet ihr euch nur in den ExplorerHook des Dialogs einschalten, bei Msg = WM_NOTIFY und POFNotifyExW(LParam)^.hdr.code = CDN_INITDONE.
SendMessageW(GetDlgItem(hWnd, 1), WM_SETTEXT, 0, Integer(PChar('abc123')));
Oder, wenn's reicht ins onShow-Ereignis (wird über's ExplorerHook aufgerufen). Ich persönlich hab hier meinen eigenen ExplorerHook, daher isses wohl etwas einfacher :mrgreen: Zu dem Handle-Problem: Dat hab'sch aus'm MSDN - das über GetOpenFileName/GetSaveFileName-Fenster enthält seit Win2K/NT vermutlich sowas wie ein Explorer-Fenster, welches wohl jetzt die WindowsMessages an den ExplorerHook versendet, muß also erst das Handle auf das Dialog-Fenster geholt werden. Zitat:
Delphi-Quellcode:
das richtige Fenster, mit den gesuchten Controls, herran.
hWnd := GetParent(hWnd);
Ach ja, hab auch etwas gebraucht und diese Fenster bisher entziffert. (bis auf 0 und 1088 ... keine Ahnug was das ist)
Code:
Und Luckie ... WinSight hilft irgendwie auch nicht viel weiter :gruebel:
#32770 DialogName
0 ? 1 Öffnen-Button 2 Abbrechen-Button 1038 Hilfe-Button 1040 Schreibgeschützt-CheckBox 1088 ? 1089 Typ-Label 1090 Dateiname-Label 1091 SuchenIn-Label 1120 Datei-ListBox 1136 Typ-Edit 1137 SuchenIn-ComboBox 1148 Dateiname-Edit 1184 PlacesBar bei mir hat das nur die beiden SuchenIn-Controls entdeckt :gruebel: (hab dann einfach mal in 'ner Schleife eines per GetDlgItem testen lassen) |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
So, die letzten Contros wurden endlich entschlüsselt :)
Code:
#32770 » DialogName
0 » OpenDialog-ClientBereich 1 » Öffnen-Button 2 » Abbrechen-Button 1038 » Hilfe-Button 1040 » Schreibgeschützt-CheckBox 1088 » Control-Butons (at top-right) 1089 » Typ-Label 1090 » Dateiname-Label 1091 » SuchenIn-Label 1120 » Datei-ListBox 1136 » Typ-Edit 1137 » SuchenIn-ComboBox 1152 » Dateiname-Edit 1184 » PlacesBar |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Gleiches Problem ... neue Ursache :shock:
Dachte erst ich hätte mich beim Dateiname-Edit (ID 1148) verschrieben, aber als ich jetzt wieder daheim weiterproggen wollte ging es plötzlich nicht mehr (falsche ID), also nochmal gesucht und siehe da, ich hatte es richtig aufgeschrieben nur da ist es die ID 1152 :wall: Also ich hab für das selbe Editfeld bisher 2 IDs (WinXP mit und ohne SP) Wie soll ich denn jetzt vorgehen ... kann ja schließlich nicht alle IDs, für alle Windowsversionen ermitteln und dann die passende verwenden? :stupid: Es ist zwar einfach an alle IDs der vorhanden Controls ranzukommen, aber wie kann ich mit Sicherheit feststellen welche ID welches Control darstellt? |
Re: Ich finde keine ChildHandles beim TSaveDialog ...
Zitat:
Aber zumindestens hab ich inzwischen alles so hinbekommen, daß jetzt die meißten Beschriftungen über ResourceStrings geladen und erfolgreich gesetzt werden (solange die DlgItemIDs stimmen) Drüben der entsprechende QuellCode ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:47 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