Open an application and set its window position with VBA

tweak_four17

New Member
Joined
Aug 2, 2013
Messages
14
Hello,

I'm trying to create a macro in VBA using excel 2003 and/or 2010 to launch an external application. My system has 4 monitors attached to it and I would like to be able to position the application on a specific part of one of the monitors once it is opened.

Currently I am using

Dim Filename As String
Dim retVal As Variant
Filename = "filename.entension"
retVal = Shell("C:\Program Files\Program.exe " & Filename, vbMaximizedFocus)

This opens the correct file with the program but it only ever opens on monitor 1 (and not maximized either I might add)

I've managed to get Internet Explorer to open where I want by using
Set objIE = CreateObject("InternetExplorer.Application")
With objIE
.navigate "www.yahoo.com"
.visible = true
.Top = -1080
.Left = 3840
.Height = 1080
.Width = 1920
End With

Is it possible to do something similar with "Program.exe"? The program in question is a third party business application, not a microsoft application or anything like that..
 

Excel Facts

When did Power Query debut in Excel?
Although it was an add-in in Excel 2010 & Excel 2013, Power Query became a part of Excel in 2016, in Data, Get & Transform Data.
The Shell command should return a handle to the window.

I would try two things: first try:
Set RetVal = Shell(etc)

Step through it to see if it creates an error here. If not then Retval should be the object and you can use it now just like ObjIE in your other example.

If it does create an issue, then look at the nearly last post in this thread, where you can see how to get a handle. You can then use Win API calls to move the application (A handle is as it sounds, the thing with which you can manipulate the application)

http://www.mrexcel.com/forum/excel-questions/580989-shell-commands-excel.html
 
Upvote 0
The program steps through everything I have so far and executes the shell command. However from that point trying to set Retval.top = 100 returns an object required error. I tried following the other thread you linked but I am at a loss on that. May need to do some googling on Win API calls if that is going to be the best course of action. Thanks.
 
Upvote 0
http://www.mrexcel.com/forum/excel-...programs-using-visual-basic-applications.html
that may be the ticket. Not within Excel, but still for you to launch everything as you want it

I have tried it with limited success thorough VBA and the windows API. Most programs use their last position as their next start-up position, and will ignore position & size info at start-up. Which means you will need to get the handle properly to do it. This is how far I got. See the comments in the code for additional information.

