[Solved] #PB_ANY or Gadget creation limitations

Just starting out? Need help? Post your questions and find answers here.
jimcorr
New User
New User
Posts: 5
Joined: Sun Dec 14, 2014 11:38 pm

[Solved] #PB_ANY or Gadget creation limitations

Post by jimcorr »

It all started with me wondering if i created windows and gadgets all using #pb_any and the user working for several days opening and closing windows if it would be unlimited.

I created a code that opens and closes the same window for 500 times and i receive 0 from the gadget creation at some point.

Is it a limitation, of what? Or am i doing something wrong?

PS: this is a simplified version of the final code with the minimal parts for execution.

thanks,

Code: Select all

DeclareModule mglobal
  Enumeration #PB_Event_FirstCustomValue
    #EventBeginProcessing
    #EventUpdateThread
    #EventProcessingFinished
    #EventAtualizaGui
  EndEnumeration
  
  Define vi_tp_db.i
  vi_tp_db = 0
  
EndDeclareModule
Module mglobal
  
EndModule

DeclareModule mwnd
  
  Structure st_gadgets
    ;vs_nm_gadget.s ja eh a chave...
    vq0_id_gadget.q
  EndStructure
  
  Structure st_properties
    vq0_id_window.q
    vq0_handle.q
    vq0_close_window.q
    vs_nm_modulo.s
    vi_id_retorno_thread.i
    vs_nm_retorno_thread.s
    Map vm_gadgets.st_gadgets()
  EndStructure
  
  Define vq0_id_mae.q
  
  Declare.q create_window(*vst_properties.st_properties, pid_estrutura.q, pq0_id_window.q) 
  Declare.q create_gadget(*vst_properties.st_properties, pnm_gadget.s, pq0_gadget.q)
  
  Macro ID_Gadget(pnm_gadget)
    *vst_window\vst_properties\vm_gadgets(pnm_gadget)\vq0_id_gadget
  EndMacro
  
  Macro ID_Window()
    *vst_window\vst_properties\vq0_id_window
  EndMacro
  
  Macro ID_Handle()
    *vst_window\vst_properties\vq0_handle
  EndMacro
  
  Macro Add_Window(pq0_id_window)
    mwnd::create_window(*vst_window\vst_properties, *vst_window, pq0_id_window) 
  EndMacro
  
  Macro ADD_Gadget(pnm_gadget, pid_gadget)
    mwnd::create_gadget(*vst_window\vst_properties, pnm_gadget, pid_gadget) 
  EndMacro
  
  Define vq0_id_ult_janela.q
  
