Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 28-08-2006
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Red face Duda sobre FindWindow

Hola, de nuevo yo con otra duda, espero no hartarlos...

Estoy haciendo un programilla para automatizar algunas tareas en otros programas, lo que necesito es lanzar una aplicación varias veces y guardar el handle de la ventana principal de cada aplicación para mandarle mensajes, es decir pulsaciones de teclas (esto ya lo conseguí con un ejemplo de alguno de los hilos anteriores Gracias), así que lo que pienso hacer es llamar a la aplicación mediante SetForeground y despues enviarle pulsaciones de teclas, para obtener el handle de cada ventana lo que he probado hacer es lanzar la aplicación con ShellExecute o WinExec e inmediatamente llamar FindWindow, lei la ayuda de Windows, y WinExec no devuelve el handle de la ventana de la aplicación que llama, ShellExecute, devuelve el handle de la ventana o el handle de una DDE, pero la aplicación que llamo siempre devuelve 42, por lo que opté en usar FindWindow.

Mi duda es la siguiente: Cuando llamo FindWindow, usando solamente el caption de la ventana que busco ¿siempre me devolverá el handle de la ventana creada por último?

Segun lo que he probado, la respuesta es afirmativa, pero llevo poco tiempo probando esto, y me gustaría que alguien que ya haya probado esto me lo confirmara.

Por último algunas preguntas, quizas lo consideren de novatos: con el handle de la ventana, ¿Puedo situar esta ventana en otro monitor (por supuesto solo para los que tienen más de un monitor), y cambiarle el tamaño? creo que con los mensajes de Windows; y ¿Por qué algunos recomiendan usar dos veces SetForeground? ¿con una sola vez no es suficiente? ¿o no es muy seguro?

De antemano agradezco a toda la pandilla de Club Delphi por dedicarnos un tiempo a todos los preguntones...

Gracias
__________________
Herr Heins Faust
Responder Con Cita
  #2  
Antiguo 28-08-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Espero no estar reinventando la rueda, pero aquí te dejo un par de funciones que pueden resultarte útiles:

Código Delphi [-]
type
  TWindowRec = record
    ProcessId: Cardinal;
    Handle: THandle;
  end;
  PWindowRec = ^TWindowRec;

function EnumWindowsProc(Handle: Thandle; lParam: LPARAM): BOOL; stdcall;
var
  ProcessId: Cardinal;
begin
  Result:= TRUE;
  ProcessId:= 0;
  GetWindowThreadProcessId(Handle, ProcessId);
  if ProcessId = PWindowRec(lParam).ProcessId then
  begin
    PWindowRec(lParam).Handle:= Handle;
    Result:= FALSE;
  end;
end;

// Esta nos da el handle de la primera ventana que encuentra asociada al
// proceso indicado.
function GetWindowFromProcessId(ProcessId: Cardinal): THandle;
var
  WindowRec: TWindowRec;
begin
  FillChar(WindowRec,Sizeof(WindowRec),0);
  WindowRec.ProcessId:= ProcessId;
  EnumWindows(@EnumWindowsProc, LPARAM(@WindowRec));
  Result:= WindowRec.Handle;
end;

// Esta otra ejecuta un programa y devuelve el handle de la primera ventana
// que encuentra asociada a el, espera un tiempo razonable para que el 
// programa pueda crear la ventana, pasado ese tiempo devuelve 0
function Ejecutar(Cmd: string; Timeout: Cardinal): THandle;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  Ticks: Cardinal;
begin
  Result:= 0;
  FillChar(StartupInfo,Sizeof(StartupInfo),0);
  StartupInfo.wShowWindow:= SW_SHOW;
  Ticks:= GetTickCount;
  if CreateProcess(nil,PChar(Cmd),nil,nil, FALSE, CREATE_NEW_CONSOLE or
    NORMAL_PRIORITY_CLASS,nil,nil,StartupInfo, ProcessInfo) then
    while (Result = 0) and (GetTickCount - Ticks < TimeOut) do
    begin
      Result:= GetWindowFromProcessId(ProcessInfo.dwProcessId);
      if Result = 0 then Sleep(200);
    end;
end;

// Esta función pone delante una ventana pasándole el handle, esta sacada
// de otro hilo de este foro
procedure PonerDelante(Handle: THandle);
var
  FgThreadId  : DWORD;
  AppThreadId : DWORD;
begin
  FgThreadId  := GetWindowThreadProcessId(GetForegroundWindow, nil);
  AppThreadId := GetWindowThreadProcessId(Handle, nil);
  AttachThreadInput(AppThreadId, FgThreadId, true);
  SetForegroundWindow(Handle);
  AttachThreadInput(AppThreadId, FgThreadId, false);
end;

Un ejemplo de como usar las funciones anteriores seria el siguiente:

Código Delphi [-]
var
  H: THandle;
begin
  // Obtenemos el Handle de la ventana
  H:= Ejecutar('Notepad',5000);
  if H <> 0 then
  begin
    // La ponemos por delante
    PonerDelante(H);
    // Le mandamos la letra 'a'
    keybd_event($41, 0, 0, 0);
    keybd_event($41, 0, KEYEVENTF_KEYUP, 0);
  end;
end;
Responder Con Cita
  #3  
Antiguo 28-08-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Me quedaba lo de mandar a otro monitor, en este otro hilo ya hablamos sobre el tema, pero utilizando el Handle la cosa quedaría así:

Código Delphi [-]
procedure MandarA(Handle: Thandle; Monitor: Integer);
begin
  if Screen.MonitorCount > Monitor then
    SetWindowPos(Handle,HWND_TOP,Screen.Monitors[Monitor].Left,
      Screen.Monitors[Monitor].Top,0,0,SWP_NOSIZE);
end;

// Por ejemplo para mandarlo al segundo monitor
MandarA(Handle,1);
Responder Con Cita
  #4  
Antiguo 30-08-2006
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Thumbs up Gracias

Gracias camarada Seoane, voy a probar tu solución, aunque estoy seguro de que funcionará, luego cuento como me fue, es que ahorita tengo mucha chamba con otros pendientes

Bye
__________________
Herr Heins Faust
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Problema con el FindWindow lookmydoom API de Windows 3 22-07-2006 09:57:56
Una duda sobre ADO PTW Conexión con bases de datos 1 13-04-2004 23:33:14
Duda sobre BDE vs IBX ESA Firebird e Interbase 3 04-03-2004 17:20:07
Problemas con FindWindow Fita API de Windows 4 03-03-2004 19:14:00
Duda sobre ADO Omar Alejandro Conexión con bases de datos 7 31-05-2003 19:52:58


La franja horaria es GMT +2. Ahora son las 01:00:42.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi