I have a NotifyIcon that appears in the system tray and I want to show a balloon tip the first time stuff the application is idle (As suggested here: C# execute code after application.run() ) but the Idle event happens before the Icon appears in the System tray, causing the balloon to not appear. How can I force the NotifyIcon to appear before I call ShowBalloonTip?
This is a fairly fundamental race, it is another process that takes care of the icon. Windows Explorer. You can't tell when it took care of things. Calling Thread.Sleep(500) after setting Visible = true ought to improve the odds significantly.
Do consider displaying the icon when your program starts.
Why not set a flag on idle and then check the state of the flag after setting the notify icon to visible:
// Application has become idle
firstTimeIdle = true;
Then:
// Show notify icon
notifyIcon.Visible = true;
if (firstTimeIdle && !shownBalloon)
{
notifyIcon.ShowBalloonTip(timeout, title, text, icon);
shownBalloon = true;
}
Related
I'm creating a "desktop gadget" of sorts, I've disabled manual minimizing of the window, but now there is another problem: the system can still hide the window if the user presses Windows+D, for example.
When hidden that way, no usual minimize/resize/visibility events are fired.
I want to do something almost like TopMost, but without forcing the window order.
Maybe it's possible to install a global shortcut event using win32 API, and briefly set TopMost to true, but that sounds very hackish.
I found one solution, but it does not seem to work on Windows 10: Keeping window visible through "Show Desktop"/Win+D
The other common option, which would be writing an actual desktop gadget, is not possible on Windows 10, given their deprecation.
Are there any other methods to keep a window visible (but not on top of the screen) at all moments?
This function is working for me:
BOOL FixShowDesktop(HWND hWnd)
{
HWND hWndTmp = FindWindowEx(NULL, NULL, L"Progman", NULL);
if (hWndTmp)
{
hWndTmp = FindWindowEx(hWndTmp, NULL, L"SHELLDLL_DefView", NULL);
if (hWndTmp)
{
SetWindowLongPtr(hWnd, -8, (LONG_PTR)hWndTmp);
return TRUE;
}
}
return FALSE;
}
Note, this code is a bit better then from Keeping window visible through "Show Desktop"/Win+D because the window can be overflowed by other windows (like any other window). Using SetParent places window under all other windows.
I have and windows app and I want that my app icon will always show in system tray. As now it will hide after time. Please help me to solve my problem. Thanks in advance.
Code of System tray App:
NotifyIcon ni = new NotifyIcon();
// Put the icon in the system tray and allow it react to mouse clicks.
ni.MouseClick += new MouseEventHandler(ni_MouseClick);
ni.Icon = Resources.favicon;
ni.Text = "***";
ni.Visible = true;
// Attach a context menu.
ni.ContextMenuStrip = new ContextMenus().Create(ni);
ni.BalloonTipText = "abc...";
ni.BalloonTipTitle = "abc";
ni.ShowBalloonTip(5000);
I guessing a little, but I think the issue is that the user has chosen a UI option that hides notification icons to avoid the notification area taking over the taskbar.
There is no supported way for you the programmer to indicate that your notification icon is so important that it must show all the time irrespective of the wishes of the user. The user gets the opportunity to indicate that certain icons are always to be shown. Right click in the notification area and select Customize notification icons. This allows the user to decide which icons are always visible.
So, you the programmer do nothing. You let the user make the choice.
I am using WPF NotifyIcon to create a System Tray service. When I show a messagebox, it shows up for half a second and then disappears immediately without waiting for input.
This kind of situation has happened before, and the usual advice is to use an overload which accepts a Window parameter. However, being a System Tray service, there is no window to use as a parent, and null is not accepted in its place.
Is there any way to make the MessageBox wait for user input short of creating a custom MessageBox window myself?
You don't need to create a proxy window for this. Just add MessageBoxOptions.DefaultDesktopOnly to your message box and it will fire on your desktop without disappearing.
Example
MessageBox.Show("My Message", "Title", MessageBoxButton.OK,
MessageBoxImage.Information, MessageBoxResult.OK,
MessageBoxOptions.DefaultDesktopOnly);
According to the answer here, a workaround is to actually open an invisible window and use that as the parent of the MessageBox:
Window window = new Window()
{
Visibility = Visibility.Hidden,
// Just hiding the window is not sufficient, as it still temporarily pops up the first time. Therefore, make it transparent.
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
WindowStyle = WindowStyle.None,
ShowInTaskbar = false
};
window.Show();
...then open the MessageBox with the appropriate parameter:
MessageBox.Show(window, "Titie", "Text");
...and don't forget to close the window when you're done (possibly on application exit):
window.close();
I tried this and it works well. It's undesirable to have to open an extra window, but it's better than making your own messagebox window just for the sake of making this work.
We are using a NotifyIcon to alert the user when they receive a new message that needs their attention. In the event that someone else gets to the message first, the notify icon should get hidden again, however I am having a problem with figuring out how to close the balloon from code behind.
My code looks something like this:
myNotifyIcon.ShowBalloonTip(2000, title, message, icon);
I have tried the suggestions found here, but none are suitable.
Using myNotifyIcon.Visible = true does not hide it
Using myNotifyIcon.Visible = false; myNotifyIcon.Visible = true; will hide it, but it also hides the icon in the tray and when it is shown again, it shows up a a different location.
myNotifyIcon.Show(0) is not a valid method
myNotifyIcon.ShowBalloonTip(0) or myNotifyIcon.ShowBalloonTip(1) does not appear to work as the balloon just gets shown and doesn't appear to go away on its own at all.
I read this question about using the WinAPI to find the window and send it a WM_CLOSE message, but I'm not too sure how to do that reliably.
How can I close a NotifyIcon from the code behind?
I've never found a non-hacky way to do that. The documentation says:
Minimum and maximum timeout values are enforced by the operating
system and are typically 10 and 30 seconds, respectively, however this
can vary depending on the operating system. Timeout values that are
too large or too small are adjusted to the appropriate minimum or
maximum value.
Even though this does not specifically address the question of explicitly closing the balloon, it indicates to me that callers of the ShowBalloonTip() method simply do not have complete control over the balloon, once it's been shown.
The best option I've found is one you already mentioned:
myNotifyIcon.Visible = false;
myNotifyIcon.Visible = true;
Not ideal, but it works. Another idea would be to change the message displayed in the balloon to indicate that the previous message is obsolete:
myNotifyIcon.ShowBalloonTip(2000, "Title", "Never mind!", ToolTipIcon.Info);
There is a simple way to do that.
myNotifyIcon.ShowBalloonTip(2000);
myNotifyIcon.visible = true;
this.Hide();
Try this, it'll definitely work 100%.
Sometimes when our application launches it flashes orange in the taskbar. I don't think we explicitly wrote any code to do this but it still happens. Our program is a c# winforms app that sometimes takes a while to load. Any ideas what could be causing this and how I can prevent it?
I believe you can use MSDN's flashwinfo .
Edit - Here's some more info .
From my experience, if the application isn't the current application the user is using, but does something 'on its own' to update the UI(?) the system recognizes this and notifies the user by the orange flash thing.
So if your application is doing some long processing and the user clicks away to another application/window, they probably will get the orange flash.
A possible alternative would be to prevent the application from showing in the Taskbar until loading has completed.
So, something along the lines of:
// prevent from showing in the constructor (or via the designer)
public MyAppMainForm()
{
this.ShowInTaskbar = false;
// other initialization
}
// now you're ready to show in the Taskbar
private void MyAppMainForm_Load(object sender, EventArgs e)
{
this.ShowInTaskbar = true;
}