• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 621
  • Last Modified:

Move Window Of Another Program?

Hi,

I want to move a window of another program to the top left of the screen.
At the moment I'm using FindWindow api to try to get the window hWnd.
After that I tried using MoveWindow api to move the window but it didn't do anything...

My code is:

Public Class Form1
    Private Declare Auto Function FindWindow Lib "user32" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As IntPtr

    Private Declare Function MoveWindow Lib "user32" Alias "MoveWindow" ( _
    ByVal hwnd As Integer, _
    ByVal x As Integer, _
    ByVal y As Integer, _
    ByVal nWidth As Integer, _
    ByVal nHeight As Integer, _
    ByVal bRepaint As Integer) As Integer

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim D2Handle As IntPtr = FindWindow(vbNullString, "Window Title")
        MoveWindow(D2Handle, 0, 0, 800, 600, 0)

    End Sub
End Class

Can anyone help please?
Thanks In Advance
mms_master
0
mms_master
Asked:
mms_master
  • 20
  • 10
  • 8
1 Solution
 
PockyMasterCommented:
I'm sorry to disappoint you, but your code seems right.
But are you sure you got your window title right?
0
 
mms_masterAuthor Commented:
The window title is correct.
Does IntPtr have to be converted to another format or something?
I thought maybe a hWnd is different to an IntPtr.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
IntPtr and Integer are interchangeable in this case.

As PockyMaster said, this should work.

Try it with Calculator...

Public Class Form1

    Private Declare Auto Function FindWindow Lib "user32" ( _
        ByVal lpClassName As String, _
        ByVal lpWindowName As String) As IntPtr

    Private Declare Function MoveWindow Lib "user32" Alias "MoveWindow" ( _
        ByVal hWnd As IntPtr, ByVal x As Integer, ByVal y As Integer, _
        ByVal nWidth As Integer, ByVal nHeight As Integer, _
        ByVal bRepaint As Integer) As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Process.GetProcessesByName("calc").Length = 0 Then
            Dim p As Process = Process.Start("calc")
            p.WaitForInputIdle()
        End If

        Dim calcWnd As IntPtr = FindWindow(vbNullString, "Calculator")
        MoveWindow(calcWnd, 0, 0, 800, 600, 1)
    End Sub

End Class
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
mms_masterAuthor Commented:
I actually just tested it with internet explorer before I saw your post.
It worked with internet explorer...
But I know that the title of the window is correct.
To check that it was finding the window I used this code after calling the FindWindow api:

        If D2Handle.Equals(IntPtr.Zero) Then
            MsgBox("Zero")
            Exit Sub
        Else
            MsgBox(D2Handle)
        End If

The msgbox returned: 26411218
So I know that it is finding the window. But for some reason it is not moving the window. The window I am trying to move is a game playing in a window instead of full screen. I don't know if this makes any difference.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
It is always possible that the game is preventing its window from being moved or that it is constantly resetting its position.  Can you move this window normally with the mouse?
0
 
mms_masterAuthor Commented:
I can move it normaly with the mouse.
Also I have another program that moves the window, so I know that it is possible.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I set the "Repaint" option to True in my example:

    MoveWindow(calcWnd, 0, 0, 800, 600, 1)

The "1" forces a repaint of the window.  Is it possible that the window is moving but not repainting so you can't see its new position?

Try it with the last parameter set to 1.
0
 
mms_masterAuthor Commented:
Just a thought, is it possible that because the window is not resisable it is stopping the MoveWindow api because it tries to resize it to 800x600?
0
 
mms_masterAuthor Commented:
Setting repaint to true didn't work.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
That is possible (though I haven't tested it).

Do you want it to be 800x600?  Or did you just stick those arbitrary numbers in there for testing?

If you want to preserve the current size of the window, then use the GetWindowRect() API to determine its size.
0
 
mms_masterAuthor Commented:
I chose 800x600 because the video options on the game are set to 800x600.
So i assumed that that would be the size of the window...
Theres a chance that the window could be slightly bigger because maybe the area inside the window is 800x600 and not the actual window itself.

Ill try the GetWindowRect api now.
0
 
mms_masterAuthor Commented:
I used the following api:

Private Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Integer, ByVal lpRect As RECT) As Integer

and got an error saying that RECT isn't defined.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
It should be:

    Public Structure RECT
        Public Left As Integer
        Public Top As Integer
        Public Right As Integer
        Public Bottom As Integer
    End Structure

    Private Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" _
        (ByVal hWnd As Integer, ByRef lpRect As RECT) As Integer

*** Notice the RECT is passed ByRef.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Then of course you have to compute the width:

    Dim myWidth As Integer = someRect.Right - someRect.Left + 1

...similar for the height...
0
 
mms_masterAuthor Commented:
I now have the following code:

        Dim D2Handle As IntPtr = FindWindow(vbNullString, "Diablo II")
        If D2Handle.Equals(IntPtr.Zero) Then
            MsgBox("Couldn't Find Instance...")
            Exit Sub
        End If

        GetWindowRect(D2Handle, varRect)
        varMoveWindow = MoveWindow(D2Handle, 10, 10, varRect.Right - varRect.Left + 1, varRect.Bottom - varRect.Top + 1, 1)
        If varMoveWindow.Equals(IntPtr.Zero) Then
            MsgBox("Move Failed!")
        End If