EndDeclareModule
Module mwnd
  EnableExplicit
  
  Procedure.q create_gadget(*vst_properties.st_properties, pnm_gadget.s, pq0_gadget.q)
    
    Define vq0_id_procedure.q    
    
    If pq0_gadget > 0
      *vst_properties\vm_gadgets(pnm_gadget)\vq0_id_gadget = pq0_gadget
      
      vq0_id_procedure = GetRuntimeInteger(*vst_properties\vs_nm_modulo + "::" + pnm_gadget + "_event()")
      If vq0_id_procedure
        BindGadgetEvent(pq0_gadget, vq0_id_procedure)
      EndIf      
      
    Else
      Debug "fail to create gadget: " + pnm_gadget + "id: " + pq0_gadget
      End
    EndIf
    
    ProcedureReturn pq0_gadget
    
  EndProcedure
  
  Procedure.q create_window(*vst_properties.st_properties, pid_estrutura.q, pq0_id_window.q)
    
    Define vq0_id_procedure.q
    
    If pq0_id_window
      *vst_properties\vq0_handle = WindowID(pq0_id_window)
      *vst_properties\vq0_id_window = pq0_id_window
      
      vq0_id_procedure = GetRuntimeInteger(*vst_properties\vs_nm_modulo + "::" + "window_event()")
      If vq0_id_procedure
        BindEvent(#PB_Event_CloseWindow, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_SizeWindow, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_MoveWindow, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_MinimizeWindow, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_RestoreWindow, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_ActivateWindow, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_DeactivateWindow, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_WindowDrop, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_RightClick, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_LeftClick, vq0_id_procedure, pq0_id_window)
        BindEvent(#PB_Event_LeftDoubleClick, vq0_id_procedure, pq0_id_window)
      EndIf
      
      SetWindowData(pq0_id_window, pid_estrutura)
      
      mwnd::vq0_id_ult_janela = pq0_id_window
    EndIf

    ProcedureReturn pq0_id_window
  EndProcedure
 
  
EndModule

;do programa atual
DeclareModule mimporta_csv
  
  Structure st_thread_csv
    vq0_id_ativo.q
    vq0_id_dados_ativos.q
    vs_descricao_dados_ativos.s
    vs_fl_sobrescrever.s
    vs_nm_arquivo.s
    vs_origem_dados.s
    vi_pc_barra.i
    vq0_id_window.q
  EndStructure
  
  Structure st_window
    vst_properties.mwnd::st_properties
    vst_thread_csv.st_thread_csv

  EndStructure  
  
  Declare init() 
  Declare clique_importar()
  Declare clique_destino()
  Declare thread_importa_csv(*xxx.st_window)
  Declare callback_thread() 
  
  Global vs_nm_modulo.s = "mimporta_csv"
  
  
EndDeclareModule
Module mimporta_csv
  
  EnableExplicit
  
  Procedure destroy()
    Define *vst_window.st_window = GetWindowData(EventWindow())
    
    FreeStructure(*vst_window)
    
  EndProcedure
  
  Procedure callback_thread()
    Define *vst_window.st_window = GetWindowData(EventWindow())
    
    If Event() = mglobal::#EventUpdateThread 
      SetGadgetState(mwnd::ID_Gadget("pb_importacao"), *vst_window\vst_thread_csv\vi_pc_barra)
    ElseIf Event() = mglobal::#EventProcessingFinished
      SetGadgetText(mwnd::ID_Gadget("txt_log"), GetGadgetText(mwnd::ID_Gadget("txt_log")) + #CRLF$ +  "Fim: " + FormatDate("%hh:%ii:%ss", Date()))
      
      SetGadgetState(mwnd::ID_Gadget("pb_importacao"), 100)
      DisableGadget(mwnd::ID_Gadget("btn_iniciar"), #False)
      DisableWindow(mwnd::ID_Window(), #False)
      MessageRequester("Fim", "Operação Finalizada!")
      SetGadgetState(mwnd::ID_Gadget("pb_importacao"), 0)
    EndIf
  EndProcedure
  
  Procedure prepara_tela(ps_destino.s, *vst_window.st_window)
    
    If ps_destino = "rb_base"
      
      DisableGadget(mwnd::ID_Gadget("cmb_ativo"), #False)
      DisableGadget(mwnd::ID_Gadget("edt_id_dados_ativo"), #False)
      DisableGadget(mwnd::ID_Gadget("edt_descricao_dados_ativo"), #False)
      DisableGadget(mwnd::ID_Gadget("btn_id_dados_ativo"), #False)
      DisableGadget(mwnd::ID_Gadget("btn_limpa_dados_ativo"), #False)
      DisableGadget(mwnd::ID_Gadget("edt_nm_arquivo_db"), #True)
      DisableGadget(mwnd::ID_Gadget("btn_db"), #True)
      
    Else
      
      DisableGadget(mwnd::ID_Gadget("cmb_ativo"), #True)
      DisableGadget(mwnd::ID_Gadget("edt_id_dados_ativo"), #True)
      DisableGadget(mwnd::ID_Gadget("edt_descricao_dados_ativo"), #True)
      DisableGadget(mwnd::ID_Gadget("btn_id_dados_ativo"), #True)
      DisableGadget(mwnd::ID_Gadget("btn_limpa_dados_ativo"), #True)
      DisableGadget(mwnd::ID_Gadget("edt_nm_arquivo_db"), #False)
      DisableGadget(mwnd::ID_Gadget("btn_db"), #False)      
      
    EndIf
    
  EndProcedure
  
  Procedure init()
    
    Define *vst_window.st_window
    *vst_window.st_window = AllocateStructure(st_window)
    *vst_window\vst_properties\vs_nm_modulo = vs_nm_modulo

    If mwnd::Add_Window(OpenWindow(#PB_Any, 100, 300, 500, 440, "Importa CSV", 
                                   #PB_Window_MinimizeGadget | #PB_Window_WindowCentered | #PB_Window_Invisible, 
                                   WindowID(mwnd::vq0_id_mae)))    
      
      BindEvent(mglobal::#EventProcessingFinished, @callback_thread(), mwnd::ID_Window())
      BindEvent(mglobal::#EventUpdateThread, @callback_thread(), mwnd::ID_Window())
      
      mwnd::ADD_Gadget("frm_origem", FrameGadget(#PB_Any, 5, 10, 490, 90, "CSV Origem"))
      
      mwnd::ADD_Gadget("frm_formato_dados", FrameGadget(#PB_Any, 10, 25, 195, 40, "Formato dos dados"))
      mwnd::ADD_Gadget("rb_mt5", OptionGadget(#PB_Any, 25, 40, 60, 20, "MT5"))
      mwnd::ADD_Gadget("rb_profit", OptionGadget(#PB_Any, 105, 40, 70, 20, "Profit"))
      SetGadgetState(mwnd::ID_Gadget("rb_mt5"), 1)
      
      mwnd::ADD_Gadget("lbl_csv", TextGadget(#PB_Any, 10, 72, 200, 24, "Arquivo"))
      mwnd::ADD_Gadget("edt_nm_arquivo_csv", StringGadget(#PB_Any, 70, 70, 390, 22, ""))
      mwnd::ADD_Gadget("btn_csv", ButtonGadget(#PB_Any, 469, 69, 20, 24, "..."))
      
      mwnd::ADD_Gadget("frm_destino_dados", FrameGadget(#PB_Any, 5, 105, 195, 40, "Destino Importação"))
      mwnd::ADD_Gadget("rb_base", OptionGadget(#PB_Any, 20, 120, 70, 20, "DB Base"))
      mwnd::ADD_Gadget("rb_db", OptionGadget(#PB_Any, 100, 120, 70, 20, "DB SQLite Avulso"))
      SetGadgetState(mwnd::ID_Gadget("rb_base"), 1)
      BindGadgetEvent(mwnd::ID_Gadget("rb_base"), @clique_destino())    
      BindGadgetEvent(mwnd::ID_Gadget("rb_db"), @clique_destino())    
      
      mwnd::ADD_Gadget("frm_arquivo_db", FrameGadget(#PB_Any, 5, 150, 490, 50, "Informações DB SQLite Avulso"))
      
      mwnd::ADD_Gadget("lbl_db", TextGadget(#PB_Any, 10, 172, 200, 24, "Arquivo"))
      mwnd::ADD_Gadget("edt_nm_arquivo_db", StringGadget(#PB_Any, 70, 170, 390, 22, ""))
      mwnd::ADD_Gadget("btn_db", ButtonGadget(#PB_Any, 469, 169, 20, 24, "..."))
      
      mwnd::ADD_Gadget("frm_dados_ativo", FrameGadget(#PB_Any, 5, 205, 490, 110, "Informações DB Base"))
      
      mwnd::ADD_Gadget("lbl_id_ativo", TextGadget(#PB_Any, 10, 227, 200, 24, "Ativo"))
      ; TODO isso aqui deveria carregar atraves de um select...
      mwnd::ADD_Gadget("cmb_ativo", ComboBoxGadget(#PB_Any, 70, 225, 200, 22))
      AddGadgetItem(mwnd::ID_Gadget("cmb_ativo"), -1,"Mini Índice B3")
      SetGadgetItemData(mwnd::ID_Gadget("cmb_ativo"), CountGadgetItems(mwnd::ID_Gadget("cmb_ativo")) - 1, 1)
      AddGadgetItem(mwnd::ID_Gadget("cmb_ativo"), -1,"Mini Dólar B3")
      SetGadgetItemData(mwnd::ID_Gadget("cmb_ativo"), CountGadgetItems(mwnd::ID_Gadget("cmb_ativo")) - 1, 2)
      SetGadgetState(mwnd::ID_Gadget("cmb_ativo"), 0)
      
      
      mwnd::ADD_Gadget("lbl_id_dados_ativo", TextGadget(#PB_Any, 12, 257, 200, 24, "ID"))
      mwnd::ADD_Gadget("edt_id_dados_ativo", StringGadget(#PB_Any, 70, 255, 70, 22, ""))
      
      mwnd::ADD_Gadget("btn_id_dados_ativo", ButtonGadget(#PB_Any, 144, 254, 20, 24, "..."))
      mwnd::ADD_Gadget("btn_limpa_dados_ativo", ButtonGadget(#PB_Any, 166, 254, 20, 24, "X"))
      
      mwnd::ADD_Gadget("lbl_descricao_dados_ativo", TextGadget(#PB_Any, 12, 287, 200, 24, "Descrição"))
      mwnd::ADD_Gadget("edt_descricao_dados_ativo", StringGadget(#PB_Any, 70, 285, 420, 22, ""))
      
      
      mwnd::ADD_Gadget("btn_iniciar", ButtonGadget(#PB_Any, 10, 320, 100, 24, "Importar"))
      BindGadgetEvent(mwnd::ID_Gadget("btn_iniciar"), @clique_importar())    
      
      mwnd::ADD_Gadget("pb_importacao", ProgressBarGadget(#PB_Any, 115, 321, 373, 22, 0, 100, #PB_ProgressBar_Smooth))
      SetGadgetState(mwnd::ID_Gadget("pb_importacao"), 0)
      
      mwnd::ADD_Gadget("txt_log", EditorGadget(#PB_Any, 10, 350, 480, 85))
      DisableGadget(mwnd::ID_Gadget("txt_log"), #True)

      
      SetActiveGadget(mwnd::ID_Gadget("rb_base"))
      prepara_tela("rb_base", *vst_window.st_window)
      
      ;HideWindow(mwnd::ID_Window(), #False)
      
    Else
      MessageRequester("Error!", "Error...!")      
    EndIf
    
  EndProcedure
  
  Runtime Procedure window_event()

    Select Event()
      Case #PB_Event_CloseWindow
        destroy()
        CloseWindow(EventWindow())
    EndSelect
    
  EndProcedure
  
    
  Runtime Procedure rb_profit_event()
    Define *vst_window.st_window = GetWindowData(EventWindow())
    
    Select EventType()
      Case -#PB_EventType_LeftClick 
        MessageRequester("", "Não implementado!")
        SetGadgetState(mwnd::ID_Gadget("rb_mt5"), 1)
    EndSelect
    
  EndProcedure        
    
    Procedure clique_destino()
      If  EventType() = #PB_EventType_LeftClick
        Define *vst_window.st_window = GetWindowData(EventWindow())
        Select EventGadget()
          Case mwnd::ID_Gadget("rb_base")
            prepara_tela("rb_base", *vst_window.st_window)
          Default
            prepara_tela("rb_db", *vst_window.st_window)
        EndSelect
      EndIf      
    EndProcedure
    
    Runtime Procedure btn_csv_event()
    EndProcedure
    
  
  Procedure clique_importar()
    

    
  EndProcedure  

  
  Procedure thread_importa_csv(*vst_window.st_window) 
  EndProcedure
    
EndModule


DeclareModule mapp
  Declare init()
  Declare destroy()
  Declare test()
  Declare load_connections()
  
  Define vs_nm_dir_dados.s
  Define vs_nm_dir_logs.s
  Define vs_nm_dir_csv.s
  
EndDeclareModule
Module mapp
  EnableExplicit
  
  ;eh global do modulo, nao da aplicacao toda, fica inacessivel para fora...
  Global vq0_id_menu.q
  
  Procedure executa_menu()
    Define item.i
    
    item = EventMenu()
    
    If item = 1 
      test()
    EndIf
    
    ;End
  EndProcedure
  
  Procedure init()
    ;abrir uma janela init, que será a base do sistema...
    Define event.i
    Define quit.i
    
    load_connections()
    
    mwnd::vq0_id_mae = OpenWindow(#PB_Any, 0, 0, 800, 600, "Main", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_Invisible)
    SetWindowState(mwnd::vq0_id_mae, #PB_Window_Maximize)
    HideWindow(mwnd::vq0_id_mae, #False)
    
    vq0_id_menu = CreateMenu(#PB_Any, WindowID(mwnd::vq0_id_mae))
    If vq0_id_menu
      MenuTitle("Geral")
        MenuItem(1, "Test")
        BindMenuEvent(vq0_id_menu, 1, @executa_menu())
    EndIf
    
    Repeat
      Event = WaitWindowEvent()
      If Event = #PB_Event_CloseWindow
        If EventWindow() = mwnd::vq0_id_mae
          destroy()
        EndIf
      EndIf
    Until Quit = 1    
  EndProcedure
  
  Procedure destroy()
    ; TODO precisa ver o que mais temos que fazer free, para nao ficar leak de memoria...
    End
  EndProcedure
  
  Procedure load_connections()

  EndProcedure
  
  Procedure test()
    Define i.i
    
    For i = 1 To 500
      ;it'll create the window but it wont show it, just set it's gadget id on  mwnd::vq0_id_ult_janela
      mimporta_csv::init()
      Debug Str(i) + ": " + mwnd::vq0_id_ult_janela
      ;send event to close the window
      PostEvent(#PB_Event_CloseWindow, mwnd::vq0_id_ult_janela, #PB_Ignore)
    Next i
  EndProcedure
EndModule

mapp::init()

End
Last edited by jimcorr on Wed Sep 03, 2025 1:41 pm, edited 1 time in total.
Axolotl
Addict
Addict
Posts: 841
Joined: Wed Dec 31, 2008 3:36 pm

Re: #PB_ANY or Gadget creation limitations

Post by Axolotl »

I would always assume that everything has a maximum value, even if the maximum values can be very large.
Just some thoughts about this.... (You don't have to agree with me)
There is a reason why there are return values that also represent an error case.
When dealing with dynamic objects, you have to pay particular attention to resource consumption. (You learned this when programming under Win16, where pens and brushes ran out faster than you could blink.)
Use a tool (e.g., Task Manager) to monitor consumption.
The longer the program runs continuously, the more important this becomes.
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
jimcorr
New User
New User
Posts: 5
Joined: Sun Dec 14, 2014 11:38 pm

Re: #PB_ANY or Gadget creation limitations

Post by jimcorr »

Thanks for the answer, Axolotl, i'll keep that in mind

I found out that the issue was due to the fact that i was doing it inside a for and it wasn't processing the closewindow events, therefore, the windows were not being closed.

Once i closed the window, i was able to recreate the window as many times as needed.
Last edited by jimcorr on Wed Sep 03, 2025 6:54 pm, edited 1 time in total.
Fred
Administrator
Administrator
Posts: 18247
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: [Solved] #PB_ANY or Gadget creation limitations

Post by Fred »

also all your '.q' type is wrong, it should be '.i' (or better, nothing as specified in the doc)
jimcorr
New User
New User
Posts: 5
Joined: Sun Dec 14, 2014 11:38 pm

Re: [Solved] #PB_ANY or Gadget creation limitations

Post by jimcorr »

Thanks, Fred, i'll fix that too.
SMaag
Enthusiast
Enthusiast
Posts: 325
Joined: Sat Jan 14, 2023 6:55 pm
Location: Bavaria/Germany

Re: [Solved] #PB_ANY or Gadget creation limitations

Post by SMaag »

maybe you explain what is your goal.
Your code looks complicated and it is not the best for debugging.
I'm sure there are more clear solutions for your problem.
Post Reply