Page 1 of 1
How to set external window inside a gadget?
Posted: Tue Feb 21, 2023 3:30 am
by RobertRioja
I hope someone can help me with this.
I want to display a help file, Alpha.chm for example. I can do it with OpenHelp() or with RunProgram(). But both ways will open the file in a separate window. I would like to display that window in a gadget inside my program's UI. For example in a ContainerGadget, a PanelGadget(), or an MDI Gadget(), etc.
I think that the SetParent_() API function might be the way, but have not figured out how to do it.
Thanks,
Robert
Re: How to set external window inside a gadget?
Posted: Tue Feb 21, 2023 3:53 am
by jacdelad
Code: Select all
OpenWindow(0,0,0,600,400,"Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenHelp("C:\PureBasic64\PureBasic.chm","index.htm")
SetParent_(FindWindow_(0,"HTML-Hilfe"),WindowID(0))
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
...you must change the searched window title according to your language.
Also, this is not very elegant. Indeed, it's very crappy and can also catch other help windows.
Re: How to set external window inside a gadget?
Posted: Tue Feb 21, 2023 6:31 am
by RobertRioja
Thank you for your reply. I changed "HTML-Hilfe" to the actual title of the window. It works perfectly !!!
Robert
Re: How to set external window inside a gadget?
Posted: Tue Feb 21, 2023 8:59 am
by BarryG
Something to consider: I used to have my help file open inside my app as well, but then got negative feedback from my users that they couldn't use other areas of my app and view the help at the same time. So sometimes it's better to have it as a separate window.
Re: How to set external window inside a gadget?
Posted: Tue Feb 21, 2023 3:50 pm
by RobertRioja
Yes, I agree. Currently, some of my apps have the help built-in, and others have it as a separate chm. The built-in version is simply an HTML file that I display in a webgadget. I am actually looking for a way to have it both ways.
I plan on having the chm appear in the app, as jacdelad helped me accomplish, with a button that releases it back to the desktop if the user desires it that way. This way, I only have to develop a single chm that can be used both ways.
Once I work out all the details, I will share it on this forum.
Thank you all for your help.
Robert
Re: How to set external window inside a gadget?
Posted: Tue Feb 21, 2023 9:46 pm
by jacdelad
Also, the CHM-Files are just a bunch of html-Websites. Maybe you can unpack them and use a webgadget?!
Re: How to set external window inside a gadget?
Posted: Tue Feb 21, 2023 10:05 pm
by BarryG
RobertRioja wrote: Tue Feb 21, 2023 3:50 pma button that releases it back to the desktop
Definitely! A pop-out option is needed.
Re: How to set external window inside a gadget?
Posted: Wed Feb 22, 2023 2:36 am
by RobertRioja
Here is the completed example. Thanks to jacdelad and BarryG for help and inspiration.
This sample code reads a help file "HelpWithThisProgram.chm", which you have to supply, into a container within a main window. The help file is normally in its own window on the desktop. There are 3 buttons. The first button is used to free the help window from the container, putting it back on the desktop. The second button moves it from the desktop back to the container. The third button is used to reload the help file in case it was closed while in the container. It can also be used to load a different help file.
Obviously, this is a crude sample which can be refined any way you like.
Code: Select all
Global Hwnd.i ; Handle for help window.
Global Contain ; Container gadget number.
; This procedure fees the help window from the main window.
Procedure Event_Free()
; Set the desktop as the parent.
SetParent_(Hwnd, 0)
; Move it to an arbitrary location and size.
MoveWindow_(Hwnd, 0, 0, 500, 500, 1)
EndProcedure
; This procedure cages the help window in the container.
Procedure Event_Cage()
; Set the container as the parent.
SetParent_(Hwnd, GadgetID(Contain))
; Make the help window maximized in the container.
ShowWindow_(Hwnd, #SHOW_FULLSCREEN)
EndProcedure
; This procedure loads the help window.
Procedure Event_Load()
; Open the help chm file.
OpenHelp(GetCurrentDirectory() + "HelpWithThisProgram.chm", "gettinghelp.htm")
; Get the window handle from its name.
Hwnd = FindWindow_(0, "HelpWithThisProgram")
; Put it in its cage (the container gadget).
Event_Cage()
EndProcedure
; Open main window.
WindowMain = OpenWindow(#PB_Any, 0, 0, 800, 600, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
; Creae a container (empty for now).
Contain = ContainerGadget(#PB_Any, 0, 0, 700, 500, #PB_Container_Raised)
CloseGadgetList()
; Create a button to free the window.
ButtonFree = ButtonGadget(#PB_Any, 10, 510, 50, 30, "Free")
BindGadgetEvent(ButtonFree, @Event_Free())
; Create a button to cage the window.
ButtonCage = ButtonGadget(#PB_Any, 100, 510, 50, 30, "Cage")
BindGadgetEvent(ButtonCage, @Event_Cage())
; Create button to load the help window.
ButtonLoad = ButtonGadget(#PB_Any, 200, 510, 50, 30, "Load")
BindGadgetEvent(ButtonLoad, @Event_Load())
; Load the help chm into the container.
Event_Load()
; Wait for user to end it all.
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: How to set external window inside a gadget?
Posted: Thu Feb 23, 2023 5:17 am
by RobertRioja
Hi again,
I realized that the sample code I posted has some problems. The user could accidentally resize or even close the help window inside the container. I added some features to make this window "fixed in concrete" by altering its styles. But when the user asks to free it, I reset the styles to the original values so it becomes truly independent. However, if the user asks to bring it back to the container, I again alter the styles. This solves a lot of potential problems.
Of course you have to take care of properly sizing and placing the container and the help window if the main window is resized by the user.
Here is the new code:
Code: Select all
Global Hwnd.i ; Handle for help window.
Global Contain ; Container gadget number.
Global OldStyles.i
Global NewStyles.i
; This procedure returns a window's styles.
Procedure.i GetWindowStyles(Hwnd.i)
ProcedureReturn GetWindowLongPtr_(Hwnd, #GWL_STYLE)
EndProcedure
; This procedure sets a window's styles.
Procedure.i SetWindowStyles(Hwnd.i, Style.i)
SetWindowLongPtr_(Hwnd, #GWL_STYLE, Style)
EndProcedure
; This procedure fees the help window from the main window.
Procedure Event_Free()
; Set styles to original settings.
SetWindowStyles(Hwnd, OldStyles)
; Set the desktop as the parent.
SetParent_(Hwnd, 0)
; Show it as normal.
ShowWindow_(Hwnd, #SW_SHOWNORMAL)
EndProcedure
; This procedure cages the help window in the container.
Procedure Event_Cage()
; Set the container as the parent.
SetParent_(Hwnd, GadgetID(Contain))
; Set the new styles.
SetWindowStyles(Hwnd, NewStyles)
; Make the help window maximized in the container.
ShowWindow_(Hwnd, #SHOW_FULLSCREEN)
EndProcedure
; This procedure loads the help window.
Procedure LoadHelp()
; Open the help chm file.
OpenHelp(GetCurrentDirectory() + "HelpWithThisProgram.chm", "gettinghelp.htm")
; Get the window handle from its name.
Hwnd = FindWindow_(0, "HelpWithThisProgram")
; Get window styles.
OldStyles = GetWindowStyles(Hwnd)
; Make new styles without the border.
NewStyles = OldStyles & (~#WS_BORDER)
; Put it in its cage (the container gadget).
Event_Cage()
EndProcedure
; Open main window.
WindowMain = OpenWindow(#PB_Any, 0, 0, 800, 600, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
; Creae a container (empty for now).
Contain = ContainerGadget(#PB_Any, 0, 0, 700, 500, #PB_Container_Raised)
CloseGadgetList()
; Create a button to free the window.
ButtonFree = ButtonGadget(#PB_Any, 10, 510, 50, 30, "Free")
BindGadgetEvent(ButtonFree, @Event_Free())
; Create a button to cage the window.
ButtonCage = ButtonGadget(#PB_Any, 100, 510, 50, 30, "Cage")
BindGadgetEvent(ButtonCage, @Event_Cage())
; Load the help chm into the container.
LoadHelp()
; Wait for user to end it all.
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
; Close the help window.
CloseHelp()
Re: How to set external window inside a gadget?
Posted: Thu Feb 23, 2023 9:39 pm
by Fred
You can see how we do it for the IDE, it works great so far:
https://github.com/fantaisie-software/p ... elpTool.pb