Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros temas > Trucos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Los mejores trucos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-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
Obtener Handle a partir del PID

Existe ya una función (FindWindow) para encontrar una ventana conociendo su título, pero seria interesante poder limitar la búsqueda a las ventanas de un proceso determinado. Esto es lo que hace la función siguiente, encuentra el handle de una ventana, pasándole como parámetro el PID del proceso al que pertenece y opcionalmente el título de la ventana.

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

function EnumWindowsProc(Handle: Thandle; lParam: LPARAM): BOOL; stdcall;
var
  ProcessId: Cardinal;
  Buffer: PChar;
  Size: Integer;
begin
  Result:= TRUE;
  ProcessId:= 0;
  GetWindowThreadProcessId(Handle, ProcessId);
  if ProcessId = PWindowRec(lParam).ProcessId then
  begin
    if PWindowRec(lParam).WindowName <> nil then
    begin
      Size:= GetWindowTextLength(Handle) + 1;
      GetMem(Buffer,Size);
      try
        GetWindowText(Handle,Buffer,Size);
        if StrIcomp(PWindowRec(lParam).WindowName, Buffer) = 0 then
        begin
          PWindowRec(lParam).Handle:= Handle;
          Result:= FALSE;
        end;
      finally
        Freemem(Buffer);
      end;
    end else
    begin
      PWindowRec(lParam).Handle:= Handle;
      Result:= FALSE;
    end;
  end;
end;

function GetWindowFromProcessId(ProcessId: Cardinal; WindowName: PChar): THandle;
var
  WindowRec: TWindowRec;
begin
  FillChar(WindowRec,Sizeof(WindowRec),0);
  WindowRec.ProcessId:= ProcessId;
  WindowRec.WindowName:= WindowName;
  EnumWindows(@EnumWindowsProc, LPARAM(@WindowRec));
  Result:= WindowRec.Handle;
end;

La función anterior (GetWindowFromProcessId) nos devolverá el handle de la ventana que buscamos, o cero si no la encuentra. El parámetro WindowName es opcional, si es igual a nil, se devolverá el primer handle que se encuentre asociado a ese proceso.

Ahora solo necesitamos el PID del proceso, la siguiente función ejecuta un programa y usando su PID busca el handle de la ventana. El parámetro WindowName sigue siendo opcional, y el parámetro TimeOut indica el tiempo (en milisegundos) que hay que esperar a que el programa cree la ventana. Si la ventana se crea antes, la función volverá inmediatamente.

Código Delphi [-]
function Ejecutar(Cmd: string; WindowName: PChar; 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, WindowName);
      if Result = 0 then Sleep(200);
    end;
end;

Un ejemplo de como usar todo lo anterior seria lo siguiente. Ejecutamos el notepad, obtenemos el handle de la ventana, la ponemos al frente, y le mandamos la tecla 'a'.

Código Delphi [-]
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;


var
  H: THandle;
begin
  // Obtenemos el Handle de la ventana
  H:= Ejecutar('Notepad',nil,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
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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


La franja horaria es GMT +2. Ahora son las 23:54:34.


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