Seite 1 von 2
Fokus auf eigenes Fenster verhindern
Verfasst: 28.05.2014 05:12
von KeyKon
Ich weiß mal wieder nicht weiter und konnte bisher keine Lösung für mein Problem finden.
Das Szenario ist ein Hilfsprogamm welches ich gerade schreibe, dort kann man diverse Funktionen aktivieren die dann wiederum das Hauptprogramm (nicht von mir) beeinflussen.
Gelöst ist das ganze recht schlicht als Overlay über dem Hauptprogramm (transparentes Sticky Fenster mit ImageGadget), ich registriere einfach die Position der Maus beim Klick was dann die entsprechende Aktion auslöst.
Dummerweise löst ein Klick auf ein Fenster aber auch den Fokuswechsel auf dieses aus, das heißt das Hauptprogamm verliert den Fokus was dort dann aber ungewünschte Effekte auslöst.
Also lange Rede, einfache Frage:
Kann ich den Klick registrieren und verhindern dass mein Fenster den Fokus erhält? (Windows 7)
LG KeyKon
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 28.05.2014 12:55
von chi
Kannst du damit vielleicht was anfangen?!
Code: Alles auswählen
Enumeration
#Window
#Tool
EndEnumeration
Procedure WindowCallback(WindowID, Message, WParam, LParam)
Result = #PB_ProcessPureBasicEvents
Select Message
Case #WM_NCACTIVATE
SetActiveWindow(#Window)
If wParam = #False
Result = #True
EndIf
Case #WM_MOUSEACTIVATE
Result = #MA_NOACTIVATE
EndSelect
ProcedureReturn Result
EndProcedure
OpenWindow(#Window, 0, 0, 800, 500, "", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ButtonGadget(0,10,10,100,40,"Click Me")
OpenWindow(#Tool, 0, 0, 320, 200, "",#PB_Window_Tool|#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StickyWindow(#Tool,1)
SetWindowCallback(@WindowCallback(), #Tool)
ButtonGadget(1,10,10,100,40,"Click Me")
SetActiveWindow(#Window)
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 29.05.2014 00:00
von KeyKon
Nunja, ich verstehe den Code vll nicht ganz, aber er schanzt ja nur den Fokus direkt wieder zurück?
Er hat zumindest nicht den gewünschten Effekt (Habe das fremde Programm per Handle angesprochen).
Hier ein kleines Beispiel was mein Problem zeigt:
Code: Alles auswählen
OpenWindow(0,0,0,1000,600,"Main",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_DeactivateWindow
Debug "Fokus verloren"
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Code: Alles auswählen
OpenWindow(0,0,0,200,200,"Help",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateImage(0,200,200,24,#Red)
ImageGadget(0,0,0,200,200,ImageID(0))
StickyWindow(0,1)
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_Gadget
If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
Debug "Klick"
EndIf
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Programm Help und Programm Main zu starten, Ziel ist es wenn ich jetzt auf das Help-Fenster klicke soll beim Programm Main nicht mehr "Fokus verloren" auftauchen weil es diesen dauerhaft behält...
Auf Programm Main habe ich wie gesagt keinen Einfluss!
LG KeyKon
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 29.05.2014 00:15
von Derren
Vielleicht so. Nicht sehr elegant, aber zweckmäßig
Code: Alles auswählen
Define cursor.point
Define windowX, windowY, windowWidth, windowHeight
OpenWindow(0,0,0,200,200,"Help",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
WindowX = WindowX(0)
WindowY = WindowY(0)
WindowWidth = WindowWidth(0)
WindowHeight = WindowHeight(0)
CreateImage(0,200,200,24,#Red)
ImageGadget(0,0,0,200,200,ImageID(0))
StickyWindow(0,1)
DisableWindow(0,1)
Repeat
Delay(1)
GetCursorPos_(cursor)
If cursor\x > WindowX And cursor\x < (WindowX+WindowWidth)
If cursor\y > WindowY And cursor\y < (WindowY+WindowHeight)
Debug "onWindow"
EndIf
EndIf
ForEver
Hier müsstest du halt deine eigenen Gadget "Boundaries" definieren, ein bißchen so wie bei einer custom GUI mit Sprites oder so.
Das Mausklick event musstdu natürlich auch nocht abfragen. Sorry bin nicht so der API-crack.
Der Wait-Cursor nervt, aber mit WaitWindowEvent() wird die komplette Schleife angehalten, wegen dem DisableWindow()
Vielleicht hilfts.
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 29.05.2014 23:40
von KeyKon
Wäre zwar eine schöne Idee, wenn auch sehr unsauber, geht aber nicht.
Dein Beispiel funktioniert nämlich nur weil du die Events nicht abarbeitest, was irgendwann unweigerlich dazu führt dass Windows sich um das Programm "kümmert"^^
Mit einem WaitWindowEvent(50) (statt dem Delay()) buggt zwar nix mehr, aber dann nimmt sogar ein deaktiviertes Fenster den Fokus weg.
Keiner anderen Ideen mehr

Geht das vll einfach nicht?
LG KeyKon
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 30.05.2014 00:08
von Derren
nvm. WindowEvent() geht auch nicht. Sieht alleine gut aus, aber der Focus geht trotzdem verloren
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 30.05.2014 00:43
von TroaX
Die Window-API von Windows sieht so etwas nicht vor. Sobald du auf ein Fenster klickst, das sichtbar bzw. vorhanden ist, erhält es automatisch den Fokus. Du kannst den Fokus nur noch dem Ursprungsfenster zurückwerfen. Aber das dein Fenster keinen Fokus erhält bzw. dem Programm Main den Fokus nicht nimmt, lässt sich nicht beeinflussen. Zumindest ist mir kein Weg bekannt.
Du müsstest also direkt an den RAM des Mainprogramms und den Fokus sowie die genaue Position ermitteln und dann diesen Fokus und die Position setzen. Dann würde der Fokusverlust nicht auffallen. Dafür müsstest du dein Programm aber in einen anderen Ring befördern. Im User-Mode dürfen die Programme nur über eine API im Ring 0 untereinander im RAM rumfummeln. Also wenn gibt es dafür Befehle in der API (was mir nicht bekannt ist) oder das Programm muss auf Ring 0.
Oder du zeichnest das Overlay/OSD direkt per GDI bzw. DX und blittest das Ding in den Backbuffer. Mit dieser Sache habe ich aber keine Erfahrungen bisher gemacht. Ich weiß nur, das es geht.
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 30.05.2014 03:53
von KeyKon
Schade, so etwas hab ich schon befürchtet.
Den Aufwand mit Speichermanipulation werd ich mir sicher nicht machen, ist ja auch nicht grad die feine Art^^
Ich werde dann wohl die Interaktion komplett mit Hotkeys realisieren und das Overlay nur als Anzeige nutzen.
Trotzdem Danke für eure Beiträge
LG KeyKon
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 30.05.2014 08:44
von Bisonte
Und mal ganz banal gefragt : Hast du es schon mit SetParent_() ausprobiert ? Sozusagen : Dein Fenster "Shanghait" das andere ?
Re: Fokus auf eigenes Fenster verhindern
Verfasst: 30.05.2014 10:02
von Kiffi
@KeyKon: Du könntest kontinuierlich prüfen, welches Control den Fokus besitzt (geht IMO
hiermit).
Wenn dann Dein Programm den Fokus bekommt, setzt Du ihn sofort wieder auf das zuletzt gemerkte Control zurück.
Grüße ... Kiffi