It still doesn't work and I don't get either of the message boxes.
0
 
mms_masterAuthor Commented:
Using the GetWindowRect api and the following code:

MsgBox(varRect.Right - varRect.Left + 1 & "x" & varRect.Bottom - varRect.Top + 1, 1)

the size of the window is shown as 161x32. But my screen resolution is 1024x768 and the window covers most of the screen... so I can't see how the size shown above is right.
This doesn't realy bother me though, i just want to get the window to move to top left of the screen.
0
 
PockyMasterCommented:
Just a crazy thought, but try to move it to -100, -100. Are you sure the window you are selecting is not inside another window?
0
 
mms_masterAuthor Commented:
I just tried to move it to -100, -100 and still nothing happend :(
0
 
PockyMasterCommented:
Did you try spy++ to catch the window?

Try to use the GetWindowRect API to check the current location your window thinks he's on.
0
 
mms_masterAuthor Commented:
It says that its current position is: (its roughly in the centre of my screen)

Top=-32000
Bottom=-31969
Left=-32000
Right=-31840
0
 
PockyMasterCommented:
and now try to do that for your internet explorer, and see what it says for that
0
 
mms_masterAuthor Commented:
hmm big difference:
Top=86
Bottom=686
Left=108
Right=908
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Use Spy++ to compare the handle of the window you see with the hande of the window being returned by FindWindow().

Are they the same?  (guessing not)
0
 
mms_masterAuthor Commented:
Whats spy++? lol
0
 
PockyMasterCommented:
Spy++ is a tool that you get with visual studio
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Spy++ is a tool that comes with Visual Studio that allows you to "spy" into windows on your system.  It gives you information as the handle, size, location, class name, and the attributes that determine how it looks.  It also gives a treeview giving a hierachical view of the windows with relation to each other.  Additionally you can "watch" a window to see all the windows messages being processed in its pump.

Many developers also use WinSpector:
http://www.windows-spy.com/
0
 
mms_masterAuthor Commented:
Not sure if i've got it.
Im using vb.net 2005 express. It's a free version that you can download from microsofts website. But i dont think they include all the tools that you get with the proffesional version.
Is it on the start bar? or on one of the menus in vb?
0
 
PockyMasterCommented:
It should be in the tools menu, but I'm not sure if they give it for free
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I don't think Spy++ comes with the Express versions.

Try Winspector from my link above.
0
 
mms_masterAuthor Commented:
no its not there.
Ill get WinSpector now.
0
 
PockyMasterCommented:
For testing you might also try like this:
Find your PID in your taskmanager

Dim proc As Process
        proc = Process.GetProcessById(myPID)
        proc.MainWindowHandle  <-- your handle
0
 
mms_masterAuthor Commented:
is the handle the bit where it says:

Properties for window 0x001708FE
0
 
mms_masterAuthor Commented:
I used the following code:

        Dim D2Handle As IntPtr = FindWindow(vbNullString, "Diablo II")
        If D2Handle.Equals(IntPtr.Zero) Then
            MsgBox("Couldn't Find Instance...")
            Exit Sub
        End If

        GetWindowRect(D2Handle, varRect)
        MsgBox(D2Handle)
        'Dim temptxt As String = "Top=" & varRect.top & " Bottom=" & varRect.bottom & " Left=" & varRect.left & " Right=" & varRect.right
        'text1.text = temptxt
        Dim proc As Process
        proc = Process.GetProcessById("1932")
        MsgBox(proc.MainWindowHandle)

and got the same handle from both message boxes.
0
 
PockyMasterCommented:
Well, I've never tried it with games, but your last test proofs to me you got the right window... It might be the game is behaving different than we expect. Or this question is out of my league.. I will sleep on the answer for now :D
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Correct.  That is the windows handle in WinSpector.

To display your IntPtr in hex you can do this:

    MsgBox(D2Handle.ToInt32.ToString("x"))
0
 
mms_masterAuthor Commented:
I've increased the points for this question from 50 to 100.
0
 
mms_masterAuthor Commented:
I've been given some code that is supposed to work in C++
I'm in the middle of re-writing it in VB.NET but I need to know the integer value for SWP_NORESIZE. I can't find it anywhere on the internet.
0
 
mms_masterAuthor Commented:
I've FINALY got it to work :D
Just encase it was bugging anyone here's how I done it:

    Private Declare Auto Function FindWindow Lib "user32" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As IntPtr

    Private Declare Function ShowWindow Lib "user32" Alias "ShowWindow" _
    (ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer

    Private Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" _
    (ByVal hwnd As Integer, _
    ByVal hWndInsertAfter As Integer, _
    ByVal x As Integer, _
    ByVal y As Integer, _
    ByVal cx As Integer, _
    ByVal cy As Integer, _
    ByVal wFlags As Integer) As Integer


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim D2Handle As IntPtr = FindWindow("Diablo II", vbNullString)

        If D2Handle.Equals(IntPtr.Zero) Then
            MsgBox("Couldn't Find Instance...")
            Exit Sub
        End If

        ShowWindow(D2Handle, 9) '9 = restore (equivalent of vb6's SW_RESTORE)

        If SetWindowPos(D2Handle, 0, 0, 0, 0, 0, 1) Then 'The 1 = vb6's SWP_NORESIZE
            ':D
        Else
            MsgBox("Failed to move window.")
        End If
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 20
  • 10
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now