ContainerGadget statt eigenes Fenster

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

ContainerGadget statt eigenes Fenster

Beitrag 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?
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: ContainerGadget statt eigenes Fenster

Beitrag 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.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Re: ContainerGadget statt eigenes Fenster

Beitrag 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?
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: ContainerGadget statt eigenes Fenster

Beitrag 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
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Re: ContainerGadget statt eigenes Fenster

Beitrag von fabulouspaul »

:praise:
Dankeeeee!
Benutzeravatar
Rudi
Beiträge: 143
Registriert: 22.04.2010 18:28
Wohnort: #PB_Any

Re: ContainerGadget statt eigenes Fenster

Beitrag 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 
Win7 (x64)PB 5.4x (x86)5,7 Windows-LeistungsindexSuche
Lord
Beiträge: 313
Registriert: 21.01.2008 19:11

Re: ContainerGadget statt eigenes Fenster

Beitrag 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?
Bild
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: ContainerGadget statt eigenes Fenster

Beitrag 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 
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Re: ContainerGadget statt eigenes Fenster

Beitrag 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 
Lord
Beiträge: 313
Registriert: 21.01.2008 19:11

Re: ContainerGadget statt eigenes Fenster

Beitrag 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:
Bild
Antworten