Windows Explorer does not receive WM_DESTROY. How can I detect when the user closes their explorer window? - winapi

I'm writing a program which needs to detect when windows are closed. Currently I am using SetWindowsHookEx to register a hook which can monitor window messages.
I am monitoring for WM_DESTROY events to find out when windows have been destroyed. This works fine for most windows with Windows Explorer being a notable exception. Windows Explorer does not appear to receive a WM_DESTROY event when it terminates (but receives most other interesting events).
Is there a reason why Windows Explorer does not receive WM_DESTROY?
More importantly, is there a alternate method I can use to detect when Windows Explorer terminates other than listening for WM_DESTROY?
Thanks!
I am using Windows 7 (not sure how relevant this information is)

Use a WH_CBT hook instead of a message hook, and have it handle HCBT_DESTROYWND notifications.

Related

Does command line windows restart gracefully exit running app

Platform: Windows 2008 server
Ran into a problem where my one-file exe generated with pyinstaller would not clear its associated temporary folder. Read up about this http://pythonhosted.org/PyInstaller/ and found out if the exe doesn't close gracefully it would not delete its associated temporary folder. After this I spoke to the IT guys who setup the exe and was told that the app is started on system start-up and every night a system reboot occurs.
I tried finding out if the system restart on windows would gracefully exit running applications, but couldn't find anything regarding this.
Does anyone know if windows gracefully exits running apps with a scheduled system restart?
Thanks in advance
Yes, it does, but implementation slightly differs between XP\Vista. You can also change shutdown timer and auto-close behaviour: How to Specify WaitToKillAppTimeout to Speed Up Shut Down Time in Windows.
In Windows XP:
In Windows XP, each running application is sent the WM_QUERYENDSESSION
message at shutdown. Applications can return TRUE to indicate that
they can be closed, or FALSE to indicate that they should not be
closed (e.g., because doing so would cause the user to lose data or
destroy a CD being burned). If an application returns FALSE, in most
cases, shutdown will be cancelled (and the application that cancelled
shutdown is sent WM_ENDSESSION with wParam == FALSE).
Applications can also delay responding to WM_QUERYENDSESSION in order
to display UI asking what the user would like to do. For example, when
Notepad has unsaved data and displays a "Would you like to save your
data?" dialog during shutdown, this is what it is doing. By default,
applications can delay responding to WM_QUERYENDSESSION for up to 5
seconds. After 5 seconds, Windows XP will display a dialog that
indicates that the application is not responding and allows the user
to terminate it. Until the user responds to this dialog, applications
can block WM_QUERYENDSESSION (and, consequently, shutdown)
indefinitely.
In Windows Vista
Ability for users to forcefully shut down
In Windows XP, the UI for
blocking applications allows users to either cancel shutdown or
terminate the blocking application. If subsequent applications also
block shutdown, the system displays identical UI for each blocking
application. This is frustrating for many users, who, when shutting
down, "just want" their computers to turn off. Windows Vista will
solve this by allowing users to terminate the blocking application and
make shutdown "forceful." In a forceful shutdown, Windows will send
applications WM_QUERYENDSESSION with the ENDSESSION_CRITICAL flag. If
an application responds FALSE, Windows will continue shutdown instead
of canceling it, and will send the application WM_ENDSESSION. If an
application times out responding to WM_QUERYENDSESSION or
WM_ENDSESSION, Windows will terminate it.
Silent shutdown cancellations will no longer be allowed
In Windows XP,
applications are allowed to veto WM_QUERYENDSESSION without displaying
any UI indicating why they need to cancel shutdown. These "silent
shutdown failures" are highly frustrating to users, who often take a
minute or two to realize that shutdown has failed because no UI was
displayed. Windows Vista will eliminate this possibility by displaying
UI even if an application vetoes WM_QUERYENDSESSION.
Certain types of applications will no longer be allowed to block
shutdown. At shutdown, Windows Vista will check whether each running
application is not responding (an application is defined as not
responding if it has not responded to any of its window messages in
the last 5 seconds), and, if so, automatically terminate it.
Windows Vista will also not allow console applications or applications
that have no visible top-level windows to block shutdown. In most
cases, such applications are less important to users at shutdown than
applications that do have visible top-level windows. If an application
without a visible top-level window blocks shutdown by vetoing
WM_QUERYENDSESSION, or takes over 5 seconds to respond to
WM_QUERYENDSESSION or WM_ENDSESSION, Windows will automatically
terminate it.
However, if an application with no visible top-level windows uses the
new API to proactively indicate that it needs to block shutdown,
Windows Vista will not automatically terminate it, and will instead
treat it like an application that does have a visible top-level
window.

Windows Multitouch Events and LabView

I'm having some problems with multi-touch and LabView.
My objective is to intercept the Windows Touch Messages (generated by multitouch monitors and then interpreted and handled by Windows 7), which are intended for any and all windows owned by a program called LabVIEW.
This will prevent Windows from communicating Touch Messages with LabVIEW while allowing me to use the touch messages to create custom responses in LabVIEW myself. And, it will still allow Windows to use the Touch Messages as normal for any and all other programs which the user may want to interact with.
LabVIEW has not been registered with Windows 7 to interpret Windows Touch Messages specifically. It therefore handles them using default Windows 7 responses.
I have developed a library for LabVIEW which creates the custom multitouch enabled responses but it requires me to provide my own driver for the multitouch monitor being used in order to prevent Windows 7 from listening to the monitor's touch event messages and converting them to its own set of Touch Messages. This is inefficient as I want users to be able to plug and play any commercial multitouch monitor with my code and I don't want to have to write custom drivers for every monitor type.
So, I want to intercept the Touch Messages intended for LabVIEW (and only those Windows Touch Messages) so that they
Never reach LabVIEW
Can then be sent on to my existing program for reinterpretation via TCP messages over the localhost (this seems the best way I've found so far).
If anybody has any ideas I'd be exceedingly grateful!
LabVIEW does not see the Windows Touch Events as you already know. The only events you see are the ones you can use in the Event Structure. However, there are ways to use .Net Callbacks to see other Windows events. You can then create User Events to feed the event back to your Event Structure. Below are a couple of links that might help:
Capturing Windows System Events without Polling (Windows)
Windows Message Queue Library
Use windows touch screen (multi touch) and distinguish get touch event and mouse click
Use the event handler structure in a while loop and only register the events you want LabVIEW to handle.
If you are willing to pay for it, there is a commercial toolkit that supports multi-touch and smartphone-style gestures on a number of touchscreen devices via UDPP or Windows 7 messages:
https://www.ni.com/en-us/shop/software/products/touchscreen-toolkit-for-labview.html

How can I handle console closing in a Windows CE?

I have a Win32 C++ console application running in Window CE 6.0 that contains a number of continuously running threads. Occasionally there is a need to stop the application, and I would like that to happen in a controlled manner. One method of doing this would be to simply monitor the console window, and if it closes then stop the process. Unfortunately SetConsoleCtrlHandler does not appear to be part of the Win32 api for Windows CE 6.0. Does anyone know how I can detect that the console is closing in a Win32 C++ program running in CE?
Thanks,
You can watch for Ctrl-C by calling DeviceIoControl with IOCTL_CONSOLE_SETCONTROLCHANDLER. Use _fileno(stdout) for the hDevice parameter.
I don't think there's any way to get notified for any other "close" mechanism.
I got this working on Windows Embedded Compact 7. The Ctrl+C and the "window closed" events are both catched.
Create a Win32 event.
Pass that event to DeviceIoControl() using the IOCTL_CONSOLE_SETCONTROLCEVENT, and given the console handle (e.g., _fileno(stdout)). That event will be signaled when Ctrl+C is typed, or the console window is closed.
Create a thread that waits on the Win32 event becoming signaled, and when it becomes so, calls your Ctrl+C handler or performs your cleanup, and probably exits the program.
Notice that IOCTL_CONSOLE_SETCONTROLCHANDLER has been deprecated and DeviceIoControl() fails when it is given that IOCTL code.

Request suspend on Vista but allow other applications to cancel

My application uses the Win32 SetSuspendState() API to trigger system suspend or hibernation when it has finished doing a lengthy task.
The API accepts a parameter "ForceCritical" which determines whether or not the system suspends immediately or whether it broadcasts PBT_APMQUERYSUSPEND first to allow other apps the chance to cancel the suspend. My app uses this to play nicely with other apps like Media Player, so it doesn't suspend if you're listening to music or something.
For some reason, starting with Vista, MS have changed things so this parameter is ignored so SetSuspendState immediately causes a suspend and other applications have no opportunity to stop it.
Does anyone know how I can get the desired "polite" behaviour back again on Vista?
MSDN says
To prevent the system from transitioning to a low-power state in Windows Vista, an application must call SetThreadExecutionState to inform the system that it is in use
I would guess that WMP does this, but older apps don't. You could probably emulate this by sending the WM_POWERBROADCAST:PBT_APMQUERYSUSPEND message to all top level windows and check their return values (Send the message with a timeout so a hung app does not hang your app)

Screen capture and event with Vista UAC

I'ved developed a c# application that captures screens using bitblt and sends keyboard and mouse events using calls to keybd_event and mouse_event.
According to Microsoft I needed to modify the app.manifest with:
requestedExecutionLevel level="highestAvailable" uiAccess="true"
Sign the application and place it in a trusted location (program files).
I have done all of these to get the application to run under elevated priviledges under Vista but when UAC dialogs appear it does not capture those screens and the keyboard and mouse events do not reach the UAC dialog.
I am guess that UAC runs in a different desktop?? if so, how would i capture that? and how can i detect when the desktop switches to a UAC dialog in c#? or have i just missed a step?
UAC runs on the secure desktop, only trusted processes running on the system account are allowed to run in that context.
This is to prevent exactly what you are trying to achieve - processes spoofing or capturing user input.
You cannot. The UAC desktop is secure because it doesn't allow anyone to access it.
To detect the desktop switch event, I would try to use SENS or WTSRegisterSessionNotification. But it doesn't look very promising.

Resources