How can we prevent popup windows appearing on top of the application? - c#

I have a fullscreen window, and I want to prevent pop up windows that appear at the right bottom corner of my screen. I set the Topmost property to true, but apparently it does not help. I also tried activating the form and giving it the focus once it got deactivated, but that did not help either. What is a way to ignore such windows while the user is engaged with the fullscreen app? I am .NET programming in C#.

You can't do it, this fails the "what if two programs tried to do this" test:
those popups are just normal windows like yours, they also use the same top-most style you are using.
if there was a way to always be above other topmost windows they would have used it too rendering it useless (because the authors of the other apps are just as concerned about the user missing their "super important" notifications as you are about them interfering with your full screen app).
You can try and play dirty tricks to force your window to the top of the top-most z-order, but those popups are likely to use the exact same tricks, again making this all useless (and as an extra bonus all those dirty tricks can turn your app into a compatibility nightmare).

You can disable these balloon notifications using these steps:
Click Start, Run and type regedit
Navigate to the following subkey:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
In the right pane, create a DWORD value named EnableBalloonTips
Double-click the new entry, and give it a value of 0.
Quit Registry Editor.
Log off Windows (this is not very cool...), and then log back on for the changes to take effect.
if you need help in how doing this by program, don't hesitate to ask ;)

I don't think that you can block all the popups, windows might not let you do that. But you can try with SetWindowPos function and pass it HWND_TOP parameter. It might work a little better than Topmost = true.

I used a sys tray popup control on my personal project SvnRadar written in WPF.
The control is at the http://www.hardcodet.net/projects/wpf-notifyicon written by Philipp Sumi.
Very nice.Only thing you will be need to "detach" it from the SysTray screen coordinates and
make it appear where you wish.
Hope it helps.
Good luck.

Related

How to be OnTop but not OnTop of a full screen application

So I have tried searching for the better part of a day for the answer to a simple question. I want my C# application to popup another winform on a timer and then close it after a delay. Simple enough, done and done. Now my issue is that I want it to actually be on top of other applications UNLESS they are full screen. By that I mean a true full screen application such as a game. I do not want to interfere with such an application since it should take priority over my application.
The issue is that I am using the 'OnTop' property on the popup form and, while it works perfectly for any other applications I have been testing it while playing a full screen game and the form, when it "Show()"s, takes the full screen application and drops it into windowed mode.
Is this the intended effect of the 'OnTop' property with full screen applications? If so is there a way that I can have my form popup on top of normal windowed windows and not interfere with full screen applications?
Any links, example, a kick in the general direction is great. The only hits that I come up with when searching for winforms involving full screen is people trying to get their application into full screen or having their application take focus away from another application.
Thanks on advance.
(I didn't post any code due to it just being a simple winform that is "formX:Show()" on a timer with the "onTop" property set)
(EDIT) So thanks to awilson53 for putting me on the right track I was able to find a method (albeit somewhat picky) to determine if an application is full screen. Seems kinda simple, and an "well duh", answer after all is said and done.
95% of the credit goes to the author of the article: http://www.richard-banks.org/2007/09/how-to-detect-if-another-application-is.html
~5% goes to awilson53 for getting me on the right track. :)
Check out this wrapper for the EnumWindows function. This will allow you to enumerate all open windows and determine their window state. You will want to check the EnumWindowItem.Maximized property, and if it is true set your OnTop property to false. If none of the EnumWindowItem's return Maximised you can set OnTop to true.

Reset Taskbar Flash in C#

I have an application where the taskbar flashes if an event has occurred. This is working perfectly, and was relatively easy to implement using a Win32 API described below:
http://blogs.x2line.com/al/archive/2008/04/19/3392.aspx
However, when I stop the flashing, sometimes the application is stuck in the "highlighted" state in the taskbar. This only gets reset by clicking on the application in the taskbar, minimizing it, then re-maximizing it. Is there a way to clear this from being highlighted without any user interaction?
Maybe instead of flashing it you could put an overlay icon on it - one line of code from C# with the Code Pack. Then when you want to clear it you could take the overlay icon away - again one line of code. Windows 7 only, however.
Can you post the code that you are using to "Stop" the flashing?
Have you also considered using a different flag such as:
// flash until the window comes to the foreground
FLASHW_TIMERNOFG = 12;
You will still need to click on the applicaiton to get the flash to stop, but you should not have to minimize then re-maximize the app to get the flash to stop.
You can include the FlashTaskbar snippet and use the following code
FlashWindow(Form.Handle, FlashMode.FLASHW_STOP)

Really annoying bug with TopMost property in Windows Forms

I have this Windows Forms application where it sits in the notification area. Clicking on the icon brings it up front, clicking it again (or clicking on the app X icon) sends it back. This is the type of app that having the window always on top is important when it's displayed by clicking the icon (it's optional though).
Right-clicking the icon brings up a context menu where one can select to enable the "always on top" option or not. When the application first starts up, the app settings are read from an XML file and I'm 99% that this is working as it should, the TopMost property is properly read (and written).
After some time (minutes, hours, days, whatever; I normally hibernate and rarely shutdown) the TopMost stops working. I don't change the option, I don't think anything is changing the option value but I click the notification area icon and app is not brought up front. It shows up but it's on the background (it displays on Alt+Tab), it's not "always on top" as it should. I bring up the context menu, disable the option (cause it's enabled) and enable it back and it starts to work after that. The app is now "always on top". However, it can lose this ability anytime after a while.
I can't understand why this happens and how this happens. Does anyone have any idea why? If not, any idea how could I try to debug such behavior?
EDIT:
I added a piece of code to show a MessageBox when the TopMost property was changed to see if I could notice any strange behavior but it was no good. It didn't help because the form was with TopMost = true but it still was in the background...
There is more than just one "Topmost" window. Topmost just says "Before all non-topmost windows".
I am pretty sure a reinitialization of the desktop (such as when hibernating) requires another SetWindowPos(hwnd, HWND_TOPMOST, ...) (which is the underlying Win32 API call).
As a workaround, you could reset and set the property again when showing the window.
Another possibility is that hiding the window also changes the Z order - either implicitely how Win32 implements that, or explicitely in the way WinForms call the hide/show window.
Like peterchen i also don't have a clue how to get the root cause. But why not make it a little bit simpler?
When you click on your Icon you'll show up your window and rely that TopMost is still active. Why not call SetWindowPos() with the current setting right before you show the window. This shouldn't make any performance problems (only happens if the user clicks the icon) nor any other side effect.
I know, it would be great to find out the root cause, but maybe it's not worth if you can solve it with such a little workaround.

calling the user attention outside of app

I want to create an alarm app for myself. On certain conditions (i need to poll websites) i want my app to inform me and make it HARD TO MISS. So i can take appropriate action or ignore it if i need to do something else.
I wrote a test app and using a BalloonTip (ShowBalloonTip with notifyIcon) isnt great. One of my previous apps brings the window in front of you and does a MessageBox however that doesnt always work or work well (if i somehow miss it or accidentally forget to click ok no futher messages will occur).
What are your suggestions?
You could also make it a system tray application and change the icon out if there is something which requires attention, a la a messenger application. That may not be "hard to miss" but I am trained (for better or worse) to look down at the icon tray when I see something blinking.
Where I work, we have a TimeTracker application (built in house) with which developers are supposed to log what we worked on and when. I am notorious for not using it. So, I wrote my own (Windows Forms) version for my own use which, every hour opens up and takes over my screen:
It is a frameless dialog which consumes the entire screen.
TopMost = True.
On resize, it sets WindowsState = Normal and resizes to fill the screen.
While it is open, it polls for taskmgr.exe and procexp.exe and kills them if found.
It disables the start menu to prevent cmd.exe commands from the menu in Windows 7.
The only way to close it is to enter a log, only then is the OK button shown!
So far, it's working out well - no one has been able to break it!
My less drastic suggestion would be to have a notification which pops up momentarily above the system tray. After a second or two, fade it out. Keep showing the notification every 30 seconds or so until it is dismissed.
Always-on-top window in the corner of the screen?
You could always set your window to be a top most window, make it full screen, and activate it. It would be very, very hard to miss...
Granted, it would also be very annoying, and not something I'd do to other users...
My "real" suggestion would be to use sound along with standard notification methods if this is going to be used by other people, as that's an easy way to grab attention without necessarily killing their workflow. A modeless window that appears in a corner of the screen, especially if combined with sound and color, can be very effective to grab attention.
The industry has been adopting these ambient orb devices and variations of it when such a hard-to-miss notification is required. It is used for tracking the stock-market and for broken-daily-builds.
http://www.ambientdevices.com/cat/orb/MAN_Ambient%20Orb_3-23-03.pdf
Regards

Stop the taskbar flashing

I know I can programatically make the taskbar item for a particular window start flashing when something changes, but is there any way I can stop it from flashing either programatically after a certain period of time or at least is there a keyboard shortcur I can give to my users to somehow stop the flashing?
The FlashWindowEx function which controls the flashing takes a FLASHWINFO struct which has a uCount field to control how many times it flashes. Also, a possible value for the dwFlags field is FLASHW_STOP to cause the flashing to stop.
EDIT: Forgot was a C# tagged question ... so P/Invoke goodness found here.
Instead of flashing the tasbar you can consider using the NotifyIcon. This will let you put something on the system tray (something else many consider evil because of the proliferation of apps that do this). Then you can popup a ballon tip with any change that actually describes the change itself.
To use:
(1) Drag the NotifyIcon onto your form or create in your app NotifyIcon notify = new NotifyIcon();
(2) Set the icon property to the required image
(3) Control whether it is visible on the system tray using the Visible property
(4) Call ShowBalloonText to show popup text (limited to 64 characters)
Either way, you shoudl add an option to the program that allows the end user to turn this feature on/off based on their feelings about it all. I personally like the notify icon because the ballon text can say something like "Server went down"
#thomas -- Amazingly Microsoft's own Windows Vista User Experience Guidelines agree with you ...
While having a background window flash its taskbar button is better than having it automatically come to the top and steal input focus, flashing taskbar buttons are still very intrusive. It is hard for users to concentrate when a taskbar button is flashing, so you should assume that users will immediately stop what they are doing to make the flashing stop. Consequently, reserve taskbar flashing only for situations where immediate attention is required.
Of course who knows who actually follows those guidelines ... or who even reads them. :)

Categories