PDA

Ver la Versión Completa : Como traigo al frente una aplicacion que no sea la mia


cso2000
18-10-2003, 00:47:17
Saludos:


mi problema es que ocupo hacer una aplicacion que me muestre las aplicaciones abiertas,

es decir tengo abierto excell y word y quiero que mi aplicacion ponga al frente 3 sec una aplicacion y 3 Sec la otra


con una funcion puedo obtener la lista de los exes que se estan ejecutando incluso obtengo los Thred de cada exe


utilizo el siguiente codigo y no me funciona

Por fa. alguien Ayudeme




FgThreadId := GetWindowThreadProcessId(GetForegroundWindow, nil);
ActIdApp;
AppThreadId := arreglo_Th[ id_app ];

// AppThreadId := GetWindowThreadProcessId(Handle, nil);

Self.Caption := Inttostr( AppThreadId ) + ' ' + Inttostr( FgThreadId );


{ Anexar el hilo de nuestra app. al de la que tenga el foco }
AttachThreadInput( AppThreadId , FgThreadId , true);

{ Ahora sí, activar la applicación }
SetForegroundWindow(Handle);

{ Separar el hilo de nuestra app de la otra }
AttachThreadInput( AppThreadId , FgThreadId , false);




la funcion ActIdApp; obtiene cada uno de los THred que tengo en un Arreglo.


Gracias a Yodos

roman
18-10-2003, 01:19:45
Este código, que por cierto tomaste de http://www.clubdelphi.com/users/roman/uiapp.php,
está pensado para traer al frente la aplicación desde donde se llama este código de manera que desconozco si sirve para el caso que intentas aplicar. Lo que observo es que, a pesar de que cambiaste AppThreadId para que apunte al hilo de la aplicación que deseas activar, no parece que hayas cambiado el Handle en la llamada a SetForegroundWindow, así que posiblemente también debas cambiarlo para que apunte a la ventana de la aplicación que intentas activar.

// Saludos

cso2000
18-10-2003, 01:32:37
Gracias Roman:

y de hecho si tome el codigo de ahi:

y respecto a tu respuesta te refieres


SetForegroundWindow(AppThreadId);

Si es asi ya lo probe. y no me funciono no se si puedas ayudarme con otra pista.


Gracias.

roman
18-10-2003, 01:38:09
Posteado originalmente por cso2000
SetForegroundWindow(AppThreadId);


Pero el parámetro de SetForegroundWindow debe ser el "Handle" de la ventana y no el del hilo. Ventanas e hilos no son lo mismo. Un hilo puede manejar varias ventanas y una aplicación puede manejar varios hilos.

¿Cómo estás obteniendo la lista de hilos? Quizá algo similar te permita obener la lista de ventanas.

// Saludos

cso2000
18-10-2003, 02:29:26
Muchisimas gracias Roman


Eso de cambiar el hanle me resulto muy bien

estoy afinando la aplicacion por que traigo varios errores
pero creo que con esto me funciona bien



gracias de nuevo

cso2000
22-10-2003, 17:07:41
Hola Amigos del Foro:


Recurri a este hilo ( no se si es correcto ) porque tengo un pequeño problema Respecto a la solucion de mi problema:


Siguiendo la recomendacion de roman cambie el valor que utilizo para traer la ventana al frente oteniendo por separado el hanle de esta y funciona correctamente el problema es que para algunos programas no funciona Ejemp. el Internet Explorer o el explorador de Windows, o Excel, word...

Haber si me pueden echar la mano el codigo que utilizo para obtener el hilo y el hanle es el sig.



procedure TForm1.Button1Click(Sender: TObject);

function SacaExe(MangoW:HWND):string;
{Obtiene el EXE de una tarea}
{get EXE of a task}
var
Datos :TProcessEntry32;
hID : DWord;
Snap : Integer;
begin
GetWindowThreadProcessId(MangoW,@hID);
Snap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
try
Datos.dwSize:=SizeOf(Datos);
if(Process32First(Snap,Datos))then
begin
repeat
if Datos.th32ProcessID=hID then
begin
Result:=StrPas(Datos.szExeFile);
Break;
end;
until not(Process32Next(Snap,Datos));
end;
finally
Windows.CloseHandle(Snap);
end;
end;


