Activating another process

F

Frank Stegerwald

Hi,

I have a windows forms application that is single instance.
It checks its existance with a mutex and shows itself with the following
lines of code if it is already running (using P/Invoke):

AttachThreadInput(_hThread, hThread, 1);
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
AttachThreadInput(_hThread, hThread, 0);

On XP Systems the ForegroundLockTimeout is set to 0 to achieve this
behaviour.

Sometimes, when I launch the App from e.g. Windows explorer,
the application does not get the focus correctly. It is shown in
the taskbar as active, but the calling application (here windows
explorer) still has the focus somehow. I need to explicitely klick
into the app to activate it.

This behaviour is not always. very strange. We also tried this with
a Win32 Application and we can reproduce the behaviour there as well.
So it has nothing to do with .NET

Any solutions to this problem?
Thanks in advance for ANY help
Greetings
Frank Stegerwald
 
F

Frank Stegerwald

Hi Jeffrey,

thanks for your detailed answer and your efforts.
I included my project (stripped down sample project)
that is a little more complex since this app is also
a single instance application.

The problem I have is that the activating works
in 99 % of the tests:
1. open windows explorer
2. launch SingleInstanceApplication.exe
3. now activating / deactivating applications by
clicking into the applications (explorer and app)
changing by ALT-TAB
selecting in the taskbar

The activating works fine in 99% of the tests, but sometimes
when i activate explorer and then launch the app, then
the application is brought to the foreground, but is not active
(i see this on the color of the frameborder).
I tested with windows 2000 and windows xp.

Any clues?

How can I Send the sample project? I cannot attach to the main,
I get the error "Message is too large", Project is about 96 kbytes???
 
F

Frank Stegerwald

Hi,

something that I figured out is:
If this strange event is happening that the
app is brought to the foreground but does not get focus,
i figured out that the Form.Activated Event is not
recieved by the form.
But I dont know how this can happen...


Hi Frank,

Thanks for your post.

Based on my understanding, you failed to set your background window to
front with AttachThreadInput and SetForegroundWindow.

Because I did not get the full code snippet of your project, I just write a
sample my self. However, with the test on my side, it works well without
any problem. Code snippet listed below:

[DllImport("user32.dll")]
static extern bool AttachThreadInput(uint idAttach, uint idAttachTo,
bool fAttach);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll", SetLastError=true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint
lpdwProcessId);

[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();

private void button1_Click(object sender, System.EventArgs e)
{
this.timer1.Interval=3000;
this.timer1.Start();
}

private void timer1_Tick(object sender, System.EventArgs e)
{
IntPtr hwnd=GetForegroundWindow();
uint dwProcessID, dwThreadID;

dwThreadID=GetWindowThreadProcessId(hwnd, out dwProcessID);
if(dwThreadID==0)
{
MessageBox.Show("GetWindowThreadProcessId failed with
"+Marshal.GetLastWin32Error().ToString());
}

uint dwCurrentThreadID=GetCurrentThreadId();
if(dwCurrentThreadID==0)
{
MessageBox.Show("GetCurrentThreadId failed with
"+Marshal.GetLastWin32Error().ToString());
}

bool fSucceed=AttachThreadInput(dwCurrentThreadID, dwThreadID, true);
if(!fSucceed)
{
MessageBox.Show("AttachThreadInput failed with
"+Marshal.GetLastWin32Error().ToString());
}

fSucceed=SetForegroundWindow(this.Handle);
if(!fSucceed)
{
MessageBox.Show("SetForegroundWindow failed with
"+Marshal.GetLastWin32Error().ToString());
}

fSucceed=AttachThreadInput(dwCurrentThreadID, dwThreadID, false);
if(!fSucceed)
{
MessageBox.Show("AttachThreadInput failed with
"+Marshal.GetLastWin32Error().ToString());
}
this.timer1.Stop();
}
I just click the button to start the timer, then I switch the foreground
window to a notepad immediately. After a while, my .Net Form will jump to
the front instead of showing a highlighting in the taskbar.

I will also attach my sample project in this reply as attachment. You can
get it with Outlook Express.(Can not with IE) Hope this helps.
==========================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Frank,

Thanks for your feedback.

First, based on the feature of newsgroup support, we do not provide project
wide review for large project, only sample demonstration project is
welcome.
Second, it seems that the problem works for 99% of the time, yes? If so,
how can I reproduce your project on my side? I do not think I can run your
project for more than 100 times for only 1 time to arise the problem. I can
only give you some suggestion on this issue.
1. Does my sample project have the same problem on your machine? That is 1%
times not activating?
2. Have you tried your problematic project on other machines? Does the
problem still exist? With this, we can determine if the problem is
machine-specific.
3. Based on the feedback from another message, it seems that the key
problem is that the Activated event does not fire, yes? Based on the call
stack for Activated event, we can see that the Activated event is triggered
by Form.WmActive method, which is then triggered by WM_ACTIVATE. So I
suggest you use Spy++ to monitor the application to see if WM_ACTIVATE is
posted/sent to your form, when activating code is executed.

Additionally, if you can determine the root cause is from Win32 world, I
think win32 newground is a more suitable place. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top