Creating custom message types in win32? - c++

Is there a way to define and send custom message types in Win32, to be caught by your Main message handler? For example, my main message handler captures messages such as WM_PAINT, WM_RESIZE, WM_LBUTTONDOWN etc. Can I create my own WM_DOSOMETHING? If so, how would I send this message?
Ah, I actually just discovered this was asked before here, however, it doesn't answer how I would actually send this message.

Woah, let's just stop and think here...
First of all, Windows itself sends messages in the WM_USER+n range, that's why WM_APP was invented (I found this out the hard way). But it gets worse... there's nothing to stop badly behaved applications broadcasting WM_USER+n or WM_APP+n messages, and because human beings stole the crystal of infinite stupidity from the Gods, this does indeed happen in the real world.
So, repeat after me, the only safe message is one I define myself and can only see myself. Use RegisterWindowMessage. And even then, be untrusting. When I need a string to define a RegisterWindowMessage, I use GUIDGEN to create the string and put a human-readable app-specific prefix on the resulting gobbledygook to help me differentiate multiple messages in the code.
Bet on the stupidity of your fellow humans - it's always a winning bet.
If you want authoritative background on this whole topic, see here. No that's not my website, it's Joe Newcomer's.

Yes. Just declare a constant in the WM_USER range e.g.
#define WM_RETICULATE_SPLINES (WM_USER + 0x0001)
You can also register a message by name using the RegisterWindowMessage API.
You can then send these messages using SendMessage, PostMessage or any of their variants.

If you created the window class, you can use the WM_USER range (or WM_APP)
If it is not your class, you can use WM_APP
If you want to broadcast the message to every top level window, register your own global message with RegisterWindowMessage

Related

Change GUI in thread

I have an operation which ends in about 20 seconds. To avoid freezing, I want to create a thread and update a label text in it every second. I searched a lot, since everyone has different opinion, I couldn't decide which method to use.
I tried SendMessage and it works but some people believe that using SendMessage is not safe and I should use PostMessage instead. But PostMessage fails with ERROR_MESSAGE_SYNC_ONLY (1159).
char text[20] = "test text";
SendMessage(label_hwnd, WM_SETTEXT, NULL, text);
I searched about this and I think it's because of using pointers in PostMessage which is not allowed. That's why it fails.
So, what should I do? I'm confused. What do you suggest? Is this method is good for change UI elements in other thread?
Thanks
The documentation for ERROR_MESSAGE_SYNC_ONLY says:
The message can be used only with synchronous operations.
This means that you can use synchronous message delivery, i.e. SendMessage and similar, but you cannot use asynchronous message delivery, i.e. PostMessage.
The reason is that WM_SETTEXT is a message whose parameters include a reference. The parameters cannot be copied by value. If you could deliver WM_SETTEXT asynchronously then how would the system guarantee that the pointer that the recipient window received was still valid?
So the system simply rejects your attempt to send this message, and indeed any other message that has parameters that are references.
It is reasonable for you to use SendMessage here. That will certainly work.
However, you are forcing your worker thread to block on the UI. It may take the UI some time to update the caption's text. The alternative is to post a custom message to the UI thread that instructs the UI thread to update the UI. Then your worker thread thread can continue its tasks and let the UI thread update in parallel, without blocking the worker thread.
In order for that to work you need a way for the UI thread to get the progress information from the worker thread. If the progress is as simple as a percentage then all you need to do is have the worker thread write to, and the UI thread read from, a shared variable.
Well, the error says it all. The message cannot be sent asynchronously. The thing about PostMessage is that it posts the message to the listening thread's queue and returns immediately, without waiting for the result of message processing. SendMessage on the other hand, waits until the window procedure finishes processing the message and only then it returns.
The risk of using PostMessage in your case is that before window procedure processes the message you may have deallocated the string buffer. So it is safer to use SendMessage in this instance and that's what MS developers probably thought about when they decided not to allow asynchronous posting of this particular message.
EDIT: Just to be clear, of course this doesn't eliminate the risk of passing a naked pointer totally.
From MSDN
If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters cannot include pointers. Otherwise, the operation will fail.
The asynch PostMessage() alternative requires that the lifetime of the data passed in the parameters is extended beyond the message originator function. The 'classic' way of doing that is to heap-allocate the data, PostMessage a pointer to it, handle the data in the message-handler in the usual way and then delete it, (or handle it in some other way such that it does not leak). In other words, 'fire and forget' - you must not touch the data in the originating thread after the PostMessage has been issued.
The upside is that PostMessage() allows the originating thread to run on 'immediately' and so do further work, (maybe posting more messages). SendMessage() and such synchronous comms can get held up if the GUI is busy, imacting overall throughput.
The downside is that a thread may generate mesages faster than the GUI can process them. This usually manifests to the by laggy GUI responses, especially when performing GUI-intenisve work like moving/resizing windows and updating TreeViews. Eventually, the PostMessage call will fail when 10,000+ messages are queued up. If this is found to be a problem, additional flow-control may have to be added, so further complicating the comms, ( I usually do that by using a fixed-size object pool to block/throttle the originating thread if all available objects are stuck 'in transit' in posted, but unhandled, messages.
I think you can use SendMessage safely here. Then you don't need to worry about memory persistence for your string and other issues.
SendMessage is not safe when you send messages from another message handler or send message to blocked GUI thread, but if in your case you know it is safe - just use it
This is not a problem with the PostMessagebut a problem with the message you are sending - WM_SETTEXT. First a common misconception is that if you SendMessage() to a control from a thread, it is different from calling GUI API, it is in fact NOT. When you call a GUI API (from anywhere) for example to set text, windows implement this in the form of SendMessage() call. So when you are sending the same message, it is essentially same as calling the API. Although directly GUI access like this works in many ways it is not recommended. For this reason, I would beg to disagree with the accepted answer by #David.
The correct way is (code on the fly)
char* text = new char[20]
strcpy_s(text, "test text");
PostMessage(label_hwnd, IDM_MY_MSG_UPDATE_TEXT, NULL, text);
you will updated the text in your own message IDM_MY_MSG_UPDATE_TEXT handler function and delete the memory.

Remove Extra Expose Messages From X11 Queue

I have a program that has a thread that generates Expose messages using XSendEvent. A second thread receives the Expose messages along with other messages (mainly input handling). The problem is that the sending thread sends the Expose messages at a constant rate (~60Hz) but the receiving thread may be rendering slower than that. The X11 queue will get bogged down with extra Expose messages, and any input handling messages will start fall way behind all those extra Expose messages.
In Windows, this is not a problem because Windows will automatically coalesce all WM_PAINT messages into a single message. Is there any way to do this in X11, or some other way to solve this problem?
You can very easily coalesce any kind of event yourself with XCheckTypedEvent() and friends.
I was able to solve this problem as follows:
Block the rendering thread using XPeekEvent.
When an event comes in, read all events into a new queue data structure using a combination of XPending and XNextEvent, but only copy the first expose message.
Then run the event processing loop over the new queue data structure.
This fixed the problem for me, but I think a solution that uses XCheckTypedEvent (per n.m.'s answer here) is probably more elegant.
A few of thing you can do:
If you are doing complete redraw for each event, only action events with a count of 0, count > 1 is the redraw of a particular rectange
If you generate expose events for part of the window, this will reduce the amount of work each expose event does
The constant rate, means you could just process every nth event or keep a time since the last event and ignore events received within a given time

How to find who generated a windows message

We have a very large, complex MFC application.
For some reason a particular mode for running our application is generating WM_SIZE messages to the window. It should not be happening and is killing performance.
I can see the message getting handled. How can I find what or where in the code, is generating the window message?
Note: it tends to happen when we have a performance monitoring tool hooked into the application. So it might be the third party tool doing it.
But it only happens in this one particular mode of operation so it might be some sort of strange interaction.
You could see message map to specify for which all windows onSize has been mapped.
as an 'not elegant' alternative, you could trape WM_ONSIZE in PreTranslateMessage and see windows handle using hwnd member of pMsg structure being passed in PreTranslateMessage.
How would it help to know who sends the message? I would rather focus on a solution, such as delay processing of the message (assuming this processing is responsible for the perf hit) when an avalanche of such messages is detected.
e.g. If you receive too many messages within x milliseconds, you may decide to start a timer and process only the last message receives when the timer elapses. This way, you process max one message per x milli-seconds instead of each one.

C++ - Totally suspend windows application

I am developing a simple WinAPI application and started from writing my own assertion system.
I have a macro defined like ASSERT(X) which would make pretty the same thing as assert(X) does, but with more information, more options and etc.
At some moment (when that assertion system was already running and working) I realized there is a problem.
Suppose I wrote a code that does some action using a timer and (just a simple example) this action is done while handling WM_TIMER message. And now, the situation changes the way that this code starts throwing an assert. This assert message would be shown every TIMER_RESOLUTION milliseconds and would simply flood the screen.
Options for solving this situation could be:
1) Totally pause application running (probably also, suspend all threads) when the assertion messagebox is shown and continue running after it is closed
2) Make a static counter for the shown asserts and don't show asserts when one of them is already showing (but this doesn't pause application)
3) Group similiar asserts and show only one for each assert type (but this also doesn't pause application)
4) Modify the application code (for example, Get / Translate / Dispatch message loop) so that it suspends itself when there are any asserts. This is good, but not universal and looks like a hack.
To my mind, option number 1 is the best. But I don't know any way how this can be achieved. What I'm seeking for is a way to pause the runtime (something similiar to Pause button in the debugger). Does somebody know how to achieve this?
Also, if somebody knows an efficient way to handle this problem - I would appreciate your help. Thank you.
It is important to understand how Windows UI programs work, to answer this question.
At the core of the Windows UI programming model is of course "the message" queue". Messages arrive in message queues and are retrieved using message pumps. A message pump is not special. It's merely a loop that retrieves one message at a time, blocking the thread if none are available.
Now why are you getting all these dialogs? Dialog boxes, including MessageBox also have a message pump. As such, they will retrieve messages from the message queue (It doesn't matter much who is pumping messages, in the Windows model). This allows paints, mouse movement and keyboard input to work. It will also trigger additional timers and therefore dialog boxes.
So, the canonical Windows approach is to handle each message whenever it arrives. They are a fact of life and you deal with them.
In your situation, I would consider a slight variation. You really want to save the state of your stack at the point where the assert happened. That's a particularity of asserts that deserves to be respected. Therefore, spin off a thread for your dialog, and create it without a parent HWND. This gives the dialog an isolated message queue, independent of the original window. Since there's also a new thread for it, you can suspend the original thread, the one where WM_TIMER arrives.
Don't show a prompt - either log to a file/debug output, or just forcibly break the debugger (usually platform specific, eg. Microsoft's __debugbreak()). You have to do something more passive than show a dialog if there are threads involved which could fire lots of failures.
Create a worker thread for your debugging code. When an assert happens, send a message to the worker thread. The worker thread would call SuspendThread on each thread in the process (except itself) to stop it, and then display a message box.
To get the threads in a process - create a dll and monitor the DllMain for Thread Attach (and Detach) - each call will be done in the context of a thread being created (or destroyed) so you can get the current thread id and create a handle to use with SuspendThread.
Or, the toolhelp debug api will help you find out the threads to pause.
The reason I prefer this approach is, I don't like asserts that cause side effects. Too often Ive had asserts fire from asynchronous socket processing - or window message - processing code - then the assert Message box is created on that thread which either causes the state of the thread to be corrupted by a totally unexpected re-entrancy point - MessageBox also discards any messages sent to the thread, so it messes up any worker threads using thread message queues to queue jobs.
My own ASSERT implementation calls DebugBreak() or as alternative INT 3 (__asm int 3 in MS VC++). An ASSERT should break on the debugger.
Use the MessageBox function. This will block until the user clicks "ok". After this is done, you could choose to discard extra assertion failure messages or still display them as your choice.

How to lookup obscure windows message codes?

I'm receiving a windows message with code 1092 (0x444) and I don't know what it is. It's higher than WM_USER but I searched our code base and found no reference so I don't think it's one of ours... does Windows use custom messages above 0x400 and if so how can I look this up?
From the documentanion of WM_USER:
Message numbers in the second range
(WM_USER through 0x7FFF) can be
defined and used by an application to
send messages within a private window
class. These values cannot be used to
define messages that are meaningful
throughout an application, because
some predefined window classes already
define values in this range. For
example, predefined control classes
such as BUTTON, EDIT, LISTBOX, and
COMBOBOX may use these values.
Messages in this range should not be
sent to other applications unless the
applications have been designed to
exchange messages and to attach the
same meaning to the message numbers.
So, that message can be anything.
A quick look in the MFC source code, for example, reveals these definitions
// COMMCTRL.H
#define TB_ADDBUTTONSW (WM_USER + 68)
// RICHEDIT.H
#define EM_SETCHARFORMAT (WM_USER + 68)
I searched for 68 because 0x444 = 0x400 + 0x44 = WM_USER + 68
Any application can use messages above WM_USER or WM_APP. Windows itself even uses messages above WM_USER. Because any application can broadcast these message values (and some do, because they're written by idiots), you should always use registered messages for private comms.
You could use Spy++ to try and track these messages down, but you can't guarantee ever stopping them all, so it's best to avoid them by using RegisterWindowMessage.
You could search around in the Windows headers for strings like 0x444, 0x0444, 0x00000444, etc.
It might also be a rogue application sending around messages that it shouldn't.