Seite 1 von 1

ContainerGadget statt eigenes Fenster

Verfasst: 23.10.2016 13:40
von fabulouspaul
Hallo Gemeinde,

gibt es einen Weg, ein "beliebiges" Programm so zu starten, dass es statt eines eigenen Fensters seine Ausgabe in ein ContainerGadget packt?
Also quasi ContainerGadget als Fenster-Ersatz.

Hintergrund: ich möchte gerne PDFs in einem PB-Programm anzeigen. Funktioniert prima mit einem WebGadget, wenn AcrobatReader installiert ist. Ohne diesen macht Windows 10 Edge als eigenständiges Browser-Fenster auf. Das PB-Programm soll aber in einem Umfeld zum Einsatz kommen, in dem eine Installation von AcrobatReader nicht möglich ist.
Daher stelle ich mir vor, einen portablen freien PDF-Viewer aus dem PB-Programm zu starten, nur sollte er eben nicht in einem separaten Fenster laufen sondern wie bei der Lösung oben im PB-Programm (ContainerGadget).

Hat jemand eine Idee dazu?

Re: ContainerGadget statt eigenes Fenster

Verfasst: 23.10.2016 14:02
von RSBasic
Du kannst mit WinAPI beliebige Win32-Fenster in dein eigenes Fenster verschieben.
Beispiel:

Code: Alles auswählen

EnableExplicit

