Not receiving WM_QUERYENDSESSION when minimized to system tray - winapi

I'm trying to catch WM_QUERYENDSESSION to save some data in the app, but it seems that I'm not receiving this message on User logoff/system restart when the app is minimized to the system tray. How can I catch it?
Thanks.
Relevant code (nothing magic in there, hopefully :)):
ON_WM_QUERYENDSESSION()
BOOL CMainFrame::OnQueryEndSession()
{
AfxMessageBox(L"Are we hitting this?");
return FALSE;
}
For the tray icon I'm using a third-party lib (CodeJock), which I probably can't post here, but generally, it creates a hidden window to process messages, but the main window is simply ShowWindow(SW_HIDE) when needed. Maybe I need to intercept that message in that hidden window and pass it up, I'll need to try that.

This is basically eaten by a third-party class that I'll need to fix up.

Related

SetWindowsHookEx() WM_KEYBOARD_LL not coming through with full screen RDC

I'm trying to do a away timer style thing like Skype. If the user is 'away' for a period of time I'll trigger something. I have been using SetWindowsHookEx() with WM_KEYBOARD_LL which works fine. That is until you open a RDC connection and have it full screen. Then I never get the keyboard events.
Anyone come across this? Or know of a better way to achieve this? I have actually tested skype and with a full screen RDC it will correctly go from Away to Online if I type in the RDC.
Thanks
EDIT: After Raymond Chen's comment I did some testing, and he is right. Can not believe I never found this method after all my searching. It also solved an issue I was having with a WPF app not triggering the LL_Mouse/KEYBOARD events.
Thanks Again. Update my accepted answer based on this. The other answer is still good if you need to do LL_MOUSE/KWYBOARD.
Have a look at GetLastInputInfo(). Try calling that periodically.
Yes. You'll not get keys pressed in remote desktop. I had this problem and only solution I found was this:
Using FindWindow API always look to find RDP window, if you've detected that full-screen RDP window has been created you should do this:
a) Unhook all hooks.
b) Reset all hooks.
So create a function which makes SetWindowHookEx API calls and call it SetHook and another one as UnHook function. Then re-call both of them anytime you find out user get into remote desktop.
Now you can get keys pressed even inside remote desktop connection.
I found my old code, I did something like this:
Created a timer with 1 sec.
Then
std::string tmp;
HWND hParent = ::FindWindow(TEXT("TSHELLHWND"), NULL);
GetWindowString(hParent, tmp);
ix = za.find(" - Remote Desktop");
if (hParent != NULL && ix != string::npos)
RestartHook();
You also should have a global variable to set when you've restarted hook, otherwise all the time it will restart the hook. When window closed, you can reset that global variable.

Handling windows button during Async BeginGetResponse in wp7

is there any way to handle the Windows button keypress within the *.Xaml.cs especially when the app is busy getting a request processed using an Asynchronous BeginGetResponse. is there a override handler like OnBackKeyPress?
What's the appropriate way to handle this use case? i'm already handling Application_Activated and deactivated in the App.Xaml.cs file for tombstoning.
You can't stop this from happening. When this happens the current page will get its OnNavigatedFrom override called so you could clean up your page and save state from this method.
Bear in mind that it won't be possible to tell whether this is due to the hardware Start key or if the user just navigated away by say pressing the Back key or tapping a button.
Update:
If you're trying to avoid a crash due to Fast App Switching interrupting your networking call you should rather handle this when you return to the application. Your WebRequest will be cancelled and you should handle this case as shown in this MSDN blog post.

netServiceBrowserDidStopSearch not called

I'm now writing a Bonjour service listener class, according to the document here:
Currently, it seems working, I can receive "netServiceBrowserWillSearch:" and "didFindService:moreComing:" correctly. However, after a long wait, I cannot receive " netServiceBrowserDidStopSearch:" or "netServiceBrowser:didNotSearch:". Therefore I don't know that is the proper time for my delegate class to stop showing some UI.
Could anyone have an idea for this? Thanks.
NSNetServiceBrowser doesn't stop browsing (and call the -netServiceBrowserDidStopSearch: delegate method) until you explicitly tell it to by calling -stop. After it's found the initial services, it continues informing you as new matching services are added or old ones disappear.
How you handle this depends on how you want your app to behave. If you have a window that continuously shows the available services (e.g. like the Bonjour window in iChat), then it's best to let it continue, and contiuously update the list in response to delegate messages. If you've got more like a dialog that gets populated and then goes away once the user makes a selection (e.g like the system Add Printer... dialog), then you want to keep the browser running while it's displayed, then call -stop once the user dismisses it. If you're waiting to find just one specific service, then you can call -stop once you've found and resolved it.

Detect window close outside of wndproc?

I am currently working on a win32 GUI app that does most of its work in the window thread.
This thread can sometimes be blocked since it runs a script engine that can be suspended by an external script debugger (another process). This is not a problem most of the time as it is expected behavior.
However, if the user tries to close the window, the app obviously becomes unresponsive and you get the "This application is not responding..." dialog.
My plan was to periodically call back from the "suspend code" to the app and have it do PeekMessage for WM_CLOSE, and if so, terminate the debugger. Unfortunately, from what I can understand, WM_CLOSE it sent directly to the wndproc.
Is there some other way that I could detect that the user wants to close the window, short of redesigning the app which is not an option?
For example, is there some other message that can be checked for with PeekMessage?
How about this: periodically spin a message loop to dispatch any messages on the message queue (that'll cause mouse/input messages to be handled which will generate the WM_CLOSE). In your app's main window set a flag when WM_CLOSE is received and check that flag after spinning the loop.
Simplest case of spinning a message loop to flush any pending messages would be:
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
though your app frame work may already have functions to do this. Hope this helps.
Would you consider adding another thread redesigning the application? It certainly would make your life much easier! Just let the Gui do all the Gui stuff and run it's message loop and do all the hard work in another thread. If the user wants to quit the application, present him a nice OK/Cancel message and suspend/abort the "worker thread" accordingly. Handling two separate tasks in this one thread - with all the workarounds - will make things way more messier than it has to be. Good luck!
I guess you can keep handling your WM_ CLOSE message in the wndproc, and when you receive it you call PostQuitMessage(), which in turn will generate a WM_ QUIT message that in turn will be read by GetMessage()/PeekMessage().
If your window thread is completely blocked, you're out of luck. You have a few options. The thread must be able to periodically do PeekMessage() while in "script engine mode".
while (IsScripting()) {
ScriptEngineTimeSlice();
while (PeekMessage( .. )) {
TranslateMessage( .. );
DispatchMessage( .. ); // <-- wnd procedure will be called
// ..
}
}
This is probabably old news for you, since you already are aware of this. But if you somehow can't give the UI thread a break, there is no way to solve this. If the thread is blocked, it's blocked.
If you are debugging, wouldn't that mean the user was debugging? Why would they be surprised that the app was then "not responding"? Anyway, you have control of the window procedure for the window, so why not just watch for the WM_CLOSE message in there? It is your window?

Session 0 Isolation

Vista puts out a new security preventing Session 0 from accessing hardware like the video card, and the user no longer logs into session 0. I know this means that I cannot show the user a GUI, however, does that also mean I can't show one at all? The way my code is set up right now, it would be more work to make it command line only, however if I can use my existing code and just programmatically manage the GUI it would take a lot less code.
Is this possible?
The article from MSDN says this:
• A service attempts to create a user interface (UI), such as a dialog box, in Session 0. Because the user is not running in Session 0, he or she never sees the UI and therefore cannot provide the input that the service is looking for. The service appears to stop functioning because it is waiting for a user response that does not occur.
Which makes me think it is possible to have an automated UI, but someone told me that you couldn't use SendKeys with a service because it was disabled in Session 0.
EDIT: I don't actually need to show the user the GUI
You can show one; it just doesn't show up.
There is a little notification in the taskbar about there being a GUI window and a way to switch to it.
Anyway, there actually is a TerminalServices API command to switch active session that you could call if you really needed it to show up.
You can write a separate process which provides the UI for your service process. The communication between your UI and service process can be done in various ways (search the web for "inter process communication" or "IPC").
Your service can have a GUI. It's simply that no human will ever see it. As the MSDN quote suggests, a service can display a dialog box. The call to MessageBox won't fail; it just won't ever return — there won't be anyone to press its buttons.
I'm not sure what you mean by wanting to "manage the GUI." Do you actually mean pretending to send input to the controls, as with SendInput? I see no reason that it wouldn't be possible; you'd be injecting input into your own program's queue, after all, and SendInput's Vista-specific warnings don't say anything about that. But I think you'd be making things much more complicated than they need to be. Revisit the idea to alter your program to have no UI at all. (That's not the same as having a console program. Consoles are UI.)
Instead of simulating the mouse messages necessary to click a button, for instance, eliminate the middle-man and simply call directly the function that the button-click event would have called.

Resources