Page 2 of 2
Re: Additional parameter for WindowEvent and WaitWindowEvent
Posted: Tue Jun 10, 2025 10:47 am
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().
Re: Additional parameter for WindowEvent and WaitWindowEvent
Posted: Tue Jun 10, 2025 11:56 am
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()
Re: Additional parameter for WindowEvent and WaitWindowEvent
Posted: Tue Jun 10, 2025 12:29 pm
by Fred
You can also specify the window number in SetWindowCallback() if you don't want to set a global one.
Re: Additional parameter for WindowEvent and WaitWindowEvent
Posted: Tue Jun 10, 2025 12:37 pm
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.
Re: Additional parameter for WindowEvent and WaitWindowEvent
Posted: Tue Jun 10, 2025 7:57 pm
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 ?