Transfer a gadget to another window

Just starting out? Need help? Post your questions and find answers here.
StarWarsFan
Enthusiast
Enthusiast
Posts: 169
Joined: Sat Mar 14, 2015 11:53 am

Transfer a gadget to another window

Post by StarWarsFan »

Given this situation:

I got a log gadget window on my screen where the user sees what is being done.
After the actions of screen#1 are complete, the program moves on to screen#2.

Now how do I move that log gadget window over to the second screen? It is a standard ListViewGadget
Image - There is usually a lot of "try this, maybe do that" but ONLY an example that one can test for themself and get an immediate result actually brings people forward.
User avatar
spikey
Enthusiast
Enthusiast
Posts: 581
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Transfer a gadget to another window

Post by spikey »

You can use the SetParent api function, see https://learn.microsoft.com/en-us/windo ... -setparent

Code: Select all

If OpenWindow(0, 50, 50, 270, 140, "ListViewGadget1", #PB_Window_SystemMenu)
  ListViewGadget(0, 10, 40, 250, 90)
  ButtonGadget(1, 10, 10, 50, 25, "Click me")
  OpenWindow(1, 400, 50, 270, 140, "ListViewGadget2", #PB_Window_SystemMenu)
  For a = 1 To 12
    AddGadgetItem (0, -1, "Item " + Str(a) + " of the Listview") ; define listview content
  Next
  SetGadgetState(0, 9) ; set (beginning with 0) the tenth item as the active one
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_Gadget And EventGadget() = 1
      SetParent_(GadgetID(0), WindowID(1))
    EndIf
  Until Event = #PB_Event_CloseWindow
EndIf
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: Transfer a gadget to another window

Post by mestnyi »

here for all three OS
viewtopic.php?t=61028
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Transfer a gadget to another window

Post by ChrisR »

I had made an example using SetParent (Windows) but spikey was faster.
But I have a strange behavior when it is done with OpenWindow/CloseWindow
When I switch windows the Listview background color is grey and If I use the Listview ScrollBar, it becomes black.
Do you have an explanation for this behavior ?
No problem if I use HideWindow True/False instead of Open(Close)Window.

Code: Select all

EnableExplicit

Enumeration Window
  #Window_1
  #Window_2
EndEnumeration

Enumeration Gadgets
  #ListView
  #Btn_Open_Window_1
  #Btn_Open_Window_2
EndEnumeration

Procedure Open_Window_2(X = 0, Y = 0, Width = 360, Height = 240)
  If OpenWindow(#Window_2, X, Y, Width, Height, "Window_2", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(#Btn_Open_Window_1, 20, 170, 320, 50, "Open_Window_1")
  EndIf
EndProcedure

Procedure Open_Window_1(X = 0, Y = 0, Width = 360, Height = 240)
  If OpenWindow(#Window_1, X, Y, Width, Height, "Window_1", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(#Btn_Open_Window_2, 20, 170, 320, 50, "Open_Window_2")
  EndIf
EndProcedure

Define I.i
Open_Window_1()
ListViewGadget(#ListView, 20, 20, 320, 140)  
For I=1 To 10
  AddGadgetItem(#ListView, -1, "ListView Element " + Str(I))
Next

;Open_Window_2() : HideWindow(#Window_2, #True)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break

    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Btn_Open_Window_1
          Open_Window_1()
          SetParent_(GadgetID(#ListView), WindowID(#Window_1))
          CloseWindow(#Window_2)
          ;HideWindow(#Window_2, #True) : HideWindow(#Window_1, #False)
        Case #Btn_Open_Window_2
          Open_Window_2()
          SetParent_(GadgetID(#ListView), WindowID(#Window_2))
          CloseWindow(#Window_1)
          ;HideWindow(#Window_1, #True) : HideWindow(#Window_2, #False)
      EndSelect

  EndSelect
StarWarsFan
Enthusiast
Enthusiast
Posts: 169
Joined: Sat Mar 14, 2015 11:53 am

Re: Transfer a gadget to another window

Post by StarWarsFan »

spikey wrote: Sat Oct 01, 2022 9:26 pm
SetParent_(GadgetID(0), WindowID(1))
Thank you, this works nicely. I have tried with your code and with mine.

BUT, one issue:

I had set bg and fg colors in that gadget and after "transferring" the colors look really broken, until I manually left-click each line. Only then bg and fg colors in that gadget are being restored.

What am I missing?
Image - There is usually a lot of "try this, maybe do that" but ONLY an example that one can test for themself and get an immediate result actually brings people forward.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Transfer a gadget to another window

Post by RASHAD »

Code: Select all

If OpenWindow(0, 50, 50, 270, 140, "ListViewGadget1", #PB_Window_SystemMenu)
  ListViewGadget(0, 10, 40, 250, 90)
  SetGadgetColor(0,#PB_Gadget_BackColor,0)
  SetGadgetColor(0,#PB_Gadget_FrontColor,$FFFFFF)
  ButtonGadget(1, 10, 10, 80, 24, "Click me")  
  For a = 1 To 12
    AddGadgetItem (0, -1, "Item " + Str(a) + " of the Listview") ; define listview content
  Next
  SetGadgetState(0, 9) ; set (beginning with 0) the tenth item as the active one
  OpenWindow(1, 400, 50, 270, 140, "ListViewGadget2", #PB_Window_SystemMenu)
  UseGadgetList(WindowID(1))
  ButtonGadget(2, 10, 10, 80, 24, "Click me")
  UseGadgetList(WindowID(0))
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
             SetWindowLongPtr_( GadgetID(0), #GWL_HWNDPARENT,WindowID(1))
          Case 2
             SetWindowLongPtr_( GadgetID(0), #GWL_HWNDPARENT,WindowID(0))
        EndSelect
    EndSelect
  Until Quit = 1
EndIf
Egypt my love
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Transfer a gadget to another window

Post by RASHAD »

For ChrisR

Code: Select all

EnableExplicit

Enumeration Window
  #Window_1
  #Window_2
EndEnumeration

Enumeration Gadgets
  #ListView
  #Btn_Open_Window_1
  #Btn_Open_Window_2
EndEnumeration

Procedure Open_Window_2(X = 0, Y = 0, Width = 360, Height = 240)
  If OpenWindow(#Window_2, X, Y, Width, Height, "Window_2", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(#Btn_Open_Window_1, 20, 170, 320, 50, "Open_Window_1")
  EndIf
EndProcedure

Procedure Open_Window_1(X = 0, Y = 0, Width = 360, Height = 240)
  If OpenWindow(#Window_1, X, Y, Width, Height, "Window_1", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(#Btn_Open_Window_2, 20, 170, 320, 50, "Open_Window_2")
  EndIf
EndProcedure

Define I.i
Open_Window_1()
ListViewGadget(#ListView, 20, 20, 320, 140)  
For I=1 To 10
  AddGadgetItem(#ListView, -1, "ListView Element " + Str(I))
Next

Open_Window_2() : HideWindow(#Window_2, #True)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break

    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Btn_Open_Window_1
          LockWindowUpdate_(WindowID(#Window_2))
          SetWindowLongPtr_( GadgetID(#ListView), #GWL_HWNDPARENT,WindowID(#Window_1))
          HideWindow(#Window_2, #True) : HideWindow(#Window_1, #False)
          LockWindowUpdate_(0)
        Case #Btn_Open_Window_2
          LockWindowUpdate_(WindowID(#Window_1))
          HideWindow(#Window_1, #True) : HideWindow(#Window_2, #False)          
          SetWindowLongPtr_( GadgetID(#ListView), #GWL_HWNDPARENT,WindowID(#Window_2))
          LockWindowUpdate_(0)
      EndSelect

  EndSelect
  ForEver
Egypt my love
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Transfer a gadget to another window

Post by ChrisR »

Thanks RASHAD,
It allowed me to see the difference between SetParent and #GWL_HWNDPARENT (Owner).
Raymond Chen wrote a blog: A window can have a parent or an owner but not both
And a 2nd blog Why does my control send its notifications to the wrong window after I reparent it?

Based on the 2nd blog, if I got it ~right, it seems possible to change the parent and close the previous window as long as you go through a container.

Code: Select all

EnableExplicit

Enumeration Window 1
  #Window_1
  #Window_2
EndEnumeration

Enumeration Gadgets
  #Cont
  #ListView
  #Btn_Open_Window_1
  #Btn_Open_Window_2
EndEnumeration
 
Procedure Open_Window_2(X = 0, Y = 0, Width = 360, Height = 240)
  If OpenWindow(#Window_2, X, Y, Width, Height, "Window_2", #PB_Window_SystemMenu)
    SetWindowColor(#Window_2, $002000)
    ButtonGadget(#Btn_Open_Window_1, 20, 170, 320, 50, "Open Window_1")
  EndIf
EndProcedure

Procedure Open_Window_1(X = 0, Y = 0, Width = 360, Height = 240)
  If OpenWindow(#Window_1, X, Y, Width, Height, "Window_1", #PB_Window_SystemMenu)
    SetWindowColor(#Window_1, $200000)
    ButtonGadget(#Btn_Open_Window_2, 20, 170, 320, 50, "Open Window_2")
  EndIf
EndProcedure

Define I.i
Open_Window_1(200, 100)

ContainerGadget(#Cont, 20, 20, 320, 140, #PB_Container_BorderLess)
SetWindowLongPtr_(GadgetID(#Cont), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(#Cont), #GWL_EXSTYLE) | #WS_EX_CONTROLPARENT)
ListViewGadget(#ListView, 0, 0, GadgetWidth(#Cont), GadgetHeight(#Cont))
SetGadgetColor(#ListView, #PB_Gadget_BackColor, #Cyan) : SetGadgetColor(#ListView, #PB_Gadget_FrontColor, #Blue)
For I=1 To 10
  AddGadgetItem(#ListView, -1, "ListView Element " + Str(I))
Next
CloseGadgetList()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break

    Case #PB_Event_Gadget
      Select EventGadget()
        Case #ListView  
          If EventType() = #PB_EventType_LeftClick
            Debug "Window_" + EventWindow() + ", item selected: " + GetGadgetItemText(#ListView, GetGadgetState(#ListView))
          EndIf
          
        Case #Btn_Open_Window_1
          Open_Window_1(WindowX(#Window_2), WindowY(#Window_2))
          SetParent_(GadgetID(#Cont), WindowID(#Window_1))
          CloseWindow(#Window_2)

        Case #Btn_Open_Window_2
          Open_Window_2(WindowX(#Window_1), WindowY(#Window_1))
          SetParent_(GadgetID(#Cont), WindowID(#Window_2))
          CloseWindow(#Window_1)

      EndSelect
  EndSelect
ForEver
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Transfer a gadget to another window

Post by RASHAD »

Hi ChrisR
Your last snippet works fine
But I don't like Openwindow Closewindow (because we can't know the consequences) and I dont't like Hidewindow also it's not hidden from mouse process all the time
Use resize window outside the desktop when you need to hide it it's much better
Egypt my love
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Transfer a gadget to another window

Post by ChrisR »

Hi RASHAD, thanks for your advices, they're always welcome :)

For StarWarsFan, Raymond Chen wrote
Note that changing a window’s parent or owner is not a normal operation.....
.....Since window reparenting is considered to be an unusual condition
So, it is perhaps better to have 2 ListViewGadgets one in each window, rather than changing the Parent.
And when changing the window, save the ListViewGadget in a list to reload it then in the 2nd ListViewGadget for the 2nd window.
Post Reply