Page 1 of 1

Get Current #Window

Posted: Wed Jan 13, 2016 4:56 pm
by Xanos
Hey guys,
in order to provide flexible and seamless libraries to work with pb windows, I would appreciate to get the current #Window as it is also used by the Purebasic Gadgets.

The current windowID can easily be obtained using

Code: Select all

UseGadgetList()
, but I do not see any way to get the #Window, e.g. to add timers to it or use window related procedures.

Re: Get Current #Window

Posted: Wed Jan 13, 2016 5:13 pm
by infratec

Code: Select all

GetActiveWindow()
:?:

Bernd

Re: Get Current #Window

Posted: Wed Jan 13, 2016 5:16 pm
by Xanos
No, this returns the #Window that currently has the keyboard focus. I want to retrieve the #Window on which a new gadget would be created when calling one of the gadget-creating procedures.

As far as I know there is no way to get this, as the current gadget list also only points to the WindowID, not the #Window(Number). However, I thought that maybe one has a workaround or a solution that I missed.


What do I need this for?
In this particular case I want to create a custom gadget based on the canvas gadget.
The "CanvasGadget()" can be called and will automatically create a gadget on the current window.
However, I additionally need a timer for this gadget. Therefore, I want to create a new timer by calling AddWindowTimer(). However, this procedure requires a #WindowNumber which I have no access to without the user having to pass it to the procedure which I want to avoid.
Additionally, I am not really happy that it is not possible to create a new timer with the timer ID being automatically assigned (using #PB_Any), but this is another topic ^^

Re: Get Current #Window

Posted: Wed Jan 13, 2016 6:25 pm
by kenmo
Here is one method using PB internal functions, adapted from:
http://www.purebasic.fr/english/viewtop ... =3&t=61673

Code: Select all

;-
;- INCLUDE START

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Import ""
CompilerElse
ImportC ""
CompilerEndIf
  PB_Object_EnumerateStart( PB_Objects )
  PB_Object_EnumerateNext( PB_Objects, *ID.Integer )
  PB_Object_EnumerateAbort( PB_Objects )
  PB_Window_Objects.i
EndImport

ProcedureDLL EnumerateStartWindow() ;Returns pb window object 
  PB_Object_EnumerateStart(PB_Window_Objects)
  ProcedureReturn PB_Window_Objects
EndProcedure

ProcedureDLL EnumerateNextWindow( *Window.Integer ) ;Returns next enumerate pb object 
  Protected PBObject, Window =-1
  PBObject = PB_Object_EnumerateNext( PB_Window_Objects, @Window )
  If IsWindow( Window )
    PokeI( *Window, PeekI( @Window ) )
  EndIf
  ProcedureReturn PBObject
EndProcedure

ProcedureDLL EnumerateAbortWindow() ;Abort enumerate window
  ProcedureReturn PB_Object_EnumerateAbort(PB_Window_Objects)
EndProcedure

Procedure.i GetBuildWindow()
  Protected Result.i = -1
  BuildID.i = UseGadgetList(0)
  If EnumerateStartWindow()
    Protected Window.i
    While EnumerateNextWindow(@Window)
      If (WindowID(Window) = BuildID)
        Result = Window
        EnumerateAbortWindow()
        Break
      EndIf
    Wend
  EndIf
  ProcedureReturn Result
EndProcedure

;- INCLUDE END
;-

;-
;- DEMO

OpenWindow(5, #PB_Ignore, #PB_Ignore, 320, 240, "Window 5")
Debug GetBuildWindow()

;-


To avoid the WindowTimer issue(s), you could also write a lightweight procedure (created as a background thread when your custom gadget is created) which handles whatever your timer would be doing... I think Stargate posted a nice example recently.

Re: Get Current #Window

Posted: Wed Jan 13, 2016 6:30 pm
by infratec
Hi,

I know what you want, but ...

How can you create gadgets when you don't know on which window?

It sounds that you create gadgets on the window which has the current GadetList open.
But when you don't know which window it is, how do you place the gadgets?

What you can always do:

Use a list or a map with all your windows informations like

Code: Select all

Structure WindowStructure
  Window.i
  WindowID.i
  :
  :
EndStructure
Then you can searc after what you want.

Bernd

Re: Get Current #Window

Posted: Wed Jan 13, 2016 6:31 pm
by mestnyi
Maybe it will help :)

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  Import ""
  CompilerElse
    ImportC ""
    CompilerEndIf
    PB_Object_EnumerateStart(Object)
    PB_Object_EnumerateNext(Object,*ID.Integer)
    PB_Object_EnumerateAbort(Object)
    PB_Object_Count( Objects )
    PB_Window_Objects.l
  EndImport
  
  Procedure CurrentWindow()
    Protected Window =- 1
    PB_Object_EnumerateStart(PB_Window_Objects)
    If PB_Window_Objects
      While PB_Object_EnumerateNext(PB_Window_Objects, @Window)
        If WindowID(Window) = UseGadgetList(0) 
          ProcedureReturn Window
        EndIf
      Wend
      PB_Object_EnumerateAbort(PB_Window_Objects) 
    EndIf
  EndProcedure
kenmo I did not see the answer sorry :oops:

Re: Get Current #Window

Posted: Wed Jan 13, 2016 7:13 pm
by Xanos
Thank you all for all the good input :)

Re: Get Current #Window

Posted: Thu Jan 14, 2016 5:09 am
by TI-994A
Xanos wrote:The current windowID can easily be obtained using

Code: Select all

UseGadgetList()
, but I do not see any way to get the #Window, e.g. to add timers to it or use window related procedures.
If a Windows-only solution is acceptable, this might do the trick:

* adapted from GetParent()

Code: Select all

;========================================================
; GadgetListWindow() returns the window number of the
; current gadget list obtained from UseGadgetList(0)
;
; Windows only
;   
; tested & working on Win 8.1 with PureBasic v5.40 (x64)
;
; by TI-994A - free to use, improve, share...
;
; 14th January 2016
;========================================================

Procedure GadgetListWindow()
  ;usig the UseGadgetList(0) function, the 
  ;GetProp_() function translates the returned
  ;PureBasic window ID to its window number
  w = GetProp_(UseGadgetList(0), 
      StringField("PB_WINDOWID", 1, ",")) - 1
  ProcedureReturn w
EndProcedure

OpenWindow(0, 100, 100, 200, 100, "Window 0")
ButtonGadget(0, 10, 20, 100, 30, "Button")
OpenWindow(1, 200, 200, 200, 100, "Window 1")
ButtonGadget(1, 10, 20, 100, 30, "Button")
OpenWindow(2, 300, 300, 200, 100, "Window 2")
ButtonGadget(2, 10, 20, 100, 30, "Button")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      appQuit = 1
      
    Case #PB_Event_Gadget
      ;for this example, when a button is pressed, 
      ;its window is made the current gadget list
      UseGadgetList(WindowID(EventWindow()))
      MessageRequester("UseGadgetList()", 
                       "Current gadget list: Window #" + 
                       Str(GadgetListWindow()))
  EndSelect
Until appQuit = 1
Hope it helps. :)

Re: Get Current #Window

Posted: Thu Jan 14, 2016 11:07 am
by Dude
You put the gadgets on the window, so you already know which window it is. Thus, store it in a variable for future use, such as when creating timers. ;)