views:

338

answers:

2

Hi,

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

+2  A: 

There is more than jsut one "Topmost" window. Topmost just says "Before all non-topmost windows".

I am pretty sure a reinitializaiton of the desktop (such as when hibernating) requries 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.

peterchen
I know that my app is not the only topmost window, but things like Windows Explorer, Firefox and such are NOT topmost and my window should be on top of those. Which is not happening because of this glitch. I disable and re-enable the option and it gets on top of them as it should.
Nazgulled
And I don't think hibernate is the issue. I just did a quick test and hibernated the machine with Explorer and Firefox opened. After restoring it, my app is still topmost. It must happen on a different situation...
Nazgulled
Did you try the workaround I suggested? (after showing the window, reset and set the "topmost" property)
peterchen
Not yet, I'm trying something else first to see if the problem lies on two lines of code that are now commented out.
Nazgulled
If you find a reason / solution, please let us know.
peterchen
My solution didn't work, heading to yours... Should I use `SetWindowPos()` or can I just do `Form.TopMost = True`?
Nazgulled
I've marked this answer as accepted cause so far it's working and the bounty was almost over...
Nazgulled
+1  A: 

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.

Oliver