By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,238 Members | 1,804 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,238 IT Pros & Developers. It's quick & easy.

Problem trying to position a process window - please advise

P: n/a
For this first time today I used the System.Diagnositcs namespace to
launch a program from my c# code. The program launches OK but I have
something which has completely stumped me.

The SetWindowPos method does not work. If I run the code as it is
presented below, app.exe launches in its own window and is displayed at
the top left part of the screen. However it isn't repositioned which is
what the last piece of code should do. HOWEVER if i end my c# program
and leave app.exe open - and then comment out the launchapp() part of
Form1_load and just run my c# program again the window is moved as
expected. So for some reason the SetWindowPos method is only working if
app.exe is open BEFORE I run my c# code, and not when I use my C# code
to open app.exe. Any ideas why this is please?

NB
The original (originalapp.exe) ran in fullscreen. Somebody wrote a
programme app.exe which runs originalapp.exe in a window. This is the
reason why I have to use FindWindow to find the Hwnd of originalapp.exe
from within app.exe and can't just query the process p for it's Hwnd.

Thanks very much for comments,

Gary-

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace WindowsApplication1
{

public partial class Form1 : Form
{

#region static bool SetWindowPos (hWnd, hWndInsertAfter, X, Y,
cx, cy, uFlags) *via imported dll*
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr
hWndInsertAfter,
int X, int Y, int cx, int cy, uint uFlags);
private const int HWND_TOP = 0;
#endregion

#region static int FindWindow(_ClassName, _WindowName) *via
imported dll*
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError =
true)]
private static extern int FindWindow(string _ClassName,
string _WindowName);
#endregion

#region static void GetWindowText(h, s, nMaxCount) *via
imported dll*
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError =
true)]
public static extern void GetWindowText(int h,
StringBuilder s, int nMaxCount);
#endregion
public Form1()
{
InitializeComponent();
}
private void launchapp()
{
Process p = new Process();
p.StartInfo.FileName = @"C:\Program
Files\app\directory\app.exe";
p.StartInfo.WorkingDirectory = @"C:\Program
Files\app\directory\";
p.StartInfo.WindowStyle =
System.Diagnostics.ProcessWindowStyle.Hidden;
p.Start();
return;
}
private void Form1_Load(object sender, EventArgs e)
{

launchapp();

// window handle, place window at top of Z order, WP left,
WP top, width, height
int handle = FindWindow(null, "Title of Application
Window");
SetWindowPos((IntPtr)handle, (IntPtr)HWND_TOP, 5, 5, 5,
5,0);
}
}
}

Dec 20 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Have you tried debugging this in conjunction with Spy++ to see if you are
actually getting the correct window handle? Also, have you checked the return
values of your Win32 API calls to see if they are returning success?

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #2

P: n/a
The original (originalapp.exe) ran in fullscreen. Somebody wrote a
programme app.exe which runs originalapp.exe in a window. This is the
reason why I have to use FindWindow to find the Hwnd of
originalapp.exe
from within app.exe and can't just query the process p for it's Hwnd.
Thanks very much for comments,
Why not improve your search by using FindWindowEx so that you can narrow
your search to the children of Process.MainWindowHandle?

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #3

P: n/a
Dustin thankyou, I have queried the return value of my SetWindowPos and
it is returning false when I run it first time, and True when I cancel
my program, comment out the launchapp, and rerun the program. So it's
the SetWindowPos that's failing first time around.

I'll look into spy++ that you mentioned now, and see if it sheds any
light on why this is.

Many Thanks,

Gary-

Dustin Campbell wrote:
The original (originalapp.exe) ran in fullscreen. Somebody wrote a
programme app.exe which runs originalapp.exe in a window. This is the
reason why I have to use FindWindow to find the Hwnd of
originalapp.exe
from within app.exe and can't just query the process p for it's Hwnd.
Thanks very much for comments,

Why not improve your search by using FindWindowEx so that you can narrow
your search to the children of Process.MainWindowHandle?

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #4

P: n/a
Unfonruntely i don't seem to have spy++ i'm using Visual C# express and
don't think it comes with that tool. I have VS 2005 at home in the
attic i think but i'll have to find it.

In the meantime, i'll try to use that other function you mentioned.

Thanks,

Gary-

ga********@myway.com wrote:
Dustin thankyou, I have queried the return value of my SetWindowPos and
it is returning false when I run it first time, and True when I cancel
my program, comment out the launchapp, and rerun the program. So it's
the SetWindowPos that's failing first time around.

I'll look into spy++ that you mentioned now, and see if it sheds any
light on why this is.

Many Thanks,

Gary-

Dustin Campbell wrote:
The original (originalapp.exe) ran in fullscreen. Somebody wrote a
programme app.exe which runs originalapp.exe in a window. This is the
reason why I have to use FindWindow to find the Hwnd of
originalapp.exe
from within app.exe and can't just query the process p for it's Hwnd.
Thanks very much for comments,
Why not improve your search by using FindWindowEx so that you can narrow
your search to the children of Process.MainWindowHandle?

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #5

P: n/a
I dont really understand the difference between FindWindow and
FindWindowEx, i'm new to all of this - so it's quite confusing.

Gary-

ga********@myway.com wrote:
Dustin thankyou, I have queried the return value of my SetWindowPos and
it is returning false when I run it first time, and True when I cancel
my program, comment out the launchapp, and rerun the program. So it's
the SetWindowPos that's failing first time around.

I'll look into spy++ that you mentioned now, and see if it sheds any
light on why this is.

Many Thanks,

Gary-

Dustin Campbell wrote:
The original (originalapp.exe) ran in fullscreen. Somebody wrote a
programme app.exe which runs originalapp.exe in a window. This is the
reason why I have to use FindWindow to find the Hwnd of
originalapp.exe
from within app.exe and can't just query the process p for it's Hwnd.
Thanks very much for comments,
Why not improve your search by using FindWindowEx so that you can narrow
your search to the children of Process.MainWindowHandle?

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #6

P: n/a
Dustin thankyou, I have queried the return value of my SetWindowPos
and it is returning false when I run it first time, and True when I
cancel my program, comment out the launchapp, and rerun the program.
So it's the SetWindowPos that's failing first time around.

I'll look into spy++ that you mentioned now, and see if it sheds any
light on why this is.
Is the handle returned by FindWindow (and being passed into SetWindowPos)
valid?

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #7

P: n/a
For this first time today I used the System.Diagnositcs namespace to
launch a program from my c# code. The program launches OK but I have
something which has completely stumped me.

The SetWindowPos method does not work. If I run the code as it is
presented below, app.exe launches in its own window and is displayed
at the top left part of the screen. However it isn't repositioned
which is what the last piece of code should do. HOWEVER if i end my c#
program and leave app.exe open - and then comment out the launchapp()
part of Form1_load and just run my c# program again the window is
moved as expected. So for some reason the SetWindowPos method is only
working if app.exe is open BEFORE I run my c# code, and not when I use
my C# code to open app.exe. Any ideas why this is please?
Is it possible that the problem is because your "launchapp" code makes the
window hidden?

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #8

P: n/a
I dont really understand the difference between FindWindow and
FindWindowEx, i'm new to all of this - so it's quite confusing.
FindWindowEx allows you to specify a few extra parameters to narrow your
search. If the window that your searching for is parented by another window
(as you said in your original post), you should be able to use FindWindowEx
to locate that window and pass the Process.MainWindowHandle as the parent
window. Here's how I define both APIs in C#:

[DllImport("user32.dll")]
static extern IntPtr FindWindow([MarshalAs(UnmanagedType.LPTStr)] string
lpClassName, [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName);

[DllImport("user32.dll")]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
[MarshalAs(UnmanagedType.LPTStr)] string lpszClass, [MarshalAs(UnmanagedType.LPTStr)]
string lpszWindow);

Using the code that you original posted (untested!!):

private Process launchapp()
{
Process p = new Process();
p.StartInfo.FileName = @"C:\Program Files\app\directory\app.exe";
p.StartInfo.WorkingDirectory = @"C:\Program Files\app\directory\";
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.Start();
return p;
}

private void Form1_Load(object sender, EventArgs e)
{
launchapp();

// window handle, place window at top of Z order, WP left, WP top, width,
height
int handle = FindWindowEx(p.MainWindowHandle, IntPtr.Zero, null, "Title
of Application Window");
SetWindowPos((IntPtr)handle, (IntPtr)HWND_TOP, 5, 5, 5, 5,0);
}

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #9

P: n/a
After much investigation and armed with your kind advice Dustin I have
found the problem.

There is a delay between the launch of app.exe and the availability of
the Hwnd that i'm searching for.

I have managed to overcome this by using the following: -

while (handle == 0)
{
handle = FindWindow(null, "title of application");
}

//here i make the calls to the api's only once my hwnd has a value that
isn't 0.

The only problem with this is it causes a fairly significant delay
between the time of launching my c# code, and the app.exe actually
being launched. (Which surprised me because my P.Start() is actually
BEFORE the while code i have placed above.

Any ideas why this delay may be happening and how i might overcome it?

Thanks,

Gary-

Dec 20 '06 #10

P: n/a
After much investigation and armed with your kind advice Dustin I have
found the problem.

There is a delay between the launch of app.exe and the availability of
the Hwnd that i'm searching for.

I have managed to overcome this by using the following: -

while (handle == 0)
{
handle = FindWindow(null, "title of application");
}
//here i make the calls to the api's only once my hwnd has a value
that isn't 0.

The only problem with this is it causes a fairly significant delay
between the time of launching my c# code, and the app.exe actually
being launched. (Which surprised me because my P.Start() is actually
BEFORE the while code i have placed above.

Any ideas why this delay may be happening and how i might overcome it?
You could get a similar effect by calling Process.WaitForInputIdle() after
calling Process.Start(). Assuming that the process that your starting has
a GUI (it appears to), this will block your thread until it is ready.

Process.Start() does just that -- it starts the process. After starting the
process, there is initialization that takes place in that process before
the main window is created. However, the Process.Start() call will have already
returned by the time that happens. There's no way to actually speed up the
start of that process -- you simply don't have control of that.

A simple solution to keep your application from blocking might be to just
use a System.Windows.Forms.Timer on your form and check for the handle ever
10 milliseconds or so.

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #11

P: n/a
Dustin. Process.WaitForInputIdle();

Is doing exactly what I needed. It's achieving the same effect as my
while loop, but it isn't creating the significant (approx 10 second)
delay.

Thank you,

Your advice has been invaluable.

Gary-

Dustin Campbell wrote:
After much investigation and armed with your kind advice Dustin I have
found the problem.

There is a delay between the launch of app.exe and the availability of
the Hwnd that i'm searching for.

I have managed to overcome this by using the following: -

while (handle == 0)
{
handle = FindWindow(null, "title of application");
}
//here i make the calls to the api's only once my hwnd has a value
that isn't 0.

The only problem with this is it causes a fairly significant delay
between the time of launching my c# code, and the app.exe actually
being launched. (Which surprised me because my P.Start() is actually
BEFORE the while code i have placed above.

Any ideas why this delay may be happening and how i might overcome it?

You could get a similar effect by calling Process.WaitForInputIdle() after
calling Process.Start(). Assuming that the process that your starting has
a GUI (it appears to), this will block your thread until it is ready.

Process.Start() does just that -- it starts the process. After starting the
process, there is initialization that takes place in that process before
the main window is created. However, the Process.Start() call will have already
returned by the time that happens. There's no way to actually speed up the
start of that process -- you simply don't have control of that.

A simple solution to keep your application from blocking might be to just
use a System.Windows.Forms.Timer on your form and check for the handle ever
10 milliseconds or so.

Best Regards,
Dustin Campbell
Developer Express Inc.
Dec 20 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.