Tray Icons Keep On Popping Up - winforms

I have a WinForm program that checks a database for changes, and if there are any, it will open another WinForm telling the user what is happening (the popup WinForm has some special functionality making a MessageBox insufficient for this task). Each time one of these popup WinForms shows up, a new icon shows up in the system tray and does not go away even if you hover over it (this isn't a tray refresh issue).
What I'm wondering is how to get the popup WinForm to display no tray icon at all.

You might be doing something like 'new NotifyIcon' in the wrong places (like the constructor of your popup-form). It gets created, but if you never call NotifyIcon.Dispose() it will stay until you stop your program and hover you mouse over the icon.
Another cause might be that you have added the NotifyIcon as a component to the popup-form in the designer.

Related

Focus indicator on a Microsoft droplist combo box not showing (sometimes)

I have a legacy application that uses Win32 (not MFC) to create graphical screens. One of the control types we use is a combo box with the droplist style (using the new Common Controls module). We have discovered a very strange thing about this control lately.
If I start the application with a mouse click, the focus indicator on the droplist does not show! This can be done using the Start->Run dialog (click OK after filling in the program to run). This can be done using a desktop shortcut (double-click). This can be done by clicking the Go button in Visual Studio 2010 to debug the program. Our user discovered this by using a small Delphi app that acts similar to Start->Run (fill in an entry field of a program to execute, and press a Launch button). If you click the Launch button, the focus indicator is missing.
If I start the application with a keypress, the focus indicator shows! Again, Start->Run dialog (but press Enter to activate the OK button). Desktop shortcut (single click to highlight the icon, then press Enter to activate it). F5 from within Visual Studio. Even the Delphi app - if you tab to the Launch button, and press Space or Enter, our application starts and shows the focus indicator on the drop list.
I have tried to create a small MFC application with just a drop list, and have started that application in all the ways described above. However, this small application always shows the focus indicator of the drop list, regardless of how I start it.
I have examined the styles of both drop lists (on my small application, as well as my actual application). They are slightly different, but changing the style of my small MFC app to match my desktop app doesn't change the behavior. Nor does changing my desktop app to match the style of the small MFC app change the behavior of my desktop app.
I modified my desktop application to require the user to press Enter after the main window is displayed, but before any graphical controls are shown. This causes the focus indicator to now show!
I have found that, when debugging my desktop app, if I set a breakpoint after the main window is shown, but before any controls are drawn, and then press F5 to continue, the focus indicator now shows. But if I click the Go button instead, the focus indicator does not show.
It seems like interacting with the keyboard somehow causes the focus indicator to show.
Note that a drop list combo box looks like a push button with a small down-arrow on the right hand side. The focus indicator is a dashed line near the inside border of the button.
I have struggled with this issue for two days now, with no indication that I am getting closer to an answer. So any insight into what may be causing this will be much appreciated.
The first comment to the question provided a partial answer. Changing the Control Panel setting for keyboard accelerators also causes the focus indicator to show, regardless of how the application is started. However, I believe this is only a partial answer.
When the CP setting is off, keyboard accelerators are supposed to show once you have pressed the Alt key. My understand, based on the blog post that Jonathon Potter linked to, is that focus indicators should show up once the keyboard is used. Entering text into an entry field probably doesn't count as "using the keyboard", but I would expect tabbing between controls to count as such.
Also, if the CP setting is off, the behavior of my application is different, depending on whether I start the application with a mouse click or a key press.
In summary, I find the behavior inconsistent. Perhaps it is correct. I find it hard to say.

How to detect which Window was selected when using Aero peek

I am not even sure how to ask this question...
I have a WPF app with a main window in full screen. It launches new windows in full screen and makes them a child of the main window upon some user interactions. If the user's machine only has a single monitor this child window is supposed to be the focus until closed. However, I have found that using Windows Aero if the user hovers over my application's taskbar icon a preview of both windows appear. This in itself is not an issue except if you try to select the main window of the app nothing happens because the child window is always on top but the peek functionality gives the illusion that the user can switch to the main window and it looks like a bug.
I would like to detect which window the user is selecting and, if it is the main window, simply close the child window. Alternatively I would like Aero to stop showing multiple windows if only one will work.
Anyone had any experience with this?

WPF Window that only shows in TaskBar

I'm not sure if what I want to do is appropriate, so I'll explain a little.
We've got a large application that takes a while to load. So we have a splash screen.
The Splash screen causes excessive load time on Remote Desktop (terminal server).
So to alleviate this, we want to hide the splash screen when loading on RDP.
But we still need to at least show the user that the application is loading.
So, I was thinking perhaps just show something in the Taskbar (not the system tray), as it will disappear once the application is fully loaded (and be replaced by the main form's Task icon).
However any WPF solution I've looked at, requires a visible form/window to go with the Taskbar status.
Is there any way of showing something in the Taskbar without showing a WPF window?
Or is there another way of showing application load status without something on the screen?
We had same problem.
On remote desktop, we did following steps...
We configured the Splash window to not allow resizing and have only Minimize and Close button.
We removed WindowStyle=None setting so that title bar of the Splash window appeared
We made the Splash window's width and height zero. This way all you see on screen is a small blue rectangle of the title bar with Text "Loading... Please Wait ..." and minimize and Close button.
We used Window's kernel calls to disable title bar's Close button too. This way user was not able to cancel the Splash window.
So all a user could do is to minimize or restore from taskbar.
When restored, all he sees is a title bar's blue rectangle with "Loading..." text. This way the window also claimed its place on the task bar but hid its splash animation and user is also aware that the splash screen is loading. For this you can also update the Title bar's text by appending more fullstops ...
Loading. Please Wait..
Loading. Please Wait...
Loading. Please Wait....
Loading. Please Wait..
I do think you need to look into the root cause of your issue. Possibly looking at threading and parallelism.
However, a simple solution to what you are asking would be to just create a hidden window. One that is transparent, no borders or anything. It could even bet set to a size of 0, 0. That way you would be able to get the taskbar item that you require.

Determining location of tray icon

My application is designed to sit in the system tray and behave similarly to the Network/Volume/Power/Action Centre tray items in Windows 7 (and the equivalent items in Windows Vista). That is, it becomes visible when the tray icon is clicked, and becomes hidden when focus is lost.
The application is written in WPF, but I am currently using NotifyIcon from WinForms for the tray icon.
I would like to know if anyone has any suggestions as to how I might determine the position (i.e. screen coordinates) of my application's tray icon. The default Windows Vista/7 tray items have some way of doing this, since the pop-out windows are centre-aligned above the relevant tray icon.
In Vista this wasn't much of an issue: I had the application permanently set to the bottom-right corner, and this looked fine (though there was no logic included for cases when the taskbar wasn't placed at the bottom of the screen). However, in Windows 7 my application ends up obscuring the new system tray pop-out box, rather than hovering above it like the volume controls, etc., do.
The best solution I've seen in my searches so far is to handle the mouse-up event on the NotifyIcon and use the mouse coordinates to determine the position of the icon. I think I'll end up using this method if unless someone has a better idea, though it's not ideal as the position will vary slightly depending on where within the icon the user clicks.
Windows 7 and higher expose the Shell_NotifyIconGetRect() function, which returns the screen coordinates of the icon's bounding rectangle.
You'll need to provide it the notify icon GUID, though, and I don't know if you can access that property through the managed NotifyIcon class.
Further to this, I've written about a method to find the location of a notify icon when the Shell_NotifyIconGetRect function is not available: http://blog.quppa.net/2010/12/28/windows-7-style-notification-area-applications-in-wpf-part-6-notify-icon-position-pre-windows-7/

Injecting Mouse Input in WPF Applications

I've been working on injecting input into a WPF application. What makes this project hard is that I need to be able to inject the input into the application even though it's running in the background (i.e. another application has the input focus). Using the SendInput() function is therefore out of the question.
So far, I've got keyboard input working but am having trouble injecting mouse input.
I used Spy++ to observe the window messages that get sent to the WPF window when I physically click the mouse button. I then simply craft these same mouse messages (such as WM_LBUTTONDOWN and WM_LBUTTONUP) manually and send them explicitly to the WPF window to emulate mouse input.
Unfortunately, this doesn't work as expected (not even when I, for testing purposes, have set the WPF window as the foreground window).
I've added a button to my test WPF window which when clicked displays a message box. Injecting the appropriate mouse messages when I've manually positioned the cursor over the button doesn't cause the button to be clicked, however (i.e. the clicked event isn't fired by the WPF framework).
If I add a handler for mouse clicks on the actual dialog (the client area), that handler does get called if I position the cursor over the dialog itself and inject the same window messages as before:
this.MouseLeftButtonDown += WndMouseDown;
public void WndMouseDown(object sender, EventArgs e)
{
...
}
Strangely enough, if I change the push mode of the button to Press (i.e. it's considered clicked on mouse down rather than the default mouse up), the button clicked event is now fired when I inject the same messages as before. (It's worth mentioning that the handler from the example above correctly fires for both mouse downs and ups, so it'd seem the WPF framework does process both messages successfully.)
It seems like there are some other criteria that need to be fulfilled in order for a mouse clicked event to be fired by the WPF framework. Does anybody know how mouse input is handled internally in WPF, or why it's not interpreting my mouse up and down messages as a click on the button?
(It's worth mentioning that this approach [sending window messages] works fine on ordinary Win32 windows, such as the Start->Run dialog. The difference here is that WPF only has one physical Win32 window and the rest is WPF specific, which means all window messages go to that top-level window rather than the actual button.)
I've been searching high and low for an answer to this and would appreciate any thoughts or ideas.
I'd highly suggest going the UIAutomation route. You create an AutomationElement by window handle. Crawl to the button and invoke it. I'd just like to know how you managed to get the keyboard input working. I am currently trying to resolve the converse issue. How to get a WPF window (I've managed to get a hWnd to it via Win32 calls), to respond to virtual keyboard messages. I've logged ++spy sessions on the window in question and replicated it's input without success.
Use UI Automation to do this - trying to manually simulate input via window messages is a textbook mistake, like trying to start a land war against Russia.
Your strategy is basically sound but in order to send a message to a window owned by another process you must first register the message.
Here is an article explaining the whole business. The sample code is unfortunately in VB but I'm sure that won't stop you.

Resources