Verstecktes Fenster durch Shortcut aktivieren

Für allgemeine Fragen zur Programmierung mit PureBasic.
mksft98
Beiträge: 4
Registriert: 06.10.2022 17:14

Verstecktes Fenster durch Shortcut aktivieren

Beitrag von mksft98 »

Hallo Leute,

ich würde gern ein verstecktes oder minimiertes PB-Programmfenster durch einen Shortcut reaktivieren. Ich habe schon diverse Suchen gestartet, aber nicht das Richtige gefunden.

Geht das prinzipiell? Für einen Codeschnipsel wäre ich sehr dankbar. :praise:

mksft98
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von HeX0R »

Da das Fenster keinen Focus hat, wenn es versteckt ist, musst Du die API bemühen.
Unter Windows z.B. geht das mit sog. HotKeys.
Da gibt's auch jede Menge Beispiele in den Foren.
Axolotl
Beiträge: 146
Registriert: 31.12.2008 16:34

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von Axolotl »

Nicht so elegant wie mit Hotkeys kann man auch mit

Code: Alles auswählen

#WM_TIMER or #PB_Event_Timer
und

Code: Alles auswählen

If (GetAsyncKeyState_(#VK_SPACE) & $0001) And (GetAsyncKeyState_(#VK_CONTROL) & $0001)  ; check CTRL+SPACE now 

auf Tastendrücke reagieren. (windows only)
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von mk-soft »

Dieser uralte Code 'PB v4.x' funtioniert auch heute noch

Code: Alles auswählen

;-TOP

EnableExplicit

;- Globale Variablen
Global ExitProgram

#WinMain = 0

; ***************************************************************************************

; GlobalHotkeys library
; By Gansta93
; procedure AddHotkey

ProcedureDLL AddHotkey(Window, fsModifiers, Keys, HotkeyID) ; Create a new global hotkey HotkeyID in specified Window.
  ProcedureReturn RegisterHotKey_(WindowID(Window), HotkeyID, fsModifiers, Keys)
EndProcedure

ProcedureCDLL AddHotkey_DEBUG(Window, fsModifiers, Keys, HotkeyID)
  If IsWindow(Window) = 0
    ; TB_DebugError("Specified Window is invalid.")
  EndIf
EndProcedure
;}

; Procedure RemoveHotkey
;{
ProcedureDLL RemoveHotkey(Window, HotkeyID) ; Remove Specified HotkeyID in Window.
  ProcedureReturn UnregisterHotKey_(WindowID(Window), HotkeyID)
EndProcedure

ProcedureCDLL RemoveHotkey_DEBUG(Window, HotkeyID)
  If IsWindow(Window) = 0
    ; TB_DebugError("Specified Window is invalid.")
  EndIf
EndProcedure
;}

; Sample (angepasst an PB4.x)

; ***************************************************************************************

Procedure WinMain()
  
  If OpenWindow(#WinMain, 0, 0, 240, 24, "Hotkey v1.1", #PB_Window_ScreenCentered | #PB_Window_TitleBar | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_Minimize)
    
    If CreateStatusBar(0, WindowID(#WinMain))
      AddStatusBarField(#PB_Ignore)
    Else
      ProcedureReturn
    EndIf
    StatusBarText(0, 0, "Type Alt+C for XXX")
    
    If AddHotkey(#WinMain, #MOD_ALT, #PB_Shortcut_C, 100) = 0
      MessageRequester("Error", "Cannot create hotkey Alt-C.")
      ProcedureReturn
    EndIf
    
    Repeat
      Select WaitWindowEvent()
        Case #WM_HOTKEY ; If an hotkey was called
          Select EventwParam() ; For know what hotkey was called, no documentation on PureBasic for this function.
            Case 100           ; Hotkey with ID 0 (Alt+C)
              HideWindow(0, 0)
              SetWindowState(0, #PB_Window_Normal)
              MessageRequester("Info", "Hotkey preesed")
              
          EndSelect
          
        Case #PB_Event_CloseWindow
          ExitProgram = #True
      EndSelect
    Until ExitProgram
    ; Now we remove the hotkeys.
    RemoveHotkey(0, 100)
    
  EndIf
  
EndProcedure: WinMain()
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
mksft98
Beiträge: 4
Registriert: 06.10.2022 17:14

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von mksft98 »

Habt Dank!
Bereits der 1. Link hat einen für mich passenden Weg gezeigt. Ein Problem habe ich aber noch:
Wenn das Fenstor zuvor mit hidewindow(#wdw, 0) versteckt war und mittels Hotkey anschließend wieder sichtbar und aktiviert wird, dann wird zwar das Fenster gezeigt, aber die enthaltenen Gadgets nicht aufgefrischt. Fahre ich dann während einer WaitWindowEvent-Schleife mit der Maus über die Gadgets, z.Bsp. Button, dann werden diese dargestellt.

Woran könnte das liegen?
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von HeX0R »

Ich denke ein InvalidateRect_() könnte helfen.
Wäre aber besser, wenn Du Deinen (abgespeckten) Code zeigen würdest, dann muss man nicht rumraten.
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von Nino »

Wäre aber besser, wenn Du Deinen (abgespeckten) Code zeigen würdest, dann muss man nicht rumraten.
So ist es. Wenn alles sauber programmiert ist, dann ist InvalidateRect_() dafür nicht nötig.
mksft98
Beiträge: 4
Registriert: 06.10.2022 17:14

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von mksft98 »

InvalidateRect_ hat nicht funktioniert, aber dafür UpdateWindow_(WindowID( WIN))

Code: Alles auswählen

@sauber programmiert: 
Ich benutze ein Fenster mit 2 Container-Gadgets, in denen sich mehrere ButtonImageGadgets liegen. Und offensichtlich liegt hier das Problem, die ButtonImageGadgets werden nicht aufgefrischt. Allerdings werden sie gezeichnet, wenn die Maus drüberfährt. Ein vereinfachtes Beispiel folgt, wenn UpdateWindow_ aktiviert wird, erfolgt die Darstellung korrekt:

EnableExplicit

Enumeration Handles 1 Step 1
	#WIN
	#GDT1
	#GDT2
	#GDT3
	#GDT4
	#IMG3
	#IMG4
	#CT1
EndEnumeration

Procedure ColorizeBTN(HANDLE.i, Image_ID)
	Define W=200, H=50
	Image_ID= CreateImage(#PB_Any, W, H)
	
	LoadFont(1, "@Arial Unicode MS", Int( 16) )
	
	If StartDrawing(ImageOutput(IMAGE_ID))
		
		DrawingMode(#PB_2DDrawing_Transparent)    
		Box(0, 0, W, H, #White )
		DrawingFont(FontID(1))      	
		FrontColor( #Red)
		DrawText((W-TextWidth("TEST"))/2, (H-TextHeight("TEST"))/2, "TEST")
		StopDrawing()
	EndIf
	
	SetGadgetAttribute(Handle, #PB_Button_Image, ImageID(IMAGE_ID))
EndProcedure

Procedure Make_Window()
	
	OpenWindow(#Win, 0, 0, 500, 500, "", #PB_Window_SystemMenu | #PB_Window_WindowCentered | #PB_Window_Maximize)
	
	ButtonGadget(#GDT1, 10,100, 200,50, "TEST")
	ButtonGadget(#GDT2, 10,200, 200,50, "TEST")	
	
	ButtonImageGadget(#GDT3, 10,300,200,50, #IMG3, #PB_Button_Toggle )
	ColorizeBTN( #GDT3, #IMG3)	
	
	ContainerGadget( #CT1, 10, 400, 300, 100, #PB_Container_BorderLess)
		ButtonImageGadget(#GDT4, 10,10 ,200,50, #IMG4, #PB_Button_Toggle )
		ColorizeBTN( #GDT4, #IMG4)	
	CloseGadgetList()
		
EndProcedure

  Procedure Set_HotKey(Key, Modifiers)
    
  	Static ID
  	
  	If RegisterHotKey_(0, ID, Modifiers, Key) = 0
  		ProcedureReturn -1
  	EndIf
  	ID+1
  	ProcedureReturn ID-1
 
  EndProcedure 

Define Event.i, HK.i, MSG.MSG

Make_Window()
HideWindow(	#Win, #True)
HK = Set_HotKey(#VK_P,#MOD_ALT | #MOD_SHIFT)

Repeat
 		GetMessage_(@Msg, 0, 0, 0)
 		If MSG\message = #WM_HOTKEY
 			Select MSG\wParam
 					
 				Case HK
 					HideWindow(	#Win, #False) 	
				
;  					UpdateWindow_(WindowID( #WIN))			
					
					Repeat
						Event=WaitWindowEvent()
					Until Event=#PB_Event_CloseWindow
			EndSelect
		EndIf					
Until Event=#PB_Event_CloseWindow

Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von Nino »

"sauber programmiert" heißt z.B., dass man die Ereignisse nicht innerhalb einer doppelten Repeat-Schleife abfragt, und in diesem Zusammenhang, dass man innerhalb einer Callback-Funktion prüft, ob ein Hotkey gedrückt wurde.
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: Verstecktes Fenster durch Shortcut aktivieren

Beitrag von HeX0R »

Nino hat geschrieben:"sauber programmiert" heißt z.B., dass man die Ereignisse nicht innerhalb einer doppelten Repeat-Schleife abfragt, und in diesem Zusammenhang, dass man innerhalb einer Callback-Funktion prüft, ob ein Hotkey gedrückt wurde.
Genau!
So in etwa:

Code: Alles auswählen

EnableExplicit

Enumeration Handles 1
	#WIN
	#GDT1
	#GDT2
	#GDT3
	#GDT4
	#IMG3
	#IMG4
	#CT1
EndEnumeration

Global HotKeyID

Procedure ColorizeBTN(IMAGE_ID)
	Protected W = 200, H = 50
	
	CreateImage(IMAGE_ID, W, H)
	
	LoadFont(1, "@Arial Unicode MS", Int( 16) )
	
	If StartDrawing(ImageOutput(IMAGE_ID))
		
		DrawingMode(#PB_2DDrawing_Transparent)
		Box(0, 0, W, H, #White )
		DrawingFont(FontID(1))
		FrontColor( #Red)
		DrawText((W - TextWidth("TEST")) / 2, (H - TextHeight("TEST")) / 2, "TEST")
		StopDrawing()
	EndIf
EndProcedure

Procedure Make_Window()
	
	OpenWindow(#Win, 0, 0, 500, 500, "", #PB_Window_SystemMenu | #PB_Window_WindowCentered | #PB_Window_Maximize)
	
	ButtonGadget(#GDT1, 10, 100, 200, 50, "TEST")
	ButtonGadget(#GDT2, 10, 200, 200, 50, "TEST")
	
	ColorizeBTN(#IMG3)
	ColorizeBTN(#IMG4)
	ButtonImageGadget(#GDT3, 10, 300, 200, 50, ImageID(#IMG3), #PB_Button_Toggle )
	ContainerGadget( #CT1, 10, 400, 300, 100, #PB_Container_BorderLess)
	  ButtonImageGadget(#GDT4, 10, 10 , 200, 50, ImageID(#IMG4), #PB_Button_Toggle )
	CloseGadgetList()
	
EndProcedure

Procedure MyCallBack(Win, Msg, wParam, lParam)
	
	Select Msg
		Case #WM_HOTKEY
			Select wParam
				Case HotKeyID
					HideWindow(#Win, #False)
					UpdateWindow_(WindowID(#Win))
			EndSelect
	EndSelect
	
	ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure Set_HotKey(Key, Modifiers)
	Static ID
	
	ID + 1
	If RegisterHotKey_(WindowID(#Win), ID, Modifiers, Key) = 0
		ProcedureReturn - 1
	EndIf
	
	ProcedureReturn ID
	
EndProcedure

Make_Window()
HotKeyID = Set_HotKey(#VK_P, #MOD_ALT | #MOD_SHIFT)
SetWindowCallback(@MyCallBack())
HideWindow( #Win, #True)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

UnregisterHotKey_(WindowID(#Win), HotKeyID)
Antworten