Page 1 of 1

Transfer a gadget to another window

Posted: Sat Oct 01, 2022 8:14 pm
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

Re: Transfer a gadget to another window

Posted: Sat Oct 01, 2022 9:26 pm
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

Re: Transfer a gadget to another window

Posted: Sun Oct 02, 2022 12:43 pm
by mestnyi
here for all three OS
viewtopic.php?t=61028

Re: Transfer a gadget to another window

Posted: Sun Oct 02, 2022 1:25 pm
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

Re: Transfer a gadget to another window

Posted: Tue Oct 04, 2022 1:53 pm
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?

Re: Transfer a gadget to another window

Posted: Tue Oct 04, 2022 2:38 pm
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

Re: Transfer a gadget to another window

Posted: Tue Oct 04, 2022 3:13 pm
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

Re: Transfer a gadget to another window

Posted: Tue Oct 04, 2022 10:43 pm
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

Re: Transfer a gadget to another window

Posted: Tue Oct 04, 2022 11:21 pm
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

Re: Transfer a gadget to another window

Posted: Tue Oct 04, 2022 11:51 pm
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.