CreateProcess and MoveWindow

T

Thomas Wieczorek

Hello!

I want to open a file in an external application, resize the window
and move it.

I thought I could do it with CreateProcess and the STARTUPINFO
structure, but it doesn't work for me.
So I tried to use MoveWindow to move and resize the application(I know
its handler from CreateProcess), but I am getting False returned and
nothing changes with the application window.

Can you please help me?

CODE:
Imports System.Runtime.InteropServices

Public Class Form1
Inherits System.Windows.Forms.Form

' <snip>

<Flags()> _
Private Enum START_UP_INFO_FLAGS
STARTF_USESHOWWINDOW = &H1
STARTF_USESIZE = &H2
STARTF_USEPOSITION = &H4
STARTF_USECOUNTCHARS = &H8
STARTF_USEFILLATTRIBUTE = &H10
STARTF_RUNFULLSCREEN = &H20
STARTF_FORCEONFEEDBACK = &H40
STARTF_FORCEOFFFEEDBACK = &H80
STARTF_USESTDHANDLES = &H100
End Enum

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Structure STARTUPINFO
Public cb As Integer
Public lpReserved As String
Public lpDesktop As String
Public lpTitle As String
Public dwX As Integer
Public dwY As Integer
Public dwXSize As Integer
Public dwYSize As Integer
Public dwXCountChars As Integer
Public dwYCountChars As Integer
Public dwFillAttribute As Integer
Public dwFlags As Integer
Public wShowWindow As Short
Public cbReserved2 As Short
Public lpReserved2 As Integer
Public hStdInput As Integer
Public hStdOutput As Integer
Public hStdError As Integer
End Structure

Structure PROCESS_INFORMATION
Public hProcess As IntPtr
Public hThread As IntPtr
Public dwProcessId As Integer
Public dwThreadId As Integer
End Structure

<StructLayout(LayoutKind.Sequential)> _
Structure SECURITY_ATTRIBUTES
Public nLength As Integer
Public lpSecurityDescriptor As IntPtr
Public bInheritHandle As Integer
End Structure

<DllImport("kernel32.dll")> _
Shared Function CreateProcess(ByVal lpApplicationName As String, _
ByVal lpCommandLine As String, ByRef lpProcessAttributes As
SECURITY_ATTRIBUTES, _
ByRef lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal
bInheritHandles As Boolean, _
ByVal dwCreationFlags As UInt32, ByVal lpEnvironment As
IntPtr, ByVal lpCurrentDirectory As String, _
<[In]()> ByRef lpStartupInfo As STARTUPINFO, _
<[Out]()> ByRef lpProcessInformation As PROCESS_INFORMATION)
As Boolean
End Function

<DllImport("kernel32.dll")> _
Shared Sub GetStartupInfo(<Out()> ByRef lpStartupInfo As
STARTUPINFO)
'Declare Sub GetStartupInfo Lib "kernel32.dll" (<Out()> ByRef
lpStartupInfo As STARTUPINFO)
End Sub

<DllImport("user32.dll")> _
Shared Function MoveWindow(ByVal hWnd As IntPtr, ByVal x As
Integer, ByVal y As Integer, ByVal nWidth As Integer, _
ByVal nHeight As Integer, ByVal
bRepaint As Boolean) As Boolean

End Function

Private Sub btnOpenWindow_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnOpenWindow.Click
Dim sInfo As STARTUPINFO = New STARTUPINFO
'sInfo.wShowWindow = 1
sInfo.dwX = 20
sInfo.dwY = 20
sInfo.dwXSize = 50
sInfo.dwYSize = 50
sInfo.dwFlags = START_UP_INFO_FLAGS.STARTF_USEPOSITION Or _
START_UP_INFO_FLAGS.STARTF_USESIZE

Dim retValue As Boolean
Dim pInfo As PROCESS_INFORMATION = New PROCESS_INFORMATION

' OPENS THE NOTEPAD, BUT DOES NOT RESIZE
' RETURNS TRUE
retValue = CreateProcess(Nothing, "c:\\windows\\system32\
\NotePad.exe Z:\PATH.txt", _
Nothing, Nothing, False, UInt32.Parse("0"), Nothing,
Nothing, sInfo, pInfo)

If retValue Then
' DOES NOT WORK
' RETURNS FALSE
retValue = MoveWindow(pInfo.hProcess, 2, 2, 100, 100,
True)
End If
End Sub
End Class
 
M

Mattias Sjögren

Thomas,
Can you please help me?

CreateProcess returns a *process* handle in pInfo.hProcess, but
MoveWindow takes a *window* handle. Two entirely different things.

To get the (main) window handle from the process you just created you
can use EnumThreadWindows and pass in pInfo.dwThreadId. (All this
assumes that a window actually was created and that it was created on
the startup thread). You may want to call WaitForInputIdle before
trying to enumerate windows.


Mattias
 
T

Thomas Wieczorek

Hello Mattias,
CreateProcess returns a *process* handle in pInfo.hProcess, but
MoveWindow takes a *window* handle. Two entirely different things.

Ah, I didn't know about it.
To get the (main) window handle from the process you just created you
can use EnumThreadWindows and pass in pInfo.dwThreadId. (All this
assumes that a window actually was created and that it was created on
the startup thread). You may want to call WaitForInputIdle before
trying to enumerate windows.

Thank you! It works.

Regards, Thomas
 

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