![]() |
Anderem Program den Fokus übergeben
Guten Abend,
ich habe aktuell das Problem, dass ich gerne dem Fenster, welches vor meiner Anwendung den Fokus hatte, den Fokus wieder zurück geben würde. Gibt es dazu eine Möglichkeit? Vielen Dank schonmal im Vorraus! |
AW: Anderem Program den Fokus übergeben
Hallo, ich würde mir mit
![]() ![]() Da vielleicht auch mit ![]() Hilft Dir das weiter? Ps: Das "merken" würde ich in der .dpr Datei gleich hinter "Begin" machen und das "setzen" nachdem Deine Forms erstellt sind, falls es Vcl ist. |
AW: Anderem Program den Fokus übergeben
Schwierig ist der Teil "merken Welches Programm vorher den Fokus hatte". Wenn man das Handle dieses Fensters hat, reicht
Delphi-Quellcode:
Ich weiss allerdings nicht, wie man das vorher aktive Programm ermittelt. Evtl. einfach beim Start das Fenster im Vordergrund ermitteln? Oder vielleicht das, welches unter dem eigenen Fenster liegt?
GetWindowThreadProcessId(OtherHandle, pid);
if pid = 0 then begin LogInfo('Process Id for Windows ' + _WndClass + ' not found'); Exit; end; Res := AllowSetForegroundWindow(pid); if not Res then begin LogInfo('AllowSetForegroundWindow for ' + _WndClass + ' failed'); Exit; end; Res := SetForegroundWindow(OtherHandle); if not Res then LogInfo('SetForegroundWindow for ' + _WndClass + ' failed'); |
AW: Anderem Program den Fokus übergeben
Also das mit dem ermitteln ist ein klacks.
Delphi-Quellcode:
.
if GetParent(GetForegroundWindow) = 0 then lHwnd := GetForegroundWindow else lHwnd := GetParent(GetForegroundWindow);
Diese Zeile in .dpr gleich hinter begin einfügen. In der MainForm das hier einfügen
Delphi-Quellcode:
So funktioniert es genau so wie der TE es wollte.
var
FormX: TFormX; lHwnd: HWND; ... procedure TFormX.FormActivate(Sender: TObject); begin if not Win32Check(SetForegroundWindow(lHwnd)) then mmo1.Lines.Add('SetForegroundWindow failed'); end; |
AW: Anderem Program den Fokus übergeben
Zitat:
Du weist doch gar nicht welcher Prozess den Focus hat und ob das Handle das du einholst das des Aktiven Fensters ist. Es kann genauso gut auch das eines Button des aktiven Fensters sein wenn dieser in der anderen Anwendung den Focus hat. Ich würde so vorgehen. GetForegroundWindow GetWindowThreadProcessId AttachThreadInput (true) GetFocus AttachThreadInput (false) Die lösung von @dummzeuch ist schon näher dran ;) Was das mit dem GetParent soll müsstest du mir mal näher erläutern. ;) Aber gut macht mal ;) gruss |
AW: Anderem Program den Fokus übergeben
Hab eine funktionierende Variante geupdatet. Man könnte noch einen Test einfügen ob man DesktopHandle erwischt hat aber ansonsten macht es alles was der TE wollte.
Bitte teste und überzeuge Dich selbst, Danke. edit GetParent stellt sicher das ich kein Control erwische sondern ein Fensterhandle. |
AW: Anderem Program den Fokus übergeben
Zitat:
Danke nein ich möchte es nicht testen ich weis wie der richtige weg sein muss, aber streiten deswegen tue ich mich auch nicht. EDIT: Zitat:
Ok! Was willst du eigentlich erreichen du möchtest den Focus des aktiven Fensters. 1. Mit deiner Funktion wirst du nicht immer.. ich meine Immer den Focus des aktiven Fensters erhalten. 2. Was soll das?
Delphi-Quellcode:
if GetParent(GetForegroundWindow) = 0 then lHwnd := GetForegroundWindow else lHwnd := GetParent(GetForegroundWindow);
Entweder ich will den Focus der Anwendung oder nicht was soll also das
Delphi-Quellcode:
else lHwnd := GetParent(GetForegroundWindow);
Das ist nicht das gewünschte Resultat. Wenn also GetForegroundWindow 0 zurück liefert dann ist es eben so! Da gibt es kein "else" weil uninteressant! 3. Wenn du garantieren willst das der aktive Prozess ein garantiertes Window Handle zurück liefert dann musst du den jeweiligen Prozess Attachen tust du es nicht dann vergiss es einfach das andere ist nur Spielerei. gruss |
AW: Anderem Program den Fokus übergeben
Okay ich sehe meinen Fehler ein das diese Methode nicht 100% akkurat arbeitet, ich hätte es tiefer testen sollen, bei mir kam nur TC und WindowsExplorer bis jetzt in Frage da ichs in der Autostart-Abteilung verarbeitet habe. Nun dank dieses Buttons kann ich auch das testen.
Delphi-Quellcode:
edit
procedure TForm1.btn1Click(Sender: TObject);
var oldHWND: HWND; begin Hide; if GetParent(GetForegroundWindow) = 0 then oldHWND := GetForegroundWindow else oldHWND := GetParent(GetForegroundWindow); mmo1.Lines.Add('oldHWND: '+IntToStr(oldHWND)+' - '+IntToHex(oldHWND,8)); Show; end; 2. Was soll das? Mit der ersten Abfrage teste ich ob ich GetParent brauche oder ob GetForegroundWindow bereits das Parent (Hauptfenster) Window ist. Aber mit Deinen .exes funktioniert es so nicht da alles falsch ist. |
AW: Anderem Program den Fokus übergeben
Zitat:
Delphi-Quellcode:
else oldHWND := GetParent(GetForegroundWindow);
Ist unnötig! Zitat:
Bsp. Ein Button auf der Hauptform ist ein ChildWindow von diesem ist das Parent dein HauptFenster und was ist das Parent nun von diesen? Zitat:
Habe nur aufgezeigt wie der richtige weg ist es zwingt dich aber niemand das nachzuverfolgen :) Ok bin raus.. Wie ich schon sagte macht wie ihr wollt. gruss |
AW: Anderem Program den Fokus übergeben
Delphi-Quellcode:
Zumindest ist alles vom Rezept enthalten, bin auch am Ende damit.
procedure MySetForegroundWindow(Wnd: HWND);
var Attached: Boolean; ThreadId: DWORD; FgWindow: HWND; AttachTo: DWORD; begin { Emils Rezept verlangt GetForegroundWindow GetWindowThreadProcessId AttachThreadInput (true) GetFocus <- ich nahm SetFocus, mit GetFocus wusste ich nichts mit anzufangen, bitte um hilfe dabei AttachThreadInput (false) hoffentlich ist es so ok } Attached := False; ThreadId := GetCurrentThreadId; // unsere .exe FgWindow := GetForegroundWindow(); // aktuelles Foreground AttachTo := GetWindowThreadProcessId(FgWindow, nil); if (AttachTo <> 0) and (AttachTo <> ThreadId) then if AttachThreadInput(ThreadId, AttachTo, True) then begin Attached := Windows.SetFocus(Wnd) <> 0; // Focus setzen AttachThreadInput(ThreadId, AttachTo, False); // connect lösen end; if not Attached then begin SetForegroundWindow(Wnd); // SetForeground ausführen SetFocus(Wnd); // Focussieren end; end; |
AW: Anderem Program den Fokus übergeben
Ohne gewähr..
Nur getippt nicht getestet.
Delphi-Quellcode:
man könnte das ganze jetzt noch in einem Loop packen..
function GetFocusHandle: HWND;
var ForegroundHandle: HWND; PID: DWord; myThreadID: DWord; begin // Meine ThreadID myThreadID := GetCurrentThreadId; // Hole das Handle vom Top Level Vordergrund Window ForegroundHandle := GetForegroundWindow; // Process ID vom Vordergrund Window einlesen PID := GetWindowThreadProcessId(ForegroundHandle, nil); // diesen Thread und den fremden Thread zusammen fügen AttachThreadInput(myThreadID, PID, true); // Das Focus Handle Result := GetFocus; // Threads von einander trennen in dem ich beim dritten wert false übergebe AttachThreadInput(myThreadID, PID, false); end;
Delphi-Quellcode:
Nun solltest du mit SetFocus(FocusHwnd) den alten Stand wieder zurück setzen können.
doloop := not doloop;
repeat FocusHwnd := GetFocusHandle; application.ProcessMessages; Label1.Caption := IntToStr(FocusHwnd); Sleep(10) until doloop = false; Du kannst aber auch eine Procedure erstellen und verwendest dann anstelle von
Delphi-Quellcode:
Result := GetFocus;
Delphi-Quellcode:
SetForegroundWindow(ForegroundHandle);
Es muss sich aber innerhalb der beiden AttachThreadInputs befinden. Wenn es jetzt fehlschlägt als Beispiel bei Windows Explorer Ordnern dann kannst du das Parent ermitteln um an das Fensterhandle zu kommen. Denn hier wird der Focus immer auf das DirectUIHWND gesetzt ist zumindest bei Win7 so. Bin jetzt aber wirklich raus! Muss an meinem transparenten TabControl weiterarbeiten. ;) gruss |
AW: Anderem Program den Fokus übergeben
Danke ersteinmal für die ganzen Antworten!
Habe es inzwischen mit
Code:
hinbekommen!
GetWindowThreadProcessId
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:54 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