Define Handle

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If ContainerGadget(1, 0, 0, WindowWidth(0), WindowHeight(0), 0)
    RunProgram("notepad.exe")
    Delay(100)
    Handle = FindWindow_("Notepad", 0)
    If Handle
      SetParent_(Handle, GadgetID(1))
      SetWindowPos_(Handle, 0, 0, 0, WindowWidth(0), WindowHeight(0), #SWP_NOZORDER | #SWP_FRAMECHANGED)
      
    EndIf
    
    CloseGadgetList()
  EndIf
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf
Da musst du aber auch noch dein Fenster neu zeichnen lassen, damit es keine Darstellungsfehler nach dem SetParent gibt.
Wie du den Klassennamen deines gewünschten Fensters ermitteln kannst, kannst du entweder dieses Programm oder dieses Programm nutzen.

Re: ContainerGadget statt eigenes Fenster

Verfasst: 23.10.2016 14:45
von fabulouspaul
Klasse!

Das hat gut funktioniert! Ich nehme SumatraPDF, blende die Menüzeile im Setup aus und habe im Prinzip, was ich haben möchte.

Aus optischen Gründen: gibt es auch noch einen Möglichkeit bei dem PB-fremden Programm die Fenster-Titelzeile zu unterdrücken?

Re: ContainerGadget statt eigenes Fenster

Verfasst: 23.10.2016 14:54
von RSBasic

Code: Alles auswählen

EnableExplicit

Define Handle

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If ContainerGadget(1, 0, 0, WindowWidth(0), WindowHeight(0), 0)
    RunProgram("notepad.exe")
    Delay(100)
    Handle = FindWindow_("Notepad", 0)
    If Handle
      SetParent_(Handle, GadgetID(1))
      SetWindowLongPtr_(Handle, #GWL_STYLE, GetWindowLongPtr_(Handle, #GWL_STYLE) &~ #WS_DLGFRAME &~ #WS_SIZEBOX)
      SetWindowPos_(Handle, 0, 0, 0, WindowWidth(0), WindowHeight(0), #SWP_NOZORDER | #SWP_FRAMECHANGED)
      
    EndIf
    
    CloseGadgetList()
  EndIf
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf

Re: ContainerGadget statt eigenes Fenster

Verfasst: 23.10.2016 15:13
von fabulouspaul
:praise:
Dankeeeee!

Re: ContainerGadget statt eigenes Fenster

Verfasst: 23.10.2016 18:51
von Rudi
So kannste noch das Aufflackern des zu integrierenden Fensters verhindern und beide Fenster neu zeichnen :wink: :

Code: Alles auswählen

EnableExplicit

Define Handle

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	If ContainerGadget(1, 0, 0, WindowWidth(0), WindowHeight(0), 0)
		RunProgram("notepad.exe","","",#PB_Program_Hide)
		Delay(100)
		Handle = FindWindow_("Notepad", 0)
		If Handle
			SetParent_(Handle, GadgetID(1))
			SetWindowLongPtr_(Handle, #GWL_STYLE, GetWindowLongPtr_(Handle, #GWL_STYLE) &~ #WS_DLGFRAME &~ #WS_SIZEBOX)
			SetWindowPos_(Handle, 0, 0, 0, WindowWidth(0), WindowHeight(0), #SWP_NOZORDER | #SWP_FRAMECHANGED)
			ShowWindow_(Handle, #SW_SHOW)
			UpdateWindow_(Handle)
		EndIf
		CloseGadgetList()
	EndIf
	UpdateWindow_(WindowID(0))
	
	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_CloseWindow
				End
		EndSelect
	ForEver
EndIf 

Re: ContainerGadget statt eigenes Fenster

Verfasst: 24.10.2016 09:00
von Lord
Hallo RSBasic und Rudi!

Interessante Idee.
Leider erscheint bei mir der Menüzeilentext erst, wenn
ich mit der Maus darüberfahre.

Interessanterweise erscheint der Text sofort (allerdings
ausgegraut, weil nicht aktiv), wenn ich vor der Event-
schleife einen Breakpoint setze. Nach dem Fortsetzen
ist der Menütext weiterhin da.

Wie läßt sich bei diesem Beispiel das Menü - hier insbe-
sondere Datei->Beenden - in die Eventschleife einbinden?

Re: ContainerGadget statt eigenes Fenster

Verfasst: 24.10.2016 10:30
von RSBasic
Damit sollte das Fenster direkt sichtbar sein:

Code: Alles auswählen

EnableExplicit

Define Handle

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If ContainerGadget(1, 0, 0, WindowWidth(0), WindowHeight(0), 0)
    RunProgram("notepad.exe","","",#PB_Program_Hide)
    Delay(100)
    Handle = FindWindow_("Notepad", 0)
    If Handle
      ShowWindow_(Handle, #SW_HIDE)
      SetParent_(Handle, GadgetID(1))
      SetWindowLongPtr_(Handle, #GWL_STYLE, GetWindowLongPtr_(Handle, #GWL_STYLE) &~ #WS_DLGFRAME &~ #WS_SIZEBOX)
      SetWindowPos_(Handle, 0, 0, 0, WindowWidth(0), WindowHeight(0), #SWP_NOZORDER | #SWP_FRAMECHANGED)
      UpdateWindow_(Handle)
      
    EndIf
    CloseGadgetList()
  EndIf
  UpdateWindow_(WindowID(0))
  ShowWindow_(Handle, #SW_SHOW)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf 

Re: ContainerGadget statt eigenes Fenster

Verfasst: 24.10.2016 14:02
von uweb
Ich bin zu fast dem gleichen Ergebnis gekommen. Da hätte ich wohl mal besser zwischendurch nachschauen sollen ob schon jemand etwas gepostet hat.
Eine kleine Erweiterung (der Fensterinhalt wird nun bei Bedarf halbwegs zuverlässig neu aufgebaut) habe ich zwar.
Aber für ein anderes Problem habe ich noch nicht einmal eine Idee:
Bei einem Fenster in einem Fenster kann nur eines aktiv sein. Bei der Texteingabe bleibt der sichtbare Fensterrahmen also inaktiv und beim Verschieben des Fensters wird Notepad grau. Man sieht den Unterschied zu einem Gadget.

Code: Alles auswählen

EnableExplicit
Global Handle, Program

Macro MAKELPARAM( x, y )
  (x<<16) | y
EndMacro

Procedure MyWindowCallback(WindowID, Message, wParam, lParam)
  Static Result = #PB_ProcessPureBasicEvents
  If Message = #WM_NCPAINT
    Delay(2)
    RedrawWindow_(Handle, 0, 0, #RDW_ERASE | #RDW_FRAME | #RDW_INTERNALPAINT | #RDW_INVALIDATE)
  ElseIf Message = #WM_SIZING
    ResizeGadget(1,0,0,WindowWidth(0),WindowHeight(0))
    MoveWindow_(Handle,0,0,WindowWidth(0),WindowHeight(0), #True)
  EndIf
  ProcedureReturn Result
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
  If ContainerGadget(1, 0, 0, WindowWidth(0), WindowHeight(0), 0)
    Program=RunProgram("notepad.exe","","",#PB_Program_Open | #PB_Program_Hide)
    Delay(100)
    Handle = FindWindow_("Notepad", 0)
    If Handle
      SetParent_(Handle, GadgetID(1))
      SetWindowLongPtr_(Handle, #GWL_STYLE, GetWindowLongPtr_(Handle, #GWL_STYLE) &~ #WS_DLGFRAME &~ #WS_SIZEBOX)
      SetWindowPos_(Handle, 0, 0, 0, WindowWidth(0), WindowHeight(0), #SWP_NOZORDER | #SWP_FRAMECHANGED)
    EndIf
    CloseGadgetList()
  EndIf
  UpdateWindow_(GadgetID(1))
  ShowWindow_(Handle, #SW_SHOW)
  SetWindowCallback(@MyWindowCallback(), 0)
  Repeat : If WaitWindowEvent() = #PB_Event_CloseWindow : End : EndIf : ForEver
EndIf 

Re: ContainerGadget statt eigenes Fenster

Verfasst: 25.10.2016 08:19
von Lord
Hallo Ray!

Danke für das sofort Sichtbarmachen der Menüzeile.
Lord hat geschrieben:...
Wie läßt sich bei diesem Beispiel das Menü - hier insbe-
sondere Datei->Beenden - in die Eventschleife einbinden?
Gibt es dazu auch eine Lösung?

Nachtrag:
Ich sehe gerade, daß Du nach einer Lösung gesucht hast:
http://www.purebasic.fr/german/viewtopi ... =6&t=29872
Es war aber nicht meine Absicht, mit meiner Frage
Deinen Rechner zum Absturz zu bringen. :lol: