How to not display a UI? - windows

MSDN at this link states that there is a flag
CMIC_MASK_FLAG_NO_UI
The system is prevented from displaying user interface elements (for example, error messages) while carrying out a command.
However, it also indicates that the structure has
nShow
Type: int
A set of SW_ values to pass to the ShowWindow function if the command displays a window or starts an application.
which I think contradicts each other as there is no indication I can set the latter parameter to 0 and there is no SW_NOSHOW parameter in the ShowWindow documentation.
Is it even possible to suppress that window? If yes - how?
TIA!!

There is some ambiguity about which UI we are talking about here.
There are UI things related to invoking the command (asking for network share password, error message on failure etc.) and CMIC_MASK_FLAG_NO_UI certainly applies here. I don't know how relevant nShow is though. The caller does not know which UI might be displayed and it makes zero sense for the callee to allow its error MessageBox to be maximized etc. Respecting SW_HIDE might end up stuck waiting for the user to interact with a window they can't see.
The other UI is actually the thing that is executed. In the cases where a new process is started we are looking at a ShellExecuteEx call. CMIC_MASK_FLAG_NO_UI is passed on as SEE_MASK_FLAG_NO_UI (same integral value) and MSDN just says "Do not display an error message box if an error occurs" for this flag. Here however, nShow is relevant and can trickle all the way down to CreateProcess.
This is how I personally deal with this situation:
Set CMIC_MASK_FLAG_NO_UI if you are going to display your own error UI in case of failures or if you are running in a silent/automated mode of execution.
Only set nShow to something other than SW_SHOW when you control the action being executed. For example, you know cmd.exe is getting called and you need to hide the console window with SW_HIDE.
It is important to remember that CMINVOKECOMMANDINFO is parsed by the default IContextMenu shell32 implementations for various shell objects (files, control panel etc.) and by 3rd-party context menu handlers. You cannot assume that they are going to respect your wishes.

Related

How to dispatch messages for multiple dialogs in an ATL exe

Microsoft had a knowledge base article describing how to modify the message loop in at ATL .exe so that modeless dialogs can receive appropriate messages.
I was wondering how to elegantly do this if you have potentially multiple modeless dialogs, and you don't know which dialogs might exist at any given time. Like perhaps the .exe hosts several different COM classes, each with different dialogs, and who knows which one might be instantiated.
Would you create a global set of hwnds, and have each dialog class place its hwnd in the set upon creation, and then have the message loop iterate through the set calling IsDialogMessage (and TranslateAccelerator)?
The message specifies its target (which might be a child of the actual dialog), I would handle this by having a set of dialog pointers and then simply iterate the set testing each with IsChild() and only when the right dialog HWND is found would I use IsDialogMessage.
The alternative is to walk up the ancestor tree from the HWND in the MSG translating HWNDs to objects somehow and when you get to a window that is a dialog use IsDialogMessage.
WTL's solution for this challenge is to have a specialized message loop class which registers itself in static container so that dialogs could discover message loops for the threads they belong to.
Dialogs can register themselves with these message loops via CMessageLoop::AddMessageFilter and have their callbacks invoked once it comes to translating the messages.
Example:
// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);

::PostMessage to an invalid hWnd

I have a thread that calls ::PostMessage(hWnd, [...]); to send a message to the main thread alerting it to the results of an async operation.
However, I'm concerned that if the thread takes a particularly long time to finish its operation, the hWnd may not exist when the PostMessage is called (the user may have closed the window).
The MSDN Documentation doesn't say anything about the results if hWnd is invalid.
Do you know from experience, or other documentation, about what I can expect if hWnd is invalid?
Raymond Chen wrote about this:
http://blogs.msdn.com/b/oldnewthing/archive/2007/07/16/3885472.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx
Some choice excerpts:
It so happens that boatloads of programs (and "boatloads" is a technical term) contain bugs where they use window handles after the window has been destroyed. When a window handle is re-used, that program sends a message to the window it thinks is still there, but instead it sends the message to a completely unrelated window. This doesn't bode well for the program, and it usually doesn't bode well for the new window that received the message by mistake either.
We left off our story last time by raising the problem of programs that send messages to windows that have already been destroyed and how window handle re-use exacerbates the problem. Although this is clearly a bug in the programs that use window handles after destroying the window, the problem is so widespread that the window manager folks in Windows NT decided to take a more proactive approach.
As others have pointed out, Ramond Chen explained what happens if the HWND gets re-used by a new window. PostMessage() will succeed, it will just go to the wrong window. However, in cases where the HWND does not get re-used, PostMessage() will fail with an ERROR_INVALID_WINDOW_HANDLE (1400) error code.

Is KillTimer really necessary?

This may seem to be a duplicate question for Is KillTimer necessary?, but i would like to confirm this with credible source.
Does destroying window really free the resource allocated by the OS for the timer? (does DestroyWindowsTimers really get called let alone if such function actually exists? if so, where?)
No, it is not necessary. From the documentation of DestroyWindow (with emphasis added):
The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
Doing a google search the only actual real looking reference to it looked to be some Win2k source code. The url ended with /Censorship/win2k_sources/private/.../timers.c, I'm assuming from the source code leak a while back. I did not look at the code, nor will I post a link here.
That function most likely exist - something like that almost has to exist for timers linked to window handles - since the timer message is delivered to a specific window handle.
I can't see anywhere in the documentation that states that you don't have to call KillTimer to get rid of a timer. So based on the documented contract, you need to call KillTimer. In practice Windows will probably clean it up for you, but since that is undocumented behavior you should write your code to follow the documented behavior and call KillTimer on all your timers.

Ruby Win32Api get single character non-blocking

I'm trying to write a simple game working with two threads, one thread to get input from the user, and another thread to animate some scenes. I'm able to get characters without pressing ENTER just fine, but it blocks in the animating thread until the user presses a key. Does anyone know of a way to get a character from the keyboard non-blocking?
If you're looking to checkup on a handful of specific keys, GetAsyncKeyState() can be used to poll for state. Otherwise, you should implement a message loop and handle WM_CHAR messages in your application.
You can access raw win32 functions with a library similar to the following if your environment doesn't already support the win32 functions you need.
RAA - win32-api # raa.ruby-lang.org
Here are relevant links for GetAsyncKeyState().
GetAsyncKeyState() # MSDN
Virtual-Key Codes # MSDN (used as values for GetAsyncKeyState and other functions)
If you decide to go with a message loop, you'll need to implement it on the same thread that hosts the window for your application. A short explanation is available here:
Message Loop in Microsoft Windows # Wikipedia
As shown at that link, there isn't a whole lot to a message loop. Your framework may already have one running behind the scenes to host the window containing your graphics. If this is the case, you don't need a 2nd thread for input; but you will need to intercept and handle windows messages for that host window.
If you have to implement a message loop on your own, you can use the skeleton at the wikipedia link. The DispatchMessage call will direct a windows message to the appropriate window handler. You will need to look for a matching stub or handler for windows messages in your ruby framework, and handle WM_CHAR from there.
DispatchMessage # MSDN
WM_CHAR # MSDN
If you wish to know when keys are pressed/depressed, then you will want to handle WM_KEYUP and WM_KEYDOWN messages.
WM_KEYUP # MSDN
WM_KEYDOWN # MSDN
Also note, GetAsyncKeyState() can be called and returns key state even while another application is in the foreground. Handle WM_ACTIVATE and WM_SETFOCUS/WM_KILLFOCUS messages so that your application ignores or defers checks while a different window is active if you only care about key state while your window is the primary foreground window.
WM_ACTIVATE # MSDN
WM_SETFOCUS # MSDN
WM_KILLFOCUS # MSDN
I have used rubygame for this. It gives you the ability to attach functions to keyboard events with minimal code. RubySDL and GoSu will give you similar functionality.
If you don't want to go that route with game related gems take a look at this on how to check if data is available in IO object. This could be use to poll the keyboard.

How advisable is not having a message loop in WinMain?

This may be the simplest win32 program ever ..
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdLine, int show)
{
MessageBox(0, "Hello world..", "Salutations!", MB_OK);
return 0;
}
.. which makes no calls whatsoever to the usual GetMessage() call. My question is this: if my program doesn't process any window messages, can the OS cope with that? I.e., does it cause memory leaks? Or some other resource that wouldn't be apparent unless I ran it 16K times?
In a broader sense, exactly how 'dependent' is Win32 on applications taking care of their messages? I would hope that when the compiler links the executable as a windows program, that the run-time would be capable of cleaning up any kind of message queue, be it emptied or not.
Just a technicality, but you do have a window, and you do have a message loop, just not in your code.
The call to MessageBox() creates a window (of class #32770) and runs a local message loop, not returning to your code till the message loop drops out, presumably when WM_NCDESTROY is sent. I think it's the same message loop that runs in response to DialogBox().
But you could substitute your call to MessageBox() with anything else that really doesn't create a message loop, and you'll still be fine. Windows doesn't care if you have a message loop, although some functionality (primarily UI related) is difficult or impossible to use without it. In fact, you don't have to link to user32 at all, and some apps that have no user interface don't.
Now if you create a window and don't process messages for it in some way, Windows XP and up will replace your window with a "ghost" window that has a white client area and Task Manager will tell the user that the application is not responding.
Although it seems so at first, the message loop is not magic or a strictly required part of Windows boilerplate. It is highly ingrained as a standard in most Windows applications, though, because it's the best way to handle the dispatching of window messages. The "event-driven" nature of most Windows applications makes us forget sometimes that Windows applications were originally designed to be single-threaded, and in this model, it is code running within that single thread, not some unseen force within the operating system, that must make every function call within our code. The addition of multithreading changed that somewhat, but the basic model still remains the same.
EDIT
A note about message queues:
As is mentioned elsewhere, a message queue is only created (and on a per-thread basis) when a window is created by that thread. Your example program, upon creating a message box, does create a message queue. But this queue need not be empty when your application exits. This queue is just a memory structure. It's a block of memory that can hold a certain number of message objects (specifying destination hWnd, message id, wParam, lParam, system time when message was posted, mouse position when message was posted, and some data that allows the derivation of keyboard and mouse button state when the message was posted), along with pointers to the head and tail of the queue (I assume it's a circular queue). When the application exits, this memory, like all memory belonging to the process, is summarily freed.
There are, of course, other things that must be cleaned up outside your process. The OS must keep a table of all existing windows, for example, along with the thread and process that created them. Of course, these are all cleaned up automatically as well.
Since you don't have a window, you don't need a message loop. In Win32 the messages are sent to windows, not to applications.
You do have a message loop - MessageBox is a modal dialog and therefore contains a message loop within.
You don't have to create windows. But still, there are some kind of messages, like
WM_TIMER
WM_TIMECHANGE
WM_CLIPBOARDUPDATE
WM_COPYDATA
WM_POWER
that you may need. So, a ghost window hanging around wouldn't be bad.
If you don't have a window, then that is fine, but if you do then you need to make sure that you pump messages for it. Otherwise the system can hang on broadcast messages waiting for you to respond. This is important for things like COM which create hidden windows for message processing. If your main thread does not pump messages (e.g., by calling WaitForSingleObject) then calls to your COM objects will not be processed, and any programs which send broadcasts will appear to hang.
I have read somewhere (and can't find the reference) is that Windows will create a message queue on demand. If you never call a function that looks for a message queue, one will never be created. And this occurs on a per-thread basis.

Resources