
Hace poco surgió en la lista la duda de cómo posicionar y modificar el tamaño de la ventana de un programa MS-DOS llamado por el nuestro.
Veremos dos maneras hacerlo, independientemente de si es MS-DOS o Windows.
En primer lugar podemos usar la clase que encontraremos en el artículo "Clase para arrancar aplicaciones síncrona y asíncronamente (controla tamaño y posición de la ventana, etc.)" de la sección Trucos de mi web. Esta clase
sirve para lanzar otro programa de forma síncrona (nuestro programa se detiene hasta que el otro finalice), asíncrona (nuestro programa lanza el otro y sigue su ejecución) y asíncrona con aviso (nuestro programa sigue y recibe un evento cuando el otro finaliza). Unas de las propiedades de esta clase permiten especificar el tamaño y posición de la ventana del nuevo programa.
Si queremos seguir lanzando el programa con shell podrímos utilizar este ejemplo que acabo de hacer (no lo probé mucho pero creo que funciona correctamente) :
En un formulario :
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal
lpClassName As Long, ByVal lpWindowName As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd
As Long, lpdwProcessId As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal
wCmd As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function Putfocus Lib "user32" Alias "SetFocus" (ByVal hwnd
As Long) As Long
Const GW_HWNDNEXT = 2
Private Declare Function MoveWindow Lib "user32" (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
Function InstanceToWnd(ByVal target_pid As Long) As Long
Dim test_hwnd As Long, test_pid As Long, test_thread_id As Long
'Find the first window
test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
Do While test_hwnd <> 0
'Check if the window isn't a child
If GetParent(test_hwnd) = 0 Then
'Get the window's thread
test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
If test_pid = target_pid Then
InstanceToWnd = test_hwnd
Exit Do
End If
End If
'retrieve the next window
test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
Loop
End Function
Y para ejecutar :
Dim PId As Long, hwnd As Long, res As Long
'cambio el directorio por defecto (la clase también tiene esta propiedad), si hace falta
ChDir "c:\mi directorio"
PId = Shell("c:\mi directorio\mi programa.exe", vbNormalFocus)
DoEvents
If PId <> 0 Then 'pudo arrancar la aplicación
hwnd = InstanceToWnd(PId)
'si encontró la ventana
If hwnd > 0 Then
'la coloco en la esquina superior izquierda y que ocupe la mitad
'de la pantalla, tanto de ancho como de alto
res = MoveWindow(hwnd, 0&, 0&, (Screen.Width / Screen.TwipsPerPixelX) / 2, (Screen.Height / Screen.TwipsPerPixelY) / 2, 1&)
If res = 0 Then
MsgBox "No se pudo mover la ventana"
End If
Else
MsgBox "No se pudo encontrar la ventana"
End If
Else
MsgBox "No se pudo arrancar la aplicación"
End If
Debemos tener en cuenta que las ventanas de MS-DOS no pueden cambiar libremente de tamaño, sino que lo hacen "a saltos", ajustándose a las proporciones de 25 líneas y 80 columnas.