function ObtieneVentanas(Mango: HWND;
Nada: Pointer): Boolean; stdcall;
var
sTemp:string;
begin
Result := True;
{Mango es el handle de la tarea encontrada}
{Añadimos el .EXE si no está ya añadido...}
sTemp:=SacaExe(Mango);
with Form1.ListBox1.Items do
if IndexOf(sTemp) = - 1 then begin
Add(sTemp);
Form1.lstTh.add( inttostr( GetWindowThreadProcessId(Mango,NIL) ) );
Arreglo_HWND[ Form1.lstTh.count - 1 ] := Mango;
end;
end;

begin
EnumWindows( @ObtieneVentanas, 0 );
end;







Espero que alguien me pueda dar una pista, de antemano Garcias a Todos.

roman
22-10-2003, 17:28:36
Comentario al margen:

En Windows 2000 siempre que tengo una ventana de IE abierta, las siguientes que desee abrir jamás se activan correctamente. A veces aparecen pero no tienen el foco y aveces sólo queda parpadeando el botón en la barra de tareas; situaciones por demás exasperantes.

Si el mismo IE no es capaz de activarse a sí mismo correctamente, me pregunto si valdrá la pena intentar hacerlo uno mismo?

// Saludos

cso2000
22-10-2003, 17:49:32
Si de hecho eso estaba pensando, Solo que como me ocurre lo mismo con aplicaciones como excel y word supuse que algo estaria haciendo mal


Como sea Gracias

roman
22-10-2003, 18:15:59
Vamos a ver una cosa.

¿Es realmente necesario el uso de AttachThreadInput?

El código que utilizas lo usé yo en otro contexto: el de evitar que una aplicación se ejecute más de una vez simultáneamente (http://www.clubdelphi.com/users/uiapp.php).

En ese caso fue necesario por la siguiente razón (al menos es lo que creo entender):

El código de activación (el que usa AttachThreadInput) se ejecuta en la primera instancia de la aplicación en un momento en que ésta no tiene el foco (el foco lo tiene la segunda instancia). Dicho de otra forma, es un código que se ejecuta desde un hilo distinto al que tiene el foco.

En tu caso, según entiendo, es distinto-- el código de activación se ejecuta desde tu aplicación que es la que tiene el foco. En ese caso siento que no deberías tener problemas con métodos más sencillos de activación.

El siguiente código lo acabo de probar y activa correctamente tanto IE como en MSWord:


var
AppHandle: HWnd;

begin
AppHandle := FindWindow(nil, AppName);
if AppHandle <> 0 then
if IsIconic(AppHandle)
then ShowWindow(AppHandle, SW_RESTORE)
else SetForegroundWindow(AppHandle);


Claro que tú estás obteniendo el "Handle" de las aplicaciones de otra forma pero eso no afecta.

Pruébalo así a ver si te sirve.

// Saludos

pd: Esto sólo lo he probado en Windows 2000

cso2000
22-10-2003, 19:48:56
Saludos de Nuevo


no se si algo estoy haciendo mal


uso este codigo y no me funciona


[code]

var
AppHandle: HWnd;

begin
AppHandle := FindWindow(nil, 'IEXPLORE.EXE' );
if AppHandle <> 0 then
if IsIconic(AppHandle)
then ShowWindow(AppHandle, SW_RESTORE)
else SetForegroundWindow(AppHandle);

]/Code]


Estoy utilizando:

delphi3 y windows 2000
delphi3 y windows 98

y en ninguno me funciona

solo me falta probar con win 2000 y delphi 6


ayuda por favor

roman
22-10-2003, 20:03:31
Posteado originalmente por cso2000
AppHandle := FindWindow(nil, 'IEXPLORE.EXE' );

[...]

solo me falta probar con win 2000 y delphi 6


Ni te gastes, tampoco te va a funcionar.

El parámetro que le pasas a FindWindow es el título de la ventana y no el del ejecutable, por ejemplo:

'Foros Club Delphi - Responder al tema - Microsoft Internet Explorer'.

Yo te puse FindWindow sólo por dar un ejemplo rápido para encontrar el "Handle" de una ventana (del IE en este caso). Cuando uses EnumWindows, el Handle que te pasa en la función callback es el que usarás en las llamdas a IsIconic, ShowWindow y SetForegroundWindow.

// Saludos

cso2000
22-10-2003, 21:02:05
Tal vez tengo algun problema al obtener el Handle de la aplicacion porque no me finciona


ojala se no ocurruera otra cosa


Gracias