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