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
vBulletin v3.6.8, Derechos ©2000-2024, Jelsoft Enterprises Ltd.