<font face=Courier New><SPAN style="color:#00007F">Option</SPAN> <SPAN style="color:#00007F">Explicit</SPAN><br><br>  <SPAN style="color:#00007F">Private</SPAN> <SPAN style="color:#00007F">Type</SPAN> PROCESS_INFORMATION<br>     hProcess <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     hThread <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwProcessId <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwThreadId <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>  <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Type</SPAN><br>    <SPAN style="color:#007F00">' STARTUPINFO info: _<br>      http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx</SPAN><br>  <SPAN style="color:#00007F">Private</SPAN> <SPAN style="color:#00007F">Type</SPAN> STARTUPINFO<br>     cb <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     lpReserved <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN><br>     lpDesktop <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN><br>     lpTitle <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN><br>     dwX <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwY <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwXSize <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwYSize <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwXCountChars <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwYCountChars <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwFillAttribute <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     dwFlags <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     wShowWindow <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Integer</SPAN><br>     cbReserved2 <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Integer</SPAN><br>     lpReserved2 <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     hStdInput <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     hStdOutput <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     hStdError <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>  <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Type</SPAN><br><br>    <SPAN style="color:#007F00">' CreateProcess info: _<br>      http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx</SPAN><br>  <SPAN style="color:#00007F">Private</SPAN> <SPAN style="color:#00007F">Declare</SPAN> <SPAN style="color:#00007F">Function</SPAN> CreateProcess <SPAN style="color:#00007F">Lib</SPAN> "kernel32" _<br>     Alias "CreateProcessA" _<br>     (<SPAN style="color:#00007F">ByVal</SPAN> lpApplicationName <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>, _<br>     <SPAN style="color:#00007F">ByVal</SPAN> lpCommandLine <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>, _<br>     lpProcessAttributes <SPAN style="color:#00007F">As</SPAN> Any, _<br>     lpThreadAttributes <SPAN style="color:#00007F">As</SPAN> Any, _<br>     <SPAN style="color:#00007F">ByVal</SPAN> bInheritHandles <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, _<br>     <SPAN style="color:#00007F">ByVal</SPAN> dwCreationFlags <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, _<br>     lpEnvironment <SPAN style="color:#00007F">As</SPAN> Any, _<br>     <SPAN style="color:#00007F">ByVal</SPAN> lpCurrentDriectory <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>, _<br>     lpStartupInfo <SPAN style="color:#00007F">As</SPAN> STARTUPINFO, _<br>     lpProcessInformation <SPAN style="color:#00007F">As</SPAN> PROCESS_INFORMATION) <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br><br>  <SPAN style="color:#00007F">Private</SPAN> <SPAN style="color:#00007F">Declare</SPAN> <SPAN style="color:#00007F">Function</SPAN> OpenProcess <SPAN style="color:#00007F">Lib</SPAN> "kernel32.dll" _<br>     (<SPAN style="color:#00007F">ByVal</SPAN> dwAccess <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, _<br>     <SPAN style="color:#00007F">ByVal</SPAN> fInherit <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Integer</SPAN>, _<br>     <SPAN style="color:#00007F">ByVal</SPAN> hObject <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>) <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br><br>  <SPAN style="color:#00007F">Private</SPAN> <SPAN style="color:#00007F">Declare</SPAN> <SPAN style="color:#00007F">Function</SPAN> TerminateProcess <SPAN style="color:#00007F">Lib</SPAN> "kernel32" _<br>     (<SPAN style="color:#00007F">ByVal</SPAN> hProcess <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, _<br>     <SPAN style="color:#00007F">ByVal</SPAN> uExitCode <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>) <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br><br>  <SPAN style="color:#00007F">Private</SPAN> <SPAN style="color:#00007F">Declare</SPAN> <SPAN style="color:#00007F">Function</SPAN> CloseHandle <SPAN style="color:#00007F">Lib</SPAN> "kernel32" _<br>     (<SPAN style="color:#00007F">ByVal</SPAN> hObject <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>) <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br><br>  <SPAN style="color:#00007F">Const</SPAN> SYNCHRONIZE = 1048576<br>  <SPAN style="color:#00007F">Const</SPAN> NORMAL_PRIORITY_CLASS = &H20&<br>  <SPAN style="color:#00007F">Const</SPAN> STARTF_USEPOSITION = &H4&<br>  <SPAN style="color:#00007F">Const</SPAN> STARTF_USESIZE = &H2&<br>  <br><br>  <SPAN style="color:#00007F">Private</SPAN> <SPAN style="color:#00007F">Sub</SPAN> Form_Click()<br>     <SPAN style="color:#00007F">Dim</SPAN> pInfo <SPAN style="color:#00007F">As</SPAN> PROCESS_INFORMATION<br>     <SPAN style="color:#00007F">Dim</SPAN> sInfo <SPAN style="color:#00007F">As</SPAN> STARTUPINFO<br>     <SPAN style="color:#00007F">Dim</SPAN> sNull <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN><br>     <SPAN style="color:#00007F">Dim</SPAN> lSuccess <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>     <SPAN style="color:#00007F">Dim</SPAN> lRetValue <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br><br>     <SPAN style="color:#00007F">With</SPAN> sInfo<br>        .cb = Len(sInfo)<br>        <SPAN style="color:#007F00">'set flag to tell that size and position info _<br>         has been set in structure</SPAN><br>        .dwFlags = STARTF_USESIZE + STARTF_USEPOSITION<br>        <SPAN style="color:#007F00">' set position and size</SPAN><br>        .dwX = 200<br>        .dwY = 100<br>        .dwXSize = 800<br>        .dwYSize = 400<br>    <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">With</SPAN><br>     lSuccess = CreateProcess(sNull, _<br>                             "C:\Program Files\7-Zip\7zFM.exe", _<br>                             <SPAN style="color:#00007F">ByVal</SPAN> 0&, _<br>                             <SPAN style="color:#00007F">ByVal</SPAN> 0&, _<br>                             1&, _<br>                             NORMAL_PRIORITY_CLASS, _<br>                             <SPAN style="color:#00007F">ByVal</SPAN> 0&, _<br>                             sNull, _<br>                             sInfo, _<br>                             pInfo)<br>     <SPAN style="color:#00007F">If</SPAN> lSuccess = <SPAN style="color:#00007F">False</SPAN> <SPAN style="color:#00007F">Then</SPAN> MsgBox "launch failed"<br>     lRetValue = CloseHandle(pInfo.hThread)<br>     lRetValue = CloseHandle(pInfo.hProcess)<br><br>  <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN><br>      <br>      </FONT>

a link explaining about the failure to use position info:
Answer : CreateProcess ignores dwX,dwY parameters in STARTUPINFO
 
Upvote 0
Thanks for your help sijpie, I tried to follow the code you posted in post #4, but as you linked to in another thread, it will not control the window size and position it just defaults to the last known position.

Code:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  
 Private Declare Function MoveWindow Lib "user32.dll" (ByVal hWnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long

Dim lSuccess As Long
Dim lHwnd As Long
 
    lHwnd = FindWindow("wndClass_desked_gsk", vbNullString)
    Debug.Print lHwnd


 lSuccess = MoveWindow(ByVal 6752804, ByVal 0, ByVal 0, ByVal 1920, ByVal 1200, ByVal 1)
If lSuccess = False Then MsgBox "failed"

This code I used to find the hwnd of the open excel window and from there I was able to move it and reposition it, which works fine, although I'm not sure how to modify the code to find hwnd of other running programs (some kind of search by window title would probably be ideal). Also it seems like the hwnd of the open window changed when I closed it and re-opened it. I'm not very familiar with what is going on here, this code is pretty advanced for me but I guess it wouldnt be too hard to just have it look for the current hwnd and use that if it changes every time..?
 
Upvote 0
<< Also it seems like the hwnd of the open window changed when I closed it and re-opened it. >>
Yes, the handle is not attached to the application name or so, you can see it as a pointer into the memory where the details of this particular instance of a window can be found. So if you close a window, then the handle becomes invalid. And on opening the program again, it is unlikely that Windows would put the new handle in exactly the same place in memory
 
Upvote 0
Upvote 0

Forum statistics

Threads
1,214,584
Messages
6,120,387
Members
448,956
Latest member
JPav

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top