I have a "control toolbar" app that needs to float on top of everything else on the primary screen of a dual monitor system. It positions itself at the top of the primary screen and sets TopMost=true.
This control toolbar can be used to launch two other processes which run fullscreen but NOT TopMost, one on each monitor on the dual monitor system. These windows are setup to run fullscreen by setting BorderStyle to None and setting the bounds of the window to fit exactly into the screen dimensions. The fullscreen windows have no problem covering the taskbar, and I can focus and interact with the fullscreen window on the primary monitor all day and the toolbar stays on top.
All is not peachy in the kingdom of software however - certain actions make the TopMost toolbar pop under the non-TopMost fullscreen windows. One of those actions is giving focus to the fullscreen app on the secondary monitor, then giving focus back to the fullscreen app on the primary monitor. This is the easiest situation to reproduce as it happens every time I follow this sequence. I have a hard time reproducing other scenarios reliably, but if I hit the windows key to pull up the start menu and start browsing in Internet Explorer, sometimes when I am done browsing and close IE and give focus back to the primary monitor fullscreen app it pops over the TopMost window.
Any idea how to keep the TopMost window on top, and not allow it to pop under a non-TopMost fullscreen window? I wouldn't mind doing something like polling WindowFromPoint once a second to see if the toolbar is still on top and if not then pop it back over somehow, but I don't want to take focus away from the fullscreen app if that's what the user is using, so Activate() isn't a particularly good solution.
I don't think this really matters, but the toolbar is a WPF window and the fullscreen apps are WinForms.
UPDATE:
The easiest way to test this is to press F11 to go fullscreen in two browser windows on each monitor to simulate the full screen apps and then have a TopMost window floating anywhere. Click between the two fullscreen windows and you will see the TopMost window pop under them. I opened IE on one monitor and Chrome on another since IE doesn't let me do two fullscreen windows.
I implemented the Activate() hack for now, but it's a rather ugly solution because it activates the toolbar app which unfocuses the fullscreen app, which in turn makes the taskbar pop over the fullscreen app. Kind of hacky when all you want to do is switch which fullscreen app has focus.
Okay, here is what I ended up doing...I came up with one more idea before I was going to give up and this works well. In the toolbar window I have a timer that polls the top most window over the toolbar area once a second, like this:
var topMostHandle = WindowFromPoint((int)(Left + ActualWidth / 2), (int)ActualHeight / 2);
if (topMostHandle != new WindowInteropHelper(this).Handle)
{
Topmost = false;
Topmost = true;
}
So I basically just take a point in the middle of the toolbar and test to see if the toolbar is on top. If not, I set TopMost to false and back to true, which seems to bring it back on top without activating it. The flash where it disappears for a second is slightly annoying but I don't expect this to happen often.
Credit to Hans Passant for finding a hotfix for Win7 SP1 that addresses the problem: http://support.microsoft.com/kb/2733420
I kept my hack in the code in case clients can't/aren't running the hotfix as a workaround.
Related
I am writing a small application to automatically rotate through open windows on Windows 7/8.1/10 PC's. I have written the majority of the code and it is working well except I cannot figure out or find out what key presses to use to cycle through open applications.
I have tried SendKeys.Send("%{Tab 2}"); but this seems to only actually press the TAB button once as it keeps switching between the same two windows (even though more are open).
I have tried SendKeys.Send("%+{Esc}"); but this doesn't maximize windows that are minimized to the taskbar. It will effectively cycle through each open windows and bring them into focus (as evident by watching the white semi-transparent overlay on the taskbar item) but it won't show them on screen - I'm assuming because they started minimized. Only the maximized ones will show on screen when it's their turn.
Can anyone please assist? I'm sure it's a simple fix of maximizing the window it cycles to but I'm unsure how to implement this.
I haven't included the code of the entire application as I don't think it is relevant. If you do require it please let me know and I will add it.
Many thanks.
I have a .Net 4 WinForms application with the following properties on my MainForm:
FormBorderStyle = None
WindowState = Maximized
It works as expected and covers the entire screen. However, if a second monitor is disconnected while the application is open, the screen goes black while Windows is "removing" it, and then when the screen comes back, the application is resized so that it fits above the taskbar. I want the application to always be fullscreen and on top. Ideas?
Maybe you should WindowState = Maximized in the onFocus event of your MainForm.
I have an application that minimizes to the system tray. That all works well, the problem is that when minimized the animation goes towards the left side of the screen.
Is there a way to change it so the animation goes towards the tray?
No. This animation is handled by Windows, and since you are invoking the Minimize routine on the window, Windows will automatically animate the window into the location where the window's button is on the taskbar. If you're looking for a "quick solution", there isn't one.
The most you could do is change the window's behavior so that when it's minimized, it actually closes instead. This would prevent the fly-down animation into the taskbar, and Windows would perform the window close animation instead, which may look more consistent with your application design. A lot of other tray icon programs handle it this way.
If you really want to change the window's animation, you will need to override any Windows window management features with your own, that way when the window is "minimized" (or closed), you can animate your window to appear to move into the notification area on the right.
I have a program I want to be able to handle all three states:
Not showing in taskbar, acting just as a widget like the Windows sound, network programs etc
Showing in taskbar - but not Topmost. The window would still show the notification area icon, and should still behave in the same way as #1, but also show the window in the taskbar.
Showing in taskbar with topmost. The window should behave the same as #2, but now the window will show topmost. Note: it should still be capable of being minimised, in the same way that clicking on a taskbar icon minimises a program.
These are my criteria, and I have been working on having them all working nicely together, but I can't seem to get the last few tweaks ironed out. #1 is fine - I have sorted that out easily enough. #2 and #3 cause more issues.
My first question is, how does Windows handle the user clicking on a taskbar icon to get it to minimise/switch back to normal? As I'd prefer to emulate that with #2 and #3.
For #1 I currently hide the window simply by setting Window.Visibility to Visibility.Hidden. And to show the window, call Show() and then Activate().
Like I said, for #2 and #3, I'd like to copy what Windows does when the user clicks on the taskbar icon. Can I do that? Or would I have to find another way to do this?
1- this is called thumbnail buttons
You can check http://elegantcode.com/2010/12/17/wpf-adding-thumbnail-buttons-to-windows-7-task-bar/ OR http://shareourideas.com/2010/12/19/windows-7-taskbar-thumbnail-buttons-in-wpf/ OR http://msdn.microsoft.com/en-us/library/ff699128.aspx
2- there is property called TopMost in the Window class.
3- for the taskbar icon
you can use this library it is easy to use and powerful http://www.codeproject.com/Articles/22876/WPF-Taskbar-Notifier-A-WPF-Taskbar-Notification-Wi
4- to minimize and maximize you can simply use
this.WindowState = FormWindowState.Maximized;
* that is all the info you need to create your application as you want, if you face any problems read the articles well if the problem still there find where is the problem exactly and ask again.
hope this help...
I have a WPF window that goes fullscreen, and I have made every attempt to make it truly fullscreen. WindowStyle is None, WindowState is Maximized, Topmost is true, etc. I even used p/invoke to hide the taskbar when the window is loaded and make it appear again on exit. The problem I have is when, for example, I play a video that replays once it finishes, the third-party program that plays the video pops its window up while also flashing its taskbar button. I can ignore the window since my Window has the Topmost property set to true, and I can also ignore the flashing taskbar icon/button since the taskbar is hidden, BUT the circly windows 7 logo appears on the left bottom corner no matter what. How can I disable that, too?
This example at CodeProject works with Windows 7.