I have a program that runs over the top of the screen, I couldn't figure out how to allow clicks to the window behind it, so I have decided it's easier to just reactivate the previous window if its accidentally activated. It is not possible to tab into, the only way to activate it is to click the text on it.
So, I'm asking, is it possible to find the window activated just before my program is activated? I would prefer not to do a check every couple seconds or so for the currently active window.
You can add this.BringToFront(); after InitializeComponent(); in the form constructor.
This will bring the form's window to the front.
Related
I seem to be running into a dead end here. I have a project that does the following:
just runs and stays in notification area
when user presses middle mouse button, it shows a form
user can then chose whatever from the form, and be happy.
This is working just fine, however what is NOT working is that when the form is shown, it does NOT activate.
Now, prior to me modifying the app.manifest to requireAdmin, it was working fine. Any time the form was shown, boom it was active.
But now that i'm running the form as Administrator, given that I need to be able to control one of our other applications with it (that is ran as admin as well), the form comes up just fine, but doesn't activate.
I have tried:
- TopMost = true inside of the Form_Load method
- Calling SetForegroundWindow with the forms handle on Form_Load
- Calling ShowDialog both on Form_Load and also tried it when the form was built.
- Calling Activate on Form_Load as well as when the form was built
Here's my layout:
Program runs, requires UAC permissions due to the manifest, user agrees, and it kicks off
Only a notification icon appears, shows a nice little bubble saying it's running
Program.cs monitors the keyboard/mouse hooks
When middle mouse button, or any of the keyboard hooks are triggered, it creates a new form object
sets the location of where the form should appear
and then finally shows the form.
Again, without UAC and requireAdmin inside of the app.manifest, this works fine. But once it is running as admin, nope, wont stay in front.
I know that MS has made the SetForegroundWindow requirements much stricter with later versions of windows (Vista, 7, 8), but i really need to be able to make this form show as the top most, active window (like a context menu).
How can i do that properly?
You could split your program into two, a non-admin requiring half that sits in the tray and watches for the middle button, and the half that requires admin permission that you launch when the mouse button is pressed. The non-elevated half could then call SetForegroundWindow or AllowSetForegroundWindow as needed.
If you want to avoid a UAC prompt every time you can cache a COM elevation object via the CoCreateInstanceAsAdmin method and use it repeatedly.
I would like to remove the ability for a user to close a window in my application from the taskbar in windows 7:
The close button in the image should not be available.
Any suggestions?
You shouldn't do this. Window managing/decorating is left to the window manager, you should rather handle the "close" event in some way, and avoid the applicaiton exiting.
Also, middle clicking (mouse2) on any part of that preview will also close the window, so it's not a matter of just hiding that button.
I'm implementing a Windows 7/Vista-style notification area ('system tray') pop-up application in WPF. I've written about my work so far here (determining the notify icon's position, disabling resize, etc.).
There is one problem that I haven't solved quite to my satisfaction, however: hiding the window when the notify icon is clicked a second time. If you click (for example) the volume icon in Vista/7 to show the volume control, notice that it is hidden again when the icon is clicked a second time.
I handle the window's Deactivated event to hide the window, and the window is indeed deactivated when the notify icon is clicked. However, clicking the notify icon of course shows and activates the window, so what ends up happening is that the window disappears while the mouse is down and re-appears when the mouse is released (completing the mouse click event).
My first thought was that I might use the notify icon's MouseDown event (I'm using a System.Windows.Forms.NotifyIcon) and check whether the window is visible at that time - if it were, I could interpret it as the user clicking the notify icon a second time to hide the window. Unfortunately, the MouseDown event seems not to fire until the mouse has actually been clicked (in other words it works identically to the MouseClick event), by which time the window has already been deactivated and thus hidden. This seems to rule out this solution.
My next idea (and the approach I've ended up using) was to get the cursor position when the window is deactivated (GetCursorPos) and checking whether that point is within the notify icon's bounds. At the same time, I also use GetForegroundWindow to find the currently active window - if the notify icon is indeed to be clicked, it should either be the taskbar (the top-level window with class name Shell_TrayWnd) or the notification area fly-out (top-level window with class name NotifyIconOverflowWindow; Windows 7+ only). In short, if the cursor is over the notify icon and the notification area is active, I assume that the user mouse-downed the notify icon to hide the window. If these conditions are true, then the following MouseClick event will not result in the window being shown/activated.
This solution has at least one problem, though: if the cursor is hovering over the notify icon and the user presses the Windows key to open the start menu (or uses a Windows key + number shortcut to open an application), my program will wrongly interpret that as a mouse-down to the notify icon (because the taskbar is made active by those keyboard shortcuts). This means that the next time the user actually does click the notify icon, the window will not be shown. (Clicking the notify icon once more will show it.)
I hope what I've written makes some sense; if not, I'm happy to try and clarify the situation further.
I'm interested to hear if anyone has any other ideas about how to solve this.
I suspect that it might not be possible: it seems to me that the native Windows 7 notification area pop-up applications themselves use a simple timer implementation. Clicking on (for example) the volume icon when the volume control is open will only close the volume control if the time between the window deactivation and mouse click is less than about 2 seconds. Holding the mouse down on the icon for a longer period of time and then releasing will show the volume control again, even if it was open before the mouse-down.
That's not how the volume control window works. It disappears when you click anywhere, including the notification icon. The icon isn't relevant. This is a standard Win32 trick, it captures the mouse so it can see clicks outside of its window.
Mouse.Capture in WPF. Not nearly as easy to do because it requires an IInputElement instead of a window handle.
Occasionally, seemingly randomly, when I close a dialog form my main form seems to move back in the window order, disappearing behind the next application back (usually Visual Studio). It retains focus, so clicking it in the taskbar minimises it, requiring another click. Whenever this happens, the control colours seem to change a little as well, but revert if I maximise and restore the window.
Any idea why this happens?
Edit: This happens when I'm debugging; it might happen at runtime too, but I usually don't have anything behind the application then, so I haven't noticed. Nobody has mentioned it.
This will happen when the dialog closes and Windows cannot find any window in your app that isn't disabled. Forced to move the focus somewhere, it will pick a window of another app to give the focus to. Your form will disappear behind it.
Exactly why your main form is disabled when this happens isn't clear. The color change certainly suggests you are changing the Enabled property of the form. Everything turns battle-ship gray when you do that. Setting Enabled back to true after the dialog closes doesn't work, it's too late. Just don't tinker with Enabled, the ShowDialog() method already disables other windows.
I have an application written in .NET. The previous version had no problems: you double-click on the icon or run it from a command line and when it starts up, it's the main window and has focus as you'd expect.
The latest version displays a splash screen before the main window and now the splash screen comes to the foreground ok but the main one does not always end up the main window. Sometimes it does, sometimes it doesn't. (When launched from the command line it invariably doesn't). When the main window does not come to the foreground and get focus, the taskbar icon shows as a steady orange.
I see lots of hits on the net about how MS added a facility to prevent applications stealing focus from others, centered around the ForegroundLockTimeout registry setting and related settings, but the behaviors described above for the different versions happen on the same machine.
I have tried called Activate in the main form when it finally gets created, and also SetForegroundWindow, all to no avail.
Any help is appreciated.
You should probably have the splash screen set focus to the main app window as it is going away.
As far as Window's knows your splash screen IS your app since it's the first toplevel window shown after the process is started. So that window gets the focus, but any OTHER window trying to grab focus on that same app startup (the icon click/run command) is believed to be a focus thief.
You can get around this by having the window that Window's believes has a right to have focus be the one to transfer focus to a new window.
So you splash should SetFocus on the main window BEFORE the splash is destroyed. If you destroy the focus window, then the focus is nowhere, which is probably what is happening currently in your app.
Sounds like your main window doesn't always get the focus back from the splash screen. Have you tried simply calling SetFocus in the main form's OnLoad handler?MSDN
I just corrected a similar problem. Just make sure your splash screen closes after your main form as shown (it will show in background of the splash if your splash is "always on top").