Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by Mick P. »

Faced with a panoply of possibilities (yet again) I find myself wondering what is correct protocol :oops:

I need to implement modal logic, i.e. a procedure does not return until it completes a task, but it keeps the GUI operating also.

wxModalEventLoop seems to do this with also disabling existing windows. That is like a modal dialog. It just adds wxWindowDisabler to wxEventLoop.

I'm not sure what is required to work with wxEventLoop, or how it works. The available example code suggests merely constructing it is all that is required. Of course that can't be.

Secondly, I need to have a different kind of modal scenario that is less strict, doesn't disable the window, but I want it to be simple, so I want the caller to decide when the loop is done, so the caller calls a procedure continuously, that is akin Win32's PeekMessage. The reason is I don't want to C++11 lambda feature because the low-level API is C like, and I don't want the caller to have to write a predicate and pass it through, since that's too involved... in other words, the call site is like the lambda capture since it has everything it needs.

In this second case I'm not sure if wxEventLoop is required. I wonder if it is correct to use wxApp::GetMainLoop somehow, since it has a lot of functionality. In Win32 this is stupid simple, there is just GetMessage and PeekMessage and the former is just a convenience function. Sometimes simple is nice because it doesn't lend itself to a dizzying array of possibilities (that can only be answered by appeal to authority.)

(I'm biased, but I think Win32 implements UI very well compared to other systems. I wish that there was a cross-platform option that worked like Win32.)

EDITED: This is something every UI must do at some point, but I'm not sure if there is an example (sample) in this case: https://docs.wxwidgets.org/trunk/page_samples.html
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by ONEEYEMAN »

Hi,
Why not use wxThread or std::thread?

Thank you.
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by Mick P. »

ONEEYEMAN wrote: Sun Sep 01, 2019 4:42 pm Hi,
Why not use wxThread or std::thread?

Thank you.
Never would have occurred to me. Sounds like asking for trouble.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by ONEEYEMAN »

Hi,
What kind of trouble?
Please elaborate.

Or you never did do MT application?

Thank you.
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by Mick P. »

Sorry?
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by alys666 »

Mick P. wrote: Sun Sep 08, 2019 1:30 amSorry?
Multi threaded Application, imho.
to keep wxWidgets GUI working, while your long code is running, you must run it(your code) in separate thread as usual. Else gui cannot handle its messages.
ubuntu 20.04, wxWidgets 3.2.1
Manolo
Can't get richer than this
Can't get richer than this
Posts: 828
Joined: Mon Apr 30, 2012 11:07 pm

Re: Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by Manolo »

Case 1 The task blocks everything, GUI included, until it's completed.
Then code normally. No threads, no message-handling etc.
This approach may only be user-friendly if the task finishes in less than a second.

Case 2 The task blocks nothing.
There are several ways. For example you may call wxYield so as to some OS messages get proccessed. Or you can break the task into chuncks and between two chuncks check if the event-loop has events not proccesed yet.
The best way is doing the long task in a "worker" thread. If you need to cancel the task before the task is finished you can set a global flag and test if time to time from the worker thread.

The wx event handling is something like this:
When the OS sends a message to a window wxWidgets translates it to its own idiom and pushes it to the internal event loop. Then it searches for a handler for each event (those you "Bind()" to in your code); and if the handler doesn't call event.Skip() then the message dies, otherwise it is sent to another handler, if any.
Because the OS can send a lot of messages while your code hasn't finished handling them, wxWidgets has an "event loop". It not only stores pending messages, but also asks the OS for any pending message and if not then sends a "idle-event" (you can also handle this kind of event).
In MSW wxWidgets internally comunicates with the OS by GetMessage and PeekMessage, and some others.

It's a rare case if you need to use wxEventHandler directly.
Don't think of how adapt wxWidgets to MSW style, but how to use the very good features wx already implements, hidding the platform details.
Mick P.
Earned some good credits
Earned some good credits
Posts: 145
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by Mick P. »

alys666 wrote: Sun Sep 08, 2019 7:13 am
Mick P. wrote: Sun Sep 08, 2019 1:30 amSorry?
Multi threaded Application, imho.
to keep wxWidgets GUI working, while your long code is running, you must run it(your code) in separate thread as usual. Else gui cannot handle its messages.
Oh, well, my goal is primarily to be modal, that is to say, a procedure is called, and then the caller waits until it returns. So in that case it's not a matter of two things working at the same time. The caller is part of the UI, it just needs to interrupt it, but not halt the "message pump" either.
Manolo wrote: Sun Sep 08, 2019 12:50 pm Case 2 The task blocks nothing.
There are several ways. For example you may call wxYield so as to some OS messages get proccessed. Or you can break the task into chuncks and between two chuncks check if the event-loop has events not proccesed yet.
The best way is doing the long task in a "worker" thread. If you need to cancel the task before the task is finished you can set a global flag and test if time to time from the worker thread.
I think wxYield may be onto something useful. Under Win32 (Windows) the next message can be processed anywhere in the program. It's very easy to understand because the API is called GetMessage. Maybe wxYield is like this, I don't know. In most systems yielding means signaling to the thread/process manager (task scheduler) that your program wants to forfeit the remainder of its time.

(Maybe wxYield is something like GetMainLoop()->process_next_event, I don't know?)

It seems wxYield is deprecated. SafeYield may be what I'm looking for for my secondary scenario outlined in the OP.

https://docs.wxwidgets.org/3.0/group__g ... e6d848c27a

Yield is undocumented, so I can't really know if it has anything to do with keeping the message-pump alive or not:

https://docs.wxwidgets.org/3.0/classwx_ ... 70efc25020

Maybe I would have come across wxYield sooner if it were documented. SafeYield says it's just like Yield; Yield says nothing. I guess it's one of those cases where there is a tutorial document somewhere that is not WWW searchable.

Going by some forum posts in search results my impression is that it's related to the message-pump and not task-scheduling, but I have to do more searching. Thanks for the tip. I'm trying to navigate wxWidgets best I can. It's not always intelligible.

EDITED: For the record, I've since implemented the first scenario, and I only really wrote about it to contrast it to the second scenario. If wxYield works as I imagine it, the second scenario might be as simple as calling that in a loop. (Background: I'm trying to implement this as an extension to glutMainLoop so it can be called recursively to keep the UI going in a lightweight modal loop. In best case scenario it will just be able to call Yield/SafeYield and return. An example for doing this is to put a textbox in front of an element to temporarily edit it. I realize wxWidgets has facilities just for that, but it's just an example; the textbox can be OpenGL instead of a system window.)
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Q: Is wxEventLoop closest thing to Win32's GetMessage? How does it?

Post by ONEEYEMAN »

Hi,
Yes, wx{Safe}Yeild is exactly like you wrote:

Code: Select all

MessageLoop->ProcessNextMessage()
Thank you.
Post Reply