Process SetFocus

S

Shachar

Hi All,

I need to start a new process calc for example and when ever the user click
on the button the
application should setfocus to the calc application.

I use this code but it is NOT working, what I do wrong ?

10x,

Shachar.

System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
myProcess.StartInfo.FileName = "calc";
myProcess.Start();
hWnd = myProcess.Handle;

if (hWnd == (IntPtr)0)
{
myProcess.Start();
hWnd = myProcess.Handle;
}
else
{
SetFocus(hWnd);
}
 
W

Willy Denoyette [MVP]

Shachar said:
Hi All,

I need to start a new process calc for example and when ever the user
click on the button the
application should setfocus to the calc application.

I use this code but it is NOT working, what I do wrong ?

10x,

Shachar.

System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
myProcess.StartInfo.FileName = "calc";
myProcess.Start();
hWnd = myProcess.Handle;

if (hWnd == (IntPtr)0)
{
myProcess.Start();
hWnd = myProcess.Handle;
}
else
{
SetFocus(hWnd);
}

The process Handle is not a Windows handle! You should use the
MainWindowHandle property instead.

Willy.
PS. Please don't cross-post to non relevant NG's?
 
G

Gabriel Lozano-Morán

This is what I have tried and the focus is set correctly to the calculator

1 using System;
2 using System.Runtime.InteropServices;
3
4 namespace ConsoleApplication3
5 {
6 class Class1
7 {
8 [STAThread]
9 static void Main(string[] args)
10 {
11 System.Diagnostics.Process myProcess = new
System.Diagnostics.Process();
12 myProcess.StartInfo.FileName = "calc";
13 myProcess.Start();
14 IntPtr hWnd = myProcess.Handle;
15 SetFocus(new HandleRef(null, hWnd));
16 }
17
18 [DllImport("user32.dll", CharSet=CharSet.Auto,
ExactSpelling=true)]
19 public static extern IntPtr SetFocus(HandleRef hWnd);
20 }
21 }

Gabriel
 
S

Shachar

Hi,

It works because windows automatically set the focus on the new process
if you lost focus and try to set the focus using :
SetFocus(new HandleRef(null, hWnd));
It is not working .

SetFocus is an api from user32.dll

Shachar
 
S

Shachar

Hi,

I tried changing it to : hWnd = myProcess.MainWindowHandle;
But it don't set.

Shachar.
 
W

Willy Denoyette [MVP]

Gabriel Lozano-Morán said:
This is what I have tried and the focus is set correctly to the calculator

1 using System;
2 using System.Runtime.InteropServices;
3
4 namespace ConsoleApplication3
5 {
6 class Class1
7 {
8 [STAThread]
9 static void Main(string[] args)
10 {
11 System.Diagnostics.Process myProcess = new
System.Diagnostics.Process();
12 myProcess.StartInfo.FileName = "calc";
13 myProcess.Start();
14 IntPtr hWnd = myProcess.Handle;
15 SetFocus(new HandleRef(null, hWnd));
16 }
17
18 [DllImport("user32.dll", CharSet=CharSet.Auto,
ExactSpelling=true)]
19 public static extern IntPtr SetFocus(HandleRef hWnd);
20 }
21 }

Gabriel

Sorry, but this won't work for tree reasons:
1. The process Handle is not a Windows Handle (HWND), what you need is the
MainWindowHandle .
2. You have to wait for the process to start before you can get at it's main
window handle.
3. You can't set the focus using SetFocus() if the HWND is not attached to
calling thread's message queue.
Check the return value of your Win32 API call (using MainWindowHandle as
Handle), you'll see that it fails (PS you should always check API return
values!).
Anyway, you need to call SetForegroundWindow API to set the focus to the
receiving HWND and activate it's thread.

Here is your modified sample...

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication3
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
System.Diagnostics.Process myProcess = new
System.Diagnostics.Process();
myProcess.StartInfo.FileName = "calc";
myProcess.Start();
myProcess.WaitForInputIdle(2000);
IntPtr hWnd = myProcess.MainWindowHandle;
Console.WriteLine(hWnd);
bool p = SetForegroundWindow(hWnd);
if(!p)
Console.WriteLine("Could not set focus");
}
[DllImport("user32.dll", CharSet=CharSet.Auto,SetLastError=true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet=CharSet.Auto,SetLastError=true)]
public static extern IntPtr SetFocus(IntPtr hWnd);
}
}


Willy.
 
S

Shachar

10x,

It works.

Shachar.

Willy Denoyette said:
Gabriel Lozano-Morán said:
This is what I have tried and the focus is set correctly to the
calculator

1 using System;
2 using System.Runtime.InteropServices;
3
4 namespace ConsoleApplication3
5 {
6 class Class1
7 {
8 [STAThread]
9 static void Main(string[] args)
10 {
11 System.Diagnostics.Process myProcess = new
System.Diagnostics.Process();
12 myProcess.StartInfo.FileName = "calc";
13 myProcess.Start();
14 IntPtr hWnd = myProcess.Handle;
15 SetFocus(new HandleRef(null, hWnd));
16 }
17
18 [DllImport("user32.dll", CharSet=CharSet.Auto,
ExactSpelling=true)]
19 public static extern IntPtr SetFocus(HandleRef hWnd);
20 }
21 }

Gabriel

Sorry, but this won't work for tree reasons:
1. The process Handle is not a Windows Handle (HWND), what you need is the
MainWindowHandle .
2. You have to wait for the process to start before you can get at it's
main window handle.
3. You can't set the focus using SetFocus() if the HWND is not attached to
calling thread's message queue.
Check the return value of your Win32 API call (using MainWindowHandle as
Handle), you'll see that it fails (PS you should always check API return
values!).
Anyway, you need to call SetForegroundWindow API to set the focus to the
receiving HWND and activate it's thread.

Here is your modified sample...

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication3
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
System.Diagnostics.Process myProcess = new
System.Diagnostics.Process();
myProcess.StartInfo.FileName = "calc";
myProcess.Start();
myProcess.WaitForInputIdle(2000);
IntPtr hWnd = myProcess.MainWindowHandle;
Console.WriteLine(hWnd);
bool p = SetForegroundWindow(hWnd);
if(!p)
Console.WriteLine("Could not set focus");
}
[DllImport("user32.dll", CharSet=CharSet.Auto,SetLastError=true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet=CharSet.Auto,SetLastError=true)]
public static extern IntPtr SetFocus(IntPtr hWnd);
}
}


Willy.
 
G

Gabriel Lozano-Morán

I guess I was a little to hasty in my post. Sorry bout that...

Bedankt Willy :)

Gabriel

Willy Denoyette said:
Gabriel Lozano-Morán said:
This is what I have tried and the focus is set correctly to the calculator

1 using System;
2 using System.Runtime.InteropServices;
3
4 namespace ConsoleApplication3
5 {
6 class Class1
7 {
8 [STAThread]
9 static void Main(string[] args)
10 {
11 System.Diagnostics.Process myProcess = new
System.Diagnostics.Process();
12 myProcess.StartInfo.FileName = "calc";
13 myProcess.Start();
14 IntPtr hWnd = myProcess.Handle;
15 SetFocus(new HandleRef(null, hWnd));
16 }
17
18 [DllImport("user32.dll", CharSet=CharSet.Auto,
ExactSpelling=true)]
19 public static extern IntPtr SetFocus(HandleRef hWnd);
20 }
21 }

Gabriel

Sorry, but this won't work for tree reasons:
1. The process Handle is not a Windows Handle (HWND), what you need is the
MainWindowHandle .
2. You have to wait for the process to start before you can get at it's main
window handle.
3. You can't set the focus using SetFocus() if the HWND is not attached to
calling thread's message queue.
Check the return value of your Win32 API call (using MainWindowHandle as
Handle), you'll see that it fails (PS you should always check API return
values!).
Anyway, you need to call SetForegroundWindow API to set the focus to the
receiving HWND and activate it's thread.

Here is your modified sample...

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication3
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
System.Diagnostics.Process myProcess = new
System.Diagnostics.Process();
myProcess.StartInfo.FileName = "calc";
myProcess.Start();
myProcess.WaitForInputIdle(2000);
IntPtr hWnd = myProcess.MainWindowHandle;
Console.WriteLine(hWnd);
bool p = SetForegroundWindow(hWnd);
if(!p)
Console.WriteLine("Could not set focus");
}
[DllImport("user32.dll", CharSet=CharSet.Auto,SetLastError=true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet=CharSet.Auto,SetLastError=true)]
public static extern IntPtr SetFocus(IntPtr hWnd);
}
}


Willy.
 

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