Additional parameter for WindowEvent and WaitWindowEvent

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
infratec
Always Here
Always Here
Posts: 7616
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Additional parameter for WindowEvent and WaitWindowEvent

Post by infratec »

I know this and it is OK.
An my programs only have one EventLoop.

The problem is If I want now to play MIDI I need a callback to a window when playing is finished.
I want an isolated solution, so that I don't have to modify the normal eventloop.
I tried it with BindEvent to a hidden window, but the needed event (#MM_MCINOTIFY) is not 'bindable'

If it is not possible to add a window (like a server to NetworkServerEvent() ) then it should be possible to bind any window event with
BindEvent().
User avatar
mk-soft
Always Here
Always Here
Posts: 6244
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Additional parameter for WindowEvent and WaitWindowEvent

Post by mk-soft »

You can intercept the event with a SetWindowCallback and send your own PostEvent signal to the hide window.

Update

Code: Select all

;-TOP

#ProgramTitle = "Main Window"
#Version = "v1.01.1"

Enumeration Windows
  #Main
  #HideWindow
EndEnumeration

Enumeration Menus
  #MainMenu
EndEnumeration

Enumeration MenuItems
  #MainMenuExitApplication
EndEnumeration

Enumeration Gadgets
  
EndEnumeration

Enumeration Status
  #MainStatusBar
EndEnumeration

Enumeration CustomEvent #PB_Event_FirstCustomValue
  #MyEvent_MCI_Notify
EndEnumeration

Global ExitApplication

; ----

Procedure DoEventsMain(Event)
  
  Select Event
    Case #PB_Event_CloseWindow
      ExitApplication = #True
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case #MainMenuExitApplication
          ExitApplication = #True
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
          
      EndSelect
      
  EndSelect
  
EndProcedure

Procedure DoEventsHideWindow(Event)
  
  Select Event
    Case #PB_Event_CloseWindow
      ; TODO
      CloseWindow(#HideWindow)
      
    Case #PB_Event_Menu
      Select EventMenu()
          
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
          
      EndSelect
      
    Case #PB_Event_Timer
      Select EventTimer()
        Case 1
          Debug "Timer"
          
      EndSelect
    Case #MyEvent_MCI_Notify
      ; hWnd = EventGadget
      ; wParam = Eventtype
      ; lParam = EventData
      Select EventType()
        Case #MCI_NOTIFY_ABORTED
          ; todo
        Case #MCI_NOTIFY_FAILURE
          ; todo
        Case #MCI_NOTIFY_SUCCESSFUL
          ; todo
        Case #MCI_NOTIFY_SUPERSEDED
          ; todo
      EndSelect
      
  EndSelect
  
EndProcedure

; ----

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
  ; Resize gadgets
  
EndProcedure

; ----
  
Procedure WinCallback(hWnd, uMsg, wParam, lParam) 
  Protected Result = #PB_ProcessPureBasicEvents
  Select uMsg
    Case #MM_MCINOTIFY
      PostEvent(#MyEvent_MCI_Notify, #HideWindow, hWnd, wParam, lParam)
      
  EndSelect
  
  ProcedureReturn Result
EndProcedure 


Procedure OpenHideWindow()
  If OpenWindow(#HideWindow, 0, 0, 0, 0, "EventTimer", #PB_Window_Invisible, WindowID(#Main))
    AddWindowTimer(#HideWindow, 1, 1000)    
  EndIf
EndProcedure

Procedure Main()
  Protected dx, dy

  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
    ; Menu
    CreateMenu(#MainMenu, WindowID(#Main))
    MenuTitle("File")
    MenuItem(#MainMenuExitApplication, "E&xit")
    ; For Mac
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      If Not IsMenu(#MainMenu)
        CreateMenu(#MainMenu, WindowID(#Main))
      EndIf
      MenuItem(#PB_Menu_About, "")
      MenuItem(#PB_Menu_Preferences, "")
    CompilerEndIf
    ; StatusBar  
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    StatusBarText(#MainStatusBar, 0, " " + #Version)
    ; Gadgets
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
    
    ; Bind events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
    
    OpenHideWindow()
    SetWindowCallback(@WinCallback())
    
    ; Main loop
    Repeat
      Event = WaitWindowEvent()
      Select EventWindow()
        Case #Main
          DoEventsMain(Event)
        Case #HideWindow
          DoEventsHideWindow(Event)
          
      EndSelect
      
    Until ExitApplication
    
  EndIf
  
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Fred
Administrator
Administrator
Posts: 18207
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Additional parameter for WindowEvent and WaitWindowEvent

Post by Fred »

You can also specify the window number in SetWindowCallback() if you don't want to set a global one.
Fred
Administrator
Administrator
Posts: 18207
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Additional parameter for WindowEvent and WaitWindowEvent

Post by Fred »

infratec wrote: Tue Jun 10, 2025 10:47 am If it is not possible to add a window (like a server to NetworkServerEvent() ) then it should be possible to bind any window event with
BindEvent().
No it's not possible as well, because native events are not handled the same way than PB one. Installing a specific window callback is the only supported way if you want to deal with native events.
infratec
Always Here
Always Here
Posts: 7616
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Additional parameter for WindowEvent and WaitWindowEvent

Post by infratec »

The problem is ... I still need an EventLoop:

Code: Select all

Procedure MIDIWindowCallback(hWnd.i, uMsg.i, WParam.i, LParam.i)
  
  Debug uMsg
  
  If uMsg = #MM_MCINOTIFY
    MIDIEnd = #True
  EndIf
  
  ProcedureReturn #False
  
EndProcedure

Filename$ = OpenFileRequester("Choose a MIDI file", "", "MIDI|*.mid", 0)
If Filename$
  hwin = OpenWindow(#PB_Any, 0, 0, 20, 20, "midi", #PB_Window_Invisible)
  If hwin
    SetWindowCallback(@MIDIWindowCallback(), hwin)
    playMIDIFile(WindowID(hwin), Filename$)
    Repeat  
      Delay(10)
      ;WindowEvent()
    Until MIDIEnd
    SetWindowCallback(0, hwin)
    CloseWindow(hwin)
  EndIf
EndIf
Without WindowEvent() I never reach the callback.

If I use the MIDI playback in an include file, how can I detect if an EvetLoop is available or not.
My current test programm generates a MIDI morsecode file without a GUI.
So I need WindowEvent()
But if I use this function in a GUI program, I have to avoid this.
Any idea ?
Post Reply