Window back on the Top - Gadget
Window back on the Top - Gadget
Hallo Zusammen,
Ich hoffe ich habe eine Anfänger Frage.
Meine Software startet eine externe Anwendung, der Benutzer muss hier ein paar Sachen klicken.
[Mein Programm verliert hier den Focus]
Nachdem der Benutzer fertig ist [diese Abfrage bekomme vom Programm] soll meine Software wieder den Focus bekommen, und "setactiveGadget()" aufgrufen werden, leider bringt mir das ohne Focus nichts.
Wie kann ich nun in der Z-Order von Windows rumspielen und mein Programm/Fenster nach ganz oben bekommen.
Super wäre es wenn mir jemand helfen kann.
Gruß´Andreas
Ich hoffe ich habe eine Anfänger Frage.
Meine Software startet eine externe Anwendung, der Benutzer muss hier ein paar Sachen klicken.
[Mein Programm verliert hier den Focus]
Nachdem der Benutzer fertig ist [diese Abfrage bekomme vom Programm] soll meine Software wieder den Focus bekommen, und "setactiveGadget()" aufgrufen werden, leider bringt mir das ohne Focus nichts.
Wie kann ich nun in der Z-Order von Windows rumspielen und mein Programm/Fenster nach ganz oben bekommen.
Super wäre es wenn mir jemand helfen kann.
Gruß´Andreas
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Window back on the Top - Gadget
Code: Alles auswählen
SetForeGroundWindow_(hWnd)
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Re: Window back on the Top - Gadget
Funktioniert leider nicht.
Was ich nun gerade getestet habe
SetWindowPos_ funktioniert teilweise, nur nicht unter allen System [hab 2 getestet], unter WIN Server 2008 läufts, auf Windows 7 nicht.
[Und das auch nicht immer]
Als Info
Alle Befehle werden in einer externem Thread abgebearbeitet
Vereinfachtest Beispiel
Was ich nun gerade getestet habe
Code: Alles auswählen
SetForegroundWindow_(WindowID(#Window_0))
SetActiveWindow(#Window_0)
SetActiveWindow_(WindowID(#Window_0))
SetWindowPos_(WindowID(#Window_0), #HWND_TOPMOST, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE)
SetActiveGadget(GetRightGadget(#_1String_1, #_2String_1, #_3String_1, #_4String_1))
[Und das auch nicht immer]
Als Info
Alle Befehle werden in einer externem Thread abgebearbeitet
Vereinfachtest Beispiel
Code: Alles auswählen
Procedure Alive_System(Para)
Repeat
Select Befehl
Case 1
; Hier kommen Befehle die auf die Daten von anderen Programm warten , hier verliert das Programm den Focus
; Hier sollte es den Focus es wieder bekommen, damit der Benutzer sofort weiterarbeiten kann
Befehl = 0
Case 2
Befehl = 0
Endselect
delay(10)
Until Exit = 1
Endprocedure
Re: Window back on the Top - Gadget
Probiere mal diese Funktion von MSDN: Fenster in den Desktop-Vordergrund bringen
Oder noch etwas erweitert von dort: How to bring window to top with SetForegroundWindow()
Code: Alles auswählen
; Verwenden Sie die Funktion SetForegroundWindowEx statt der
; API Funktion SetForegroundWindow ausschließlich, wenn das
; betroffene Fenster tatsächlich in den Vordergrund gebracht
; werden muss.
Procedure SetForegroundWindowEx(hWndWindow)
; Dient dem Setzen des Vordergrundfensters mit der Funktion
; SetForegroundWindow, die sich unter neueren Windows-Versionen
; anders verhält als unter Windows 95 und Windows NT 4.0.
; Der Rückgabewert ist True, wenn das Fenster erfolgreich in den
; Vordergrund gebracht werden konnte.
Protected SetForegroundWindowEx
Protected lThreadForeWin.l ; Thread-ID für das aktuelle Vordergrundfenster
Protected lThreadWindow.l ; Thread-ID für das in hWndWindow spezifizierte
; Fenster, das in den Vordergrund des Desktops
; gebracht werden soll.
; Falls das Fenster dem gleichen Thread wie das aktuelle
; Vordergrundfenster angehört, ist kein Workaround erforderlich:
lThreadWindow = GetWindowThreadProcessId_(hWndWindow, 0)
lThreadForeWin = GetWindowThreadProcessId_(GetForegroundWindow_(), 0)
If lThreadWindow = lThreadForeWin
; Vordergrundfenster und zu aktivierendes Fenster gehören zum
; gleichen Thread. SteForegroundWindow allein reicht aus:
SetForegroundWindowEx = SetForegroundWindow_(hWndWindow)
Else
; Das Vordergrundfenster gehört zu einem anderen Thread als das
; Fenster, das neues Vordergrundfenster werden soll. Mittels
; AttachThreadInput erhaten wir kurzzeitig Zugriff auf die
; Eingabeverarbeitung des Threads des Vordergrundfensters,
; so dass SetForegroundWindow wie erwartet arbeitet:
AttachThreadInput_(lThreadForeWin, lThreadWindow, #True)
SetForegroundWindowEx = SetForegroundWindow_(hWndWindow)
AttachThreadInput_(lThreadForeWin, lThreadWindow, #False)
EndIf
ProcedureReturn SetForegroundWindowEx
EndProcedure
Code: Alles auswählen
Procedure SetForegroundWindowInternal(hWnd)
If Not IsWindow_(hWnd) : ProcedureReturn : EndIf
; relation time of SetForegroundWindow lock
lockTimeOut.l = 0;
hCurrWnd = GetForegroundWindow_();
dwThisTID.l = GetCurrentThreadId_()
dwCurrTID.l = GetWindowThreadProcessId_(hCurrWnd,0);
; we need To bypass some limitations from Microsoft :)
If (dwThisTID <> dwCurrTID)
AttachThreadInput_(dwThisTID, dwCurrTID, #True);
SystemParametersInfo_(#SPI_GETFOREGROUNDLOCKTIMEOUT,0,@lockTimeOut,0);
SystemParametersInfo_(#SPI_SETFOREGROUNDLOCKTIMEOUT,0,0,#SPIF_SENDWININICHANGE | #SPIF_UPDATEINIFILE);
#ASFW_ANY = -1
AllowSetForegroundWindow_(#ASFW_ANY);
EndIf
SetForegroundWindow_(hWnd);
If (dwThisTID <> dwCurrTID)
SystemParametersInfo_(#SPI_SETFOREGROUNDLOCKTIMEOUT,0,lockTimeOut,#SPIF_SENDWININICHANGE | #SPIF_UPDATEINIFILE);
AttachThreadInput_(dwThisTID, dwCurrTID, #False);
EndIf
EndProcedure
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Re: Window back on the Top - Gadget
Klappt leider auch nicht.
Ich werde morgen mal schauen ob ich ein Code hinkriege der das Problem ausführbar zeigt.
Die Software hat aktuell etwa 7.000 selbstgeschrieben Zeilen Code sowie müssen viele Extra Programme auf dem Rechner sein.
Gruß
Ich werde morgen mal schauen ob ich ein Code hinkriege der das Problem ausführbar zeigt.
Die Software hat aktuell etwa 7.000 selbstgeschrieben Zeilen Code sowie müssen viele Extra Programme auf dem Rechner sein.
Gruß
Re: Window back on the Top - Gadget
Hat bei mir bis jetzt immer geklappt:
Code: Alles auswählen
SetForegroundWindow_(WindowID(#Window_Main))
BringWindowToTop_(WindowID(#Window_Main))

Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Re: Window back on the Top - Gadget
Mach mal aus diesem Code eine .exe mit Compileroption threadsafe:X360 Andy hat geschrieben:Klappt leider auch nicht.
Code: Alles auswählen
EnableExplicit
; http://msdn.microsoft.com/de-de/library/bb979463.aspx
;
; Verwenden Sie die Funktion SetForegroundWindowEx statt der
; API Funktion SetForegroundWindow ausschließlich, wenn das
; betroffene Fenster tatsächlich in den Vordergrund gebracht
; werden muss.
Procedure SetForegroundWindowEx(hWndWindow)
; Dient dem Setzen des Vordergrundfensters mit der Funktion
; SetForegroundWindow, die sich unter neueren Windows-Versionen
; anders verhält als unter Windows 95 und Windows NT 4.0.
; Der Rückgabewert ist True, wenn das Fenster erfolgreich in den
; Vordergrund gebracht werden konnte.
Protected SetForegroundWindowEx
Protected lThreadForeWin.l ; Thread-ID für das aktuelle Vordergrundfenster
Protected lThreadWindow.l ; Thread-ID für das in hWndWindow spezifizierte
; Fenster, das in den Vordergrund des Desktops
; gebracht werden soll.
; Falls das Fenster dem gleichen Thread wie das aktuelle
; Vordergrundfenster angehört, ist kein Workaround erforderlich:
lThreadWindow = GetWindowThreadProcessId_(hWndWindow, 0)
lThreadForeWin = GetWindowThreadProcessId_(GetForegroundWindow_(), 0)
If lThreadWindow = lThreadForeWin
; Vordergrundfenster und zu aktivierendes Fenster gehören zum
; gleichen Thread. SteForegroundWindow allein reicht aus:
;SetForegroundWindowEx = SetForegroundWindow_(hWndWindow)
Else
; Das Vordergrundfenster gehört zu einem anderen Thread als das
; Fenster, das neues Vordergrundfenster werden soll. Mittels
; AttachThreadInput erhaten wir kurzzeitig Zugriff auf die
; Eingabeverarbeitung des Threads des Vordergrundfensters,
; so dass SetForegroundWindow wie erwartet arbeitet:
AttachThreadInput_(lThreadForeWin, lThreadWindow, #True)
SetForegroundWindowEx = SetForegroundWindow_(hWndWindow)
AttachThreadInput_(lThreadForeWin, lThreadWindow, #False)
EndIf
ProcedureReturn SetForegroundWindowEx
EndProcedure
; http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo
;
Procedure SetForegroundWindowInternal(hWnd)
If Not IsWindow_(hWnd) : ProcedureReturn : EndIf
; relation time of SetForegroundWindow lock
Protected lockTimeOut.l = 0;
Protected hCurrWnd = GetForegroundWindow_();
Protected dwThisTID.l = GetCurrentThreadId_()
Protected dwCurrTID.l = GetWindowThreadProcessId_(hCurrWnd,0);
; we need To bypass some limitations from Microsoft :)
If (dwThisTID <> dwCurrTID)
AttachThreadInput_(dwThisTID, dwCurrTID, #True);
SystemParametersInfo_(#SPI_GETFOREGROUNDLOCKTIMEOUT,0,@lockTimeOut,0);
SystemParametersInfo_(#SPI_SETFOREGROUNDLOCKTIMEOUT,0,0,#SPIF_SENDWININICHANGE | #SPIF_UPDATEINIFILE);
#ASFW_ANY = -1
AllowSetForegroundWindow_(#ASFW_ANY);
EndIf
SetForegroundWindow_(hWnd);
;SetFocus_(hWnd)
If (dwThisTID <> dwCurrTID)
SystemParametersInfo_(#SPI_SETFOREGROUNDLOCKTIMEOUT,0,lockTimeOut,#SPIF_SENDWININICHANGE | #SPIF_UPDATEINIFILE);
AttachThreadInput_(dwThisTID, dwCurrTID, #False);
EndIf
EndProcedure
Global myMsg = RegisterWindowMessage_("MyWindowMessage")
Procedure run(v.i)
Protected program
program = RunProgram("calc.exe","","",#PB_Program_Open)
While ProgramRunning(program)
Delay(100)
Wend
CloseProgram(program)
PostMessage_(v,myMsg,0,0)
EndProcedure
Procedure winthread(v)
Protected win
win = OpenWindow(#PB_Any,100,100,500,300,"main")
CreateThread(@run(),WindowID(win))
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case myMsg
;SetForegroundWindowEx(WindowID(win))
SetForegroundWindowInternal(WindowID(win))
EndSelect
ForEver
CloseWindow(win)
EndProcedure
Define t
t = CreateThread(@winthread(),0)
WaitThread(t)
sobald Calc beendet wurde. Aber als EXE kompilieren und diese
ohne geöffnete PB IDE testen.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Re: Window back on the Top - Gadget
Klappt in meinem Beispiel alles nicht.
Hier ein einfaches Beispiel wie es funktionieren sollte
- Hier funktioniert es nicht
[Egal welchen Befehl ich einsetze vor dem SetActiveGadget()]
Hier ein einfaches Beispiel wie es funktionieren sollte
- Hier funktioniert es nicht
[Egal welchen Befehl ich einsetze vor dem SetActiveGadget()]
Code: Alles auswählen
Global Exit
Global Befehl
#W1=1
#G1=2
#G2=3
Procedure A1(P)
Repeat
Select Befehl
Case 1
Debug "Befehl 1"
Befehl=0
Case 2
Debug "Befehl 2 ---"
Debug "Run Calc.exe"
program=RunProgram("calc.exe", "", "", #PB_Program_Open)
While ProgramRunning(program)
Delay(100)
Wend
CloseProgram(program)
Debug "Calc Closed"
SetActiveGadget(#G1)
Debug "SetActiveGadget State to G1"
Debug "realy ?"
Befehl=0
EndSelect
Delay(10)
Until Exit=1
Exit=2
EndProcedure
OpenWindow(#W1, 100, 100, 200, 200, "Main")
StringGadget(#G1, 10, 10, 100, 20, "ABC")
ButtonGadget(#G2, 10, 40, 100, 20, "Klick mich")
CreateThread(@A1(), 1)
Repeat
event=WaitWindowEvent(50)
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case #G1
Befehl=1
Case #G2
Befehl=2
EndSelect
Case #PB_Event_CloseWindow
Select GetActiveWindow()
Case #W1
Exit=1
EndSelect
EndSelect
Until Exit=2
- HeX0R
- Beiträge: 3042
- Registriert: 10.09.2004 09:59
- Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3 - Kontaktdaten:
Re: Window back on the Top - Gadget
Aus einem Thread heraus ist meistens schlecht, probier es mal so:
[Edit]
Oder gleich aus dem Thread ein
aufrufen.
Code: Alles auswählen
Global Exit
Global Befehl
#W1=1
#G1=2
#G2=3
Procedure A1(P)
Repeat
Select Befehl
Case 1
Debug "Befehl 1"
Befehl=0
Case 2
Debug "Befehl 2 ---"
Debug "Run Calc.exe"
program=RunProgram("calc.exe", "", "", #PB_Program_Open)
While ProgramRunning(program)
Delay(100)
Wend
CloseProgram(program)
Debug "Calc Closed"
PostMessage_(WindowID(#W1), #WM_APP, 1, 1)
Befehl=0
EndSelect
Delay(10)
Until Exit=1
Exit=2
EndProcedure
OpenWindow(#W1, 100, 100, 200, 200, "Main")
StringGadget(#G1, 10, 10, 100, 20, "ABC")
ButtonGadget(#G2, 10, 40, 100, 20, "Klick mich")
CreateThread(@A1(), 1)
Repeat
event=WaitWindowEvent(50)
Select event
Case #WM_APP
SetActiveWindow(#W1)
SetActiveGadget(#G1)
Case #PB_Event_Gadget
Select EventGadget()
Case #G1
Befehl=1
Case #G2
Befehl=2
EndSelect
Case #PB_Event_CloseWindow
Select GetActiveWindow()
Case #W1
Exit=1
EndSelect
EndSelect
Until Exit=2
Oder gleich aus dem Thread ein
Code: Alles auswählen
SendMessage_(GadgetID(#G1), #WM_SETFOCUS, 1, 1)
{Home}.:|:.{Codes}.:|:.{Downloads}.:|:.{History Viewer Online}.:|:.{Bier spendieren}