Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-07-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.964
Poder: 29
delphi.com.ar Va camino a la fama
Cita:
Empezado por roman
Hola, estuve revisando este tema. El problema con el método anterior es que el usuario podría tener abiertas otras instancias de la aplicación externa y no hay garantía de que FindWindow te regrese la ventana que tú abriste en lugar de otra.

Un método un poco más complicado consiste en abrir la aplicación directamente con CreateProcess para obtener el identificador del hilo de la aplicación
Haberlo visto antes!... tengo código escrito al respecto...
Un detalle, en mi código cuando busco la ventana perteneciente al hilo de ejecución, manejo un timeout interno porque sucede que si el equipo no es muy veloz, es posible que el proceso esté creado pero no la ventana.

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #2  
Antiguo 06-07-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por delphi.com.ar
Un detalle, en mi código cuando busco la ventana perteneciente al hilo de ejecución, manejo un timeout interno porque sucede que si el equipo no es muy veloz, es posible que el proceso esté creado pero no la ventana.
Tienes razón. Aún en máquinas rápidas si la aplicación que se abre tarda mucho, como Word. No me había percatado porque hacía las pruebas por separado: en un botón mandaba abrir la aplicación y en otro botón la ponía como siempre visible.

Intente modificar GetMainWindow así

Código Delphi [-]
function GetMainWindow(ThreadId: Cardinal): HWnd;
begin
  Result := 0;

  while (Result = 0) do
    EnumThreadWindows(ThreadId, @DoEnum, Integer(Pointer(@Result)));
end;

pero no resulta. Aun cuando se obtiene el identificador de la ventana principal si la llamada a MakeAppTopMost es inmediata no siempre funciona.

Finalmente cambié ExecuteProcess:

Código Delphi [-]
function ExecuteApp(AppPath: String; TimeOut: Integer = 2000): Cardinal;
var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;

begin
  FillChar(StartInfo, SizeOf(StartInfo), 0);
  StartInfo.cb := SizeOf(StartInfo);

  if not CreateProcess(
    PChar(AppPath), nil, nil, nil, false, 0, nil, nil, StartInfo, ProcInfo
  )
  then
    RaiseLastOSError;

  Sleep(TimeOut);

  Result := ProcInfo.dwThreadId;
end;

Así, por defecto esperará 2 segundos antes de proseguir pero se le puede cambiar el valor en la llamada.

// Saludos
Responder Con Cita
  #3  
Antiguo 06-07-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.964
Poder: 29
delphi.com.ar Va camino a la fama
Yo había creado unas funciones mas genéricas, tu "GetMainWindow" es algo así:
Código Delphi [-]
function FindThreadWindow(dwThreadId: DWORD; hParent: HWND; lpClassName, lpWindowName: PAnsiChar; wTimeOut: Word = 30000): HWND;
var
  AFindWindow: TFindWindow;
  ATickCount: DWORD;
begin
  AFindWindow.lpClassName := lpClassName;
  AFindWindow.lpWindowName := lpWindowName;
  AFindWindow.hResult := 0;
  ATickCount := GetTickCount + wTimeOut;
  repeat
    if hParent = 0 Then
      EnumThreadWindows(dwThreadId, @EnumThreadWndProc, Integer(@AFindWindow))
    else
      EnumChildWindows(hParent, @EnumThreadWndProc, Integer(@AFindWindow));
  until (AFindWindow.hResult <> 0) or (ATickCount < GetTickCount);

  Result := AFindWindow.hResult;
end;
Me parece que es un poco mas real el concepto de TimeOut, en tu código es un tiempo de espera. (Solo una cuestión semántica )
Vale aclarar que usar GetTickCount no es del todo seguro para estos casos, ya que si el equipo estuvo encendido durante 49.7 días, este vuelve a cero. Un poco extraño, pero en uno de los proyectos en que estoy trabajando ha sucedido .
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #4  
Antiguo 06-07-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Bueno, pero, básicamente es mi while Result = 0 do (creo ). El caso es que probé esto y aún habiendo "encontrado" la ventana, la llamada a MakeAppTopMost no tenía efecto. Yo supongo que, como es normal en las aplicaciones Windows, luego de creada la ventana viene una llamada a SetWindowPos y si no ha pasado suficiente tiempo puede ser que ésta se haga después de la que nosotros hacemos.

// Saludos
Responder Con Cita
  #5  
Antiguo 06-07-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.964
Poder: 29
delphi.com.ar Va camino a la fama
Cita:
Empezado por roman
Bueno, pero, básicamente es mi while Result = 0 do (creo ).
Ahhh... y si el proceso ejecutado no es el correcto o una versión diferente??..

Para comparar, yo subí el ejemplo que tenía armado a mi página, no recuerdo para quien lo había hecho, me llama la atención que no lo haya puesto en el foro anteriormente.
El ejemplo hace otra cosa, pero creo que es muy aplicable a este caso.

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #6  
Antiguo 06-07-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por delphi.com.ar
Ahhh... y si el proceso ejecutado no es el correcto o una versión diferente??
¿Cómo no va a ser el proceso correcto si yo lo mando llamar?

De cualquier forma, mi apunte del while Result = 0 do no iba encaminado a decir que estábamos haciendo lo mismo, sino, esencialmente lo mismo y que hasta donde veo persiste el problema de que las llamadas a otras funciones como MakeAppTopMost no sutan efecto.

¡Todo esto por el block de notas!
Responder Con Cita
  #7  
Antiguo 06-07-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.964
Poder: 29
delphi.com.ar Va camino a la fama
Cita:
Empezado por roman
¿Cómo no va a ser el proceso correcto si yo lo mando llamar?
Nooo... supongamos que es una aplicación que distribuyes por la red, la pueden bajar usuarios con plataformas diferentes, con versiones y con "customizaciones" diferentes. Digamos que hasta pueden haber sobreescrito el Block de Notas, algo atípico pero estoy seguro de mas de un caso de esto.

¡¡Es para molestar un poco!!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #8  
Antiguo 06-07-2004
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por delphi.com.ar
ya que si el equipo estuvo encendido durante 49.7 días, este vuelve a cero. Un poco extraño, pero en uno de los proyectos en que estoy trabajando ha sucedido .
No tan extraño, de hecho está documentado y es que el valor de GetTickCount se guarda en una variable de 32 bits. En mi infinita ocisosidad ya hice las cuentas y, en efecto sólo caben 49.7 días.

Por cierto Federico, ¿podrías editar tu mensaje? Ya no cabe en el ancho de mi pantalla.

// Saludos
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 13:37:11.


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