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.
Related
I need to adjust something by a regular desktop program (not a service) when the system emerges from a sleep state. I expected that the program would get a WM_POWERBROADCAST message, but this message is never received.
According to How can I know when Windows is going into/out of sleep or Hibernate mode?, this message is expected without any preconditions.
Tested on Windows 11 with a simple Win32 program, generated by Visual Studio. Just added to the message loop "case WM_POWERBROADCAST:", which sets some static variable. After waking up from sleep, the variable is untouched.
You can verify with Spy++: there are only multiple WM_DEVICECHANGE messages, plus 0x02C8 and 0x02C9 messages, and repainting messages.
The workaround is to constantly poll the system with, for example, GetTickCount64(), and detect periods of inaction. Of course, better to avoid polling.
If you know something about it, please let me know what I am missing!
You have to register before you will get WM_POWERBROADCAST messages.
Take a look at Registering for Power Events, you will see that you need to call RegisterPowerSettingNotification() in order to get WM_POWERBROADCAST.
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
Say, if I open a Notepad, type something in it and don't save it, then call the following API from the same user session:
ExitWindowsEx(EWX_LOGOFF, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED);
That user session will enter a "shut-down state", where OS will show an overlay window displaying a message that Notepad prevents system from logging off a user. This overlay will not go away until a user clicks "Cancel" or "Force Quit" buttons.
So two part question:
Is there any way to know which processes blocked logging-off/shut-down process?
Is there any way to cancel this user-session "shut-down state" programmatically?
PS. This state can be detected by calling GetSystemMetrics(SM_SHUTTINGDOWN);
EDIT: Contrary to the answer below, I am not trying to stop system from shutting down, nor that any user-mode process is "hung."
EDIT2: Here's a screenshot of the overlay I'm trying to cancel/close:
Question 2: "Is there any way to cancel this shut-down state programmatically?"
The short is answer is not really. And neither should you want to really stop shutdown programatically UNLESS: shutting down will result in serious data loss or significantly affect the user experience on a subsequent system start up. But to mention just one example: imagine a computer is overheating - stopping shutdown programmatically could result in a fried system (and a very irate user).
System shutdown is also not the only thing you need to monitor. There's also hibernate and suspend events (have a look at WM_POWERBROADCAST message).
That said, Windows provides a plethora of mechanisms for detecting system shutdown. For instance:
If your application has a message pump you can choose to return FALSE when Windows polls running applications to vote on WM_QUERYENDSESSION , however Windows from Vista onwards will still force a shutdown after a time-out. From Vista onwards you can (and need to) ShutdownBlockReasonCreate after returning false to WM_QUERYENDSESSION.
If your application is running as a service you can use RegisterServiceCtrHandlerEx and then SetServiceStatus to get a 3 minute shutdown extension grace by setting SERVICE_ACCEPT_PRESHUTDOWN which will get you a SERVICE_CONTROL_PRESHUTDOWN notification. Naturally, you won't receive logoff notification because a service is not affected by logoff. Pre-Vista you can register for SERVICE_CONTROL_SHUTDOWN notification.
Console applications (and gui apps as well but it does not make sense) can use SetConsoleCtrlHandler to be notified of CTRL_LOGOFF and CTRL_SHUTDOWN_EVENT.
At a much lower level one can try hooking API functions such as NTShutdown or even NtSetSystemPowerState which apparently is "the last thing called during ANY type of reboot". But I would strongly suggest not to attempt this.
That said there are ways to really strongly insist that the system should not be shutdown.
Consider the following:
1.) Try to register your application to be first in line to receive Shutdown notification. Something like:
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686227(v=vs.85).aspx
if(!SetProcessShutdownParameters(0x4ff, 0)) // greedy highest documented System reserved FirstShutdown
{
// Fallback
if(!SetProcessShutdownParameters(0x3ff, 0)) // highest notification range for applications
{
// shouldn't happen
}
}
2.) Return FALSE on WM_QUERYENDSESSION
From Vista onwards call ShutdownBlockReasonCreate() after returning false on WM_QUERYENDSESSION.
3.) Tell Windows that you need the system to stay up and available. Have a look at
http://msdn.microsoft.com/en-us/library/windows/desktop/aa373208(v=vs.85).aspx
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
4.) Clean up, call ShutdownBlockReasonDestroy() on Vista onwards, and THEN shutdown the system cleanly.
You could also try the undocumented function (at least it's not on MSDN anymore) CancelShutdown in "user32.dll" which at some point (still may) used to function very much like calling shutdown.exe with the abort flag.
Your mileage may vary.
Following your edit which makes your question clearer:
If you monitor WM_QUERYENDSESSION and respond FALSE to it you can poll from your still running process for a predetermined period of time and then issue an ExitWindowsEx call with flag EWX_FORCEIFHUNG, for example on WM_ENDSESSION. Or you could actually call this pre-emptively on receiving WM_QUERYENDSESSION - the problem is: what if forcing the shutdown results in serious data loss? You're not doing the user of the system any good at that point.
Update following your comments:
How about this:
To find out blocking application:
Register your app with SetProcessShutdownParameters to be first in
line to get WM_QUERYENDSESSION.
Respond FALSE to WM_QUERYENDSESSION and on Vista onwards call
ShutdownBlockReasonCreate to buy yourself the time.
Get the first window in the chain HWND top = GetTopWindow(NULL)
Get the process ThreadId from hwnd GetWindowThreadProcessId() (compare it with your running app's ;) )
Use SendMessageTimeOut with a message to the hWnd - if you receive
no response (timeout) you may have found the blocking window. Go to step 6.
If not skip to 7.
Use OpenProcess() with the handle returned from
GetWindowThreadProcessId to get a process handle and call
GetModuleBaseName() to get the name of the hung process.
If you haven't found the hung window, enumerate the next Window with
GetNextWindow() and go back to step 4.
You can also try using the enumerate window handle technique above to find out if you can get a handle to the "hung window" overlay. Having this might give you a chance to do a send key to cancel the state. My bet is that you won't be able to access it but I haven't tried :)
Again your mileage may vary :)
I'm working on a Windows Mobile 6.5 application that has a dialog box that displays input from a camera and has a button to save a snapshot of the stream. The camera API recommends calling the function that updates the view of stream when the application is idle, via the Windows Message Loop, but doesn't get any more specific than that. After much Googling, I still can't find anything helpful in terms of actually implementing something like this.
Does anyone know how this might be achieved?
You'll have to implement a message loop, not using the conventional GetMessage which blocks until a message exists in the thread's message queue[1], but rather using PeekMessage, which returns false if no message exists[1].
If it returns false, then you do your idle processing. Note that you should divide your idle processing in small enough chunks so that the message loop doesn't cause unresponsiveness to your app.
This is also a classical alternative to threading on 1 cpu or 1 core.
[1] or should be synthesized (painting or timers)
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.