MessageRequester on a separate thread (?)
MessageRequester on a separate thread (?)
How to issue a message in Windows, which will be a separate process not associated with the program?
I suppose it is possible to make a vbs script in the temp folder and execute it.
I need a way that does not block program events.
I suppose it is possible to make a vbs script in the temp folder and execute it.
I need a way that does not block program events.
Re: MessageRequester on a separate thread (?)
Perhaps, just use a separate window to emulate a message box. In this example, the message box window stays on top until dismissed, but the running clock in the main window demonstrates that it does not block the event loop:
Code: Select all
Enumeration windows
#mainWindow
#messageBox
EndEnumeration
Enumeration gadgets
#mainWindowButton
#mainWindowClock
#mainWindowTimer
#messageBoxButton
#messageBoxText
EndEnumeration
Global mainWindowFlags = #PB_Window_SystemMenu |
#PB_Window_SizeGadget |
#PB_Window_ScreenCentered |
#PB_Window_MaximizeGadget |
#PB_Window_MinimizeGadget
Procedure messageBox(title.s, message.s)
OpenWindow(#messageBox, 10, 10, 200, 150, title,
#PB_Window_WindowCentered, WindowID(#mainWindow))
TextGadget(#messageBoxText, 10, 30, 180, 100, message, #PB_Text_Center)
ButtonGadget(#messageBoxButton, 25, 100, 150, 30, "Close Message Box")
StickyWindow(#messageBox, #True)
EndProcedure
Procedure mainwindow()
OpenWindow(#mainWindow, 0, 0, 600, 400,"Main Window", mainWindowFlags)
TextGadget(#mainWindowClock, 10, 10, 580, 50, "00:00:00", #PB_Text_Right)
ButtonGadget(#mainWindowButton, 200, 60, 200, 30, "Show Message Box")
AddWindowTimer(#mainWindow, #mainWindowTimer, 1000)
EndProcedure
mainwindow()
Repeat
event = WaitWindowEvent()
Select EventWindow()
;handles all the events for the main window
Case #mainWindow
Select event
Case #PB_Event_CloseWindow
appQuit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case #mainWindowButton
messageBox("Message Box", "Message Box Text")
EndSelect
Case #PB_Event_Timer
Select EventTimer()
Case #mainWindowTimer
time.s = FormatDate("%hh:%ii:%ss", Date())
SetGadgetText(#mainWindowClock, time)
EndSelect
EndSelect
;handles all the events for the message box window
Case #messageBox
Select event
Case #PB_Event_CloseWindow
CloseWindow(#messageBox)
Case #PB_Event_Gadget
Select EventGadget()
Case #messageBoxButton
CloseWindow(#messageBox)
EndSelect
EndSelect
EndSelect
Until appQuit
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel
Re: MessageRequester on a separate thread (?)
Hey TI-994A,
you have created a toolwindow, in my opinion. If you want the effect of the MessageRequester() to come out better, then I would still recommend the use of DisableWindow() on the main window. With that the main window is not reacting on user actions and the clock is still running....
If you want to try it out, add the DisableWindow() as follows
you have created a toolwindow, in my opinion. If you want the effect of the MessageRequester() to come out better, then I would still recommend the use of DisableWindow() on the main window. With that the main window is not reacting on user actions and the clock is still running....
If you want to try it out, add the DisableWindow() as follows
Code: Select all
Procedure messageBox(title.s, message.s)
DisableWindow(#mainWindow, 1) ; <--- new
OpenWindow(#messageBox, 10, 10, 200, 150, title,
#PB_Window_WindowCentered, WindowID(#mainWindow))
; ....
; and in the main loop
; ...
;handles all the events for the message box window
Case #messageBox
Select event
Case #PB_Event_CloseWindow ; <-- this never happens, because of window flag above ...
CloseWindow(#messageBox)
DisableWindow(#mainWindow, 0)
Case #PB_Event_Gadget
Select EventGadget()
Case #messageBoxButton ; <-- the "Ok Button"
CloseWindow(#messageBox)
DisableWindow(#mainWindow, 0) ; <--- new
EndSelect
; ...
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Re: MessageRequester on a separate thread (?)
Hi Axolotl. Great suggestion; thank you. I'm sure that it would be a welcome addition to the feature, provided AZJIO finds the multi-window approach acceptable in the first place.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel
Re: MessageRequester on a separate thread (?)
Yes, I like your choice.
I temporarily did this:
I temporarily did this:
Code: Select all
tmp$ = "Title " + Lng(17) + " & @Echo off & @Echo. & Color 1e & @Echo. " + item$ + "& "
tmp$ = EscapeString(tmp$)
tmp$ = ReplaceString(tmp$, ")", "^)")
tmp$ = ReplaceString(tmp$, "(", "^(")
RunProgram("cmd.exe", "/c (" + tmp$ + " set /p Ok=^>^>)", "")
Re: MessageRequester on a separate thread (?)
The MessageRequester function blocks events because the handle of the existing window is automatically put as a parameter even if executed in another thread.
So you can just use the MessageBox API to get the desired result.
So you can just use the MessageBox API to get the desired result.
Code: Select all
Global thread
Procedure PopupMsg(v)
MessageBox_(0, "123", "456", #MB_OK | #MB_TOPMOST)
;If necessary, an event can be sent using PostEvent according to the response result.
thread = 0
EndProcedure
If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 200, 20, "Standard Button")
ButtonGadget(1, 10, 40, 200, 20, "Left Button", #PB_Button_Left)
ButtonGadget(2, 10, 70, 200, 20, "Right Button", #PB_Button_Right)
ButtonGadget(3, 10,100, 200, 60, "Multiline Button (longer text gets automatically wrapped)", #PB_Button_MultiLine)
ButtonGadget(4, 10,170, 200, 20, "Toggle Button", #PB_Button_Toggle)
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget And EventGadget() = 0
If thread = 0
thread = CreateThread(@PopupMsg(), 0)
Else
Debug "Close the previous Msgbox first."
EndIf
EndIf
Until event = #PB_Event_CloseWindow
EndIf
Re: MessageRequester on a separate thread (?)
Great alternatives, AZJIO & breeze4me. The suggested approach was just that; a suggestion. But it does have the advantage of being cross-platform.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel
Re: MessageRequester on a separate thread (?)
I was trying to see if there was a way to pass a pointer to a structure into the thread with the structure consisting of the title and message.
I guess I don't know what I am doing.
It would be rather slick to even get the icons to work.
I guess I don't know what I am doing.
It would be rather slick to even get the icons to work.
Re: MessageRequester on a separate thread (?)
Code: Select all
Global thread
Structure MyThreadMsg
Title.s
Text.s
Flags.i
EndStructure
Procedure PopupMsg(*v.MyThreadMsg)
MessageBox_(0, *v\Text, *v\Title, #MB_OK | #MB_TOPMOST | *v\Flags)
thread = 0
EndProcedure
If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 200, 20, "Standard Button")
ButtonGadget(1, 10, 40, 200, 20, "Left Button", #PB_Button_Left)
ButtonGadget(2, 10, 70, 200, 20, "Right Button", #PB_Button_Right)
ButtonGadget(3, 10,100, 200, 60, "Multiline Button (longer text gets automatically wrapped)", #PB_Button_MultiLine)
ButtonGadget(4, 10,170, 200, 20, "Toggle Button", #PB_Button_Toggle)
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget And EventGadget() = 0
If thread = 0
v.MyThreadMsg\Title = "test title"
v\Text = "text"
v\Flags = #MB_ICONASTERISK | #MB_YESNO | #MB_DEFBUTTON2
thread = CreateThread(@PopupMsg(), v)
Else
Debug "Close the previous Msgbox first."
EndIf
EndIf
Until event = #PB_Event_CloseWindow
EndIf
Re: MessageRequester on a separate thread (?)
That's great Breeze4me. Thank you, because I think it was going to bug me for hours, or likely days until I figured it out if at all.
procedure PopupMsg(*v.MyThreadMsg) was what I was getting wrong. I was just doing *v
procedure PopupMsg(*v.MyThreadMsg) was what I was getting wrong. I was just doing *v
Re: MessageRequester on a separate thread (?)
I figured out a way to retrieve the result.
probably there is a better way such as a custom event but there we have it. Nice!
Code: Select all
Global thread
Structure MyThreadMsg
Title.s
Text.s
Flags.i
Result.i
EndStructure
Procedure PopupMsg(*v.MyThreadMsg)
*v\Result = MessageBox_(0, *v\Text, *v\Title, #MB_OK | #MB_TOPMOST | *v\Flags)
thread = 0
EndProcedure
If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 200, 20, "Standard Button")
ButtonGadget(1, 10, 40, 200, 20, "Left Button", #PB_Button_Left)
ButtonGadget(2, 10, 70, 200, 20, "Right Button", #PB_Button_Right)
ButtonGadget(3, 10,100, 200, 60, "Multiline Button (longer text gets automatically wrapped)", #PB_Button_MultiLine)
ButtonGadget(4, 10,170, 200, 20, "Toggle Button", #PB_Button_Toggle)
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget And EventGadget() = 0
If thread = 0
v.MyThreadMsg\Title = "test title"
v\Text = "text"
v\Flags = #MB_ICONASTERISK | #MB_YESNO | #MB_DEFBUTTON2
thread = CreateThread(@PopupMsg(), v)
Else
Debug "Close the previous Msgbox first."
EndIf
EndIf
If v\Result
Debug v\Result
v\Result = 0
EndIf
Until event = #PB_Event_CloseWindow
Debug v\Result
EndIf
Re: MessageRequester on a separate thread (?)
In the topic title, you said a separate thread, but in your post, you said a separate process not associated with the program. These are entirely different. All the answers above are for a separate thread, but that thread will still be associated with the program, which is not what you wanted.
So which do you actually mean?
-
- Enthusiast
- Posts: 557
- Joined: Wed Sep 25, 2019 10:18 am
Re: MessageRequester on a separate thread (?)
Run a second program.
Code: Select all
; mymsg.out
MessageRequester(ProgramParameter(0),ProgramParameter(1))
Code: Select all
; Linux, please adapt filename.
RunProgram("/tmp/mymsg.out",Chr(34)+"Titel"+Chr(34)+" "+Chr(34)+ReplaceString("Text",#LF$,"\n")+Chr(34),"")
Please ask your questions, because switch on the cognition apparatus decides on the only known life in the universe.Wersten :DDüsseldorf NRW Germany Europe Earth Solar System Flake Bubble Orionarm
Milky Way Local_Group Virgo Supercluster Laniakea Universe
Milky Way Local_Group Virgo Supercluster Laniakea Universe