Hello guys,
I've got a question about a more or less weired behavior of my application after I called Activate() of a WPF window.
I'm developing a tray application which is showing a window when e.g. the hotkey WIN+C is pressed. To capture global hotkeys I'm using
this[
^] - although I don't think that it might be caused by that library.
So, in case the window is hidden and I do a call to Show(), everything's working as expected - the window shows up. But in case the window is already shown but not active (IsActive != true) and I call window.Activate() it happens that the window is only shown the first time I do this call. When I focus another application and the hitting WIN+C again nothing happens. I put a breakpoint on the according line in my code. It breaks at window.Activate() but doesn't activate it.
I also tried to bring the window in front by using the Win32 API, also without success.
Here's the code I've tried (in comments the calls to the Win32 API I've used):
[I've implemented the property IsShown by overriding the methods Show() and Hide()]
if ( _winKeyPressed && e.KeyCode == Keys.C )
{
if ( _launcher.IsShown && !_launcher.IsActive )
{
_launcher.Activate();
}
else
{
_launcher.Show();
}
}
...
However, as mentioned it didn't work with that code.
Well, the weired behavior:
if ( _winKeyPressed && e.KeyCode == Keys.C )
{
if ( _launcher.IsShown && !_launcher.IsActive )
{
Thread.Sleep( 100 );
_launcher.Activate();
}
else
{
_launcher.Show();
}
}
When I put a sleep before I call Activate() everything's working fine.
So, as you see in my comment. WTF?
Anybody an idea, what's going? I don't understand this kind of behaviour.
Thanks in advance for any explanations.
Best regards
Edit.
Maybe it is important.
The library I'm using to capture the hotkeys relays on Windows Forms. So e is of type System.Windows.Forms.KeyEventArgs.
The code above is within a KeyDown event handler.
----
Update:
@SAKryukov,
I tried invoking the Dispatcher already. When I first read your comment about the UI thread it suddenly came to my mind :) I'm sorry for not replying directly. However, it is also not working.
I tried before
_launcher.Dispatcher.BeginInvoke( new Action( () => _launcher.Activate() ) );
as well as your suggestion later on. But as far as I know that shouldn't make a difference.
I felt a kind of bad reading your solution because you probably spent more time rebuilding my issue than me seeking for the cause. I know it is not a good idea to use Thread.Sleep() at this point. It was just an idea because I noticed that in case I debug my application, putting a breakpoint before the Active() and wait instead of stepping through directly, made it work. Miracle ha? :)
I also tried to reproduce my problem. I've created a simple project. In case you're interested, you can download it
here[
^].
It contains just a plain window. After hitting WIN+C a new window should show up.
So, what did I do?
First I only added the reference to the
library[
^] mentioned in my initial question. Surprisingly I was not able to reproduce my problem, too.
Then I added another reference. I told you, I'm developing a tray application. But I didn't tell you that I'm a lazy boy. Thus I'm playing around with the
WPF NotifyIcon[
^]
And there we go. Same issue again.
At this moment I'm not sure if it is a "bug" within the NotifyIcon or whether it is caused by using the Windows.Forms key-events. I hope I find some time later on to try dropping all references to Windows.Forms and registering the hooks by myself.
So far, thanks to you two for your solutions.
----
Update 2 & Solved:
I finally solved my problem. I completely dropped all references to Windows.Forms as well as the library I used to hook the global hot-keys and implemented it on my own.
I'm using now the Win32 API to register the hotkeys (
1[
^]) (
2[
^]) and the
ComponentDispatcher [
^] to listen to the system messages. Works very well ;)