Stop the taskbar flashing - c#

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. :)

Related

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

How can I lock the screen using C#?

I just write my first C# application, which is a scheduler. Once an hour I want to pop-up a dialog and lock the screen for two minutes in order to take a break.
As of now, my application just shows a form on "TopMost" when its time to break and hides it two minutes later.
How can I lock the screen as well? Something similar to the UAC style in Vista.
Eep, misread your question. The UAC dialog of Vista creates a new desktop and shows itself on that. To Create a desktop you can use the CreateDesktop function. You can then use SwitchDesktop to switch to it.
If you truly want to re-create the secure desktop's looks, then you need to take a screenshot first and display that on your form, darkened a little.
Original answer below, which might be of interest too:
Take a look at the LockWorkStation function.
However, you can't programmatically unlock the work station again. That's something the user has to do himself. So you can't easily enfore a break at least two minutes long unless you still resort to your top-level window technique to deny the user his workspace as long as the two minutes are not yet over.
As an alternative to taking a screen grab (which I've also used as an approach in the past under slightly different circumstances) you can also do this by creating a new window (WinForm) that is full screen and on top of all other windows.
If you set the window background colour to solid black then set the opacity to 70-80%, you'll get something that looks like the UAC prompt.
e.g.
formName.WindowState = FormWindowState.Maximized;
formName.FormBorderStyle = FormBorderStyle.None;
formName.Opacity = 0.70;
formName.TopMost = true;
Of course it would be sensible to draw a window on top of this informing the user why the screen has been dimmed, with a counter.
Using something that looks enough like a UAC prompt (which people are accustomed to seeing) to not have people even think twice about it might be enough depending on the use case.
As with the screen grab approach, this on it's own does not prevent a user from bypassing it by using the Windows key, Alt-Tab or Ctrl-Esc to bring up the Start menu, or to switch to other tasks.
Disabling built in key commands requires setting Registry Keys relating to Windows Hotkeys and is a bit more tricky (I think it requires a reboot and can't be toggled on the fly).

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

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.

Hide another app's taskbar button

I would like to be able to hide another application's window from the taskbar, without hiding the window itself. Specifically, I want to have several different Web browsers running, visible, available in the Alt+Tab list, but not taking up space on the taskbar.
(If anyone's curious why: I've written a dashboard app that uses Vista's DwmRegisterThumbnail APIs to show live previews of several windows at once -- a sort of "picture in picture", if you will. At that point, also having taskbar buttons for those windows seems redundant.)
I am aware that changing the other window's style to include WS_EX_TOOLWINDOW will hide it from the taskbar, and I tried this first. But, as expected, it had some side effects I didn't want: the title bar got shorter (not all bad, I guess) and the minimize and maximize buttons went away (not good). I also had to hide and re-show the window to get the taskbar to recognize the change, which caused repainting artifacts when I did it to IE windows.
My next thought was that, since windows with owners are hidden from the taskbar by default, maybe I could change the other windows to be owned by mine. But MSDN is pretty clear that "[a]fter creating an owned window, an application cannot transfer ownership of the window to another window."
I found this question that's worded similarly to mine, but it's specifically about windows from your own process, where you have complete control over window ownership.
Does anyone know of any other ways to hide a taskbar button, that will work for windows from another process?
Update: Tormod put me on the right track with ITaskbarList -- it works great. The pinvoke.net page had some errors (wrong GUID, methods declared alphabetically instead of in interface order), but I edited it, made corrections, and also added an example of how to instantiate the ITaskbarList via its coclass.
Update 2: If you use DeleteTab to hide a window's taskbar button, and then make that the active window (e.g. via SetForegroundWindow or Alt+Tab), its taskbar button will reappear. To keep the taskbar button hidden, I had to add a timer and keep calling DeleteTab. As long as you don't mind the taskbar button reappearing briefly whenever the window gets focused, this works well.
From MSDN:
Version 4.71 and later of Shell32.dll adds the capability to modify the contents of the taskbar. From an application, you can now add, remove, and activate taskbar buttons. Activating the item does not activate the window; it shows the item as pressed on the taskbar.
The taskbar modification capabilities are implemented in a Component Object Model (COM) object (CLSID_TaskbarList) that exposes the ITaskbarList interface (IID_ITaskbarList). You must call the ITaskbarList::HrInit method to initialize the object. You can then use the methods of the ITaskbarList interface to modify the contents of the taskbar.
It seems like COM interop is the way to go to reliably manipulate the contents of the taskbar. In particular, you would need to call the following functions:
ITaskbarList::AddTab
ITaskbarList::DeleteTab
You can find the C# signature for the ITaskbarList interface at pinvoke.net: ITaskbarList.
Have you tried removing WS_EX_APPWINDOW?

Categories