Page 1 of 1

initialize a module automatically

Posted: Tue Aug 27, 2024 11:17 am
by Denis
Hi,
I'd like to initialize a module automatically under Windows, i.e. when the program starts and closes, the Init and UnInit procedures I've coded will be executed without any external intervention.

I'm looking for events to use in the main loop or in a hook loop to do this.

Do you have any idea because I have not yet managed to do it.

Thanks in advance

Re: initialize a module automatically

Posted: Tue Aug 27, 2024 2:28 pm
by mk-soft
To initialise a module, you can simply call a procedure in the module.
However, it is a little more complicated with the release module.
Either you call a release function yourself, or you bind the event #PB_Event_CloseWindow. The problem here is that if the last window is not closed, the module is released.

Code: Select all

;-TOP

DeclareModule MyModule
  
EndDeclareModule

Module MyModule
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Import ""
      PB_Object_GetOrAllocateID(*Objects, ID)
      PB_Object_GetObject(*Objects, DynamicOrArrayID)
      PB_Object_IsObject(*Objects, DynamicOrArrayID)
      PB_Object_IsHandle(*Objects, *NativeHandle)
      PB_Object_EnumerateAll(*Objects, *ObjectEnumerateAllCallback, *pData)
      PB_Object_EnumerateStart(*Objects)
      PB_Object_EnumerateStartRecursive(*Objects)
      PB_Object_EnumerateNext(*Objects, *ID)
      PB_Object_EnumerateNextRecursive(*Objects, *ID)
      PB_Object_EnumerateAbort(*Objects)
      PB_Object_FreeID(*Objects, DynamicOrArrayID)
      PB_Object_CleanAll(*Objects)
      PB_Object_Init(StructureSize, IncrementStep, *ObjectFreeFunction)
      PB_Object_Count(*Objects)
      PB_Window_Objects
    EndImport
  CompilerElse
    ImportC ""
      PB_Object_GetOrAllocateID(*Objects, ID)
      PB_Object_GetObject(*Objects, DynamicOrArrayID)
      PB_Object_IsObject(*Objects, DynamicOrArrayID)
      PB_Object_IsHandle(*Objects, *NativeHandle)
      PB_Object_EnumerateAll(*Objects, *ObjectEnumerateAllCallback, *pData)
      PB_Object_EnumerateStart(*Objects)
      PB_Object_EnumerateStartRecursive(*Objects)
      PB_Object_EnumerateNext(*Objects, *ID)
      PB_Object_EnumerateNextRecursive(*Objects, *ID)
      PB_Object_EnumerateAbort(*Objects)
      PB_Object_FreeID(*Objects, DynamicOrArrayID)
      PB_Object_CleanAll(*Objects)
      PB_Object_Init(StructureSize, IncrementStep, *ObjectFreeFunction)
      PB_Object_Count(*Objects)
      PB_Window_Objects
    EndImport
  CompilerEndIf  
  
  Global IsInit
  
  Procedure ReleaseModule()
    Protected cntWindow
    cntWindow = PB_Object_Count(PB_Window_Objects)
    If cntWindow <= 1
      Debug #PB_Compiler_Module + "." + #PB_Compiler_Procedure + " Done."
      IsInit = #False
    EndIf
  EndProcedure
  
  Procedure InitModule()
    Debug #PB_Compiler_Module + "." + #PB_Compiler_Procedure + " Done."
    BindEvent(#PB_Event_CloseWindow, @ReleaseModule())
    IsInit = #True
  EndProcedure : InitModule()
  
EndModule

;-TOP

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(0)
  dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
  ; Resize Gadgets
EndProcedure

Procedure Main()
  Protected dx, dy
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Test Window", #WinStyle)
    ; MenuBar
    CreateMenu(0, WindowID(0))
    MenuTitle("File")
    
    ; StatusBar
    CreateStatusBar(0, WindowID(0))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(0)
    dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              Break
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()

Re: initialize a module automatically

Posted: Tue Aug 27, 2024 2:30 pm
by RASHAD
Hi
Maybe

Code: Select all

Case #PB_Event_ActivateWindow
  UseModule name
Case #PB_Event_DeactivateWindow
  UnuseModule name

Re: initialize a module automatically

Posted: Tue Aug 27, 2024 2:51 pm
by Axolotl
I am doing not much with modules. So maybe this does not work with modules, but I use this a lot in my programs.
For further explanations see the comments in the code.
HINT: To decode the messages you can use some example codes (found here on the forum) or you can use this magic database.

Code: Select all

Global g_CountDefaultMessges.i = 0 

Macro Trace(Message) 
  If IsGadget(0) : AddGadgetItem(0, -1, Message) : EndIf 
  Debug "Trace: " + Message  
EndMacro 

Procedure WinCallback(hWnd, uMsg, WParam, LParam)     
  Select uMsg 
    ; # 
    ; # Figure out which is the very first message you receive in your app. 
    ; # (for example it depends on the Gadgets you use.) 
    ; # 

    Case 799 ; #WM_DWMNCRENDERINGCHANGED  ; = 799 
      Trace("WM_DWMNCRENDERINGCHANGED  ") 

    Case #WM_ACTIVATE    : Trace("WM_ACTIVATE") 
    Case #WM_ACTIVATEAPP : Trace("WM_ACTIVATEAPP") 
    Case #WM_PAINT       : Trace("WM_PAINT") 
    Case #WM_GETICON     : Trace("WM_GETICON") 
    Case #WM_SIZE        : Trace("WM_SIZE") 

    ; #
    ; # I recommend one of the next two messages to call UnInit() 
    ; # both messages are always received in a windows program 
    ; # 
    Case #WM_NCDESTROY   : Trace("WM_NCDESTROY")  ; <-- not possible anymore because gadget is gone already 
      ; #
      ; # 
    Case #WM_DESTROY     : Trace("WM_DESTROY") 
      ; #
      ; # 

    Default 
      If g_CountDefaultMessges < 20   ; looking for the first messages we can catch with Callback() 
        Trace("WM_? <==> " + Str(uMsg))   
      EndIf 
      g_CountDefaultMessges + 1 
  EndSelect 
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 


Procedure main() 
  Protected event 
  ; #
  ; # Init() could be placed anywhere. i.e. here 
  ; #

  If OpenWindow(0, 0, 0, 600, 320, "Check on Window Messages...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ListViewGadget(0, 8, 8, 584, 304)
    SetWindowCallback(@WinCallback(), 0) 
    Repeat 
      event = WaitWindowEvent()        
    Until event = #PB_Event_CloseWindow
  EndIf 
  ProcedureReturn 0 
EndProcedure 

; # 
; # Init() could be placed anywhere. i.e. before the program starts anyway 
; # If there is another code outside a procedure, this Init() must be called first.  
; #
End main()  

Re: initialize a module automatically

Posted: Tue Aug 27, 2024 2:53 pm
by jacdelad
Maybe some RegisterMyFunctionforUninitialization(@MyFunction()), which is automatically called when the program ends (via "end" or no more code) would be a good idea?!

Re: initialize a module automatically

Posted: Tue Aug 27, 2024 5:04 pm
by Denis
Thank you all very much,

the real problem, as mk-soft pointed out, is when you want released the module.
mk-soft's approach is very good.
Perhaps it would be better to intercept #WM_DESTROY or better #WM_NCDESTROY in a hook procedure to released the module instead of #PB_Event_CloseWindow.

mk-soft, in which case the last window will not close and the module will be released ?


I will done some tests.
Thanks.

Re: initialize a module automatically

Posted: Tue Aug 27, 2024 5:17 pm
by jacdelad
A closing windows doesn't necessarily mean that the program ends as well!