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 15-02-2010
Avatar de jorosmtz
jorosmtz jorosmtz is offline
Miembro
 
Registrado: dic 2009
Posts: 108
Poder: 15
jorosmtz Va por buen camino
Restaurar ventana previamente minimizada

Buen día, ahi les va un caso para la araña (al menos para la araña en mi caso), ya tengo rato buscando, pero no encuentro la solución:

Tengo una aplicación la cual no permite doble instancia, entonces cuando esto pasa mando un mensaje de que la aplicación ya está abierta, hasta aquí todo bien.

Pero el problema es que soy de los que les gusta facilitarle la vida a los usuarios, y se me ocurrió que después del mensajito de aplicación duplicada, podría traer el frente la ventana, y he aquí el problema.... cuando la ventana está atrás de otra con el simple Application.BringToFront es suficiente.... pero: ¿Que hacer cuando la ventana está minimizada?

Ya probé con ShowWindow(frmPpal.Handle,SW_RESTORE) y Application.Restore en varias combinaciones. Mi código es como sigue:

Código Delphi [-]
  ShowMessage('Ya tiene abierto el sistema XXXXXXX');
  if frmPpal.WindowState = wsMinimized then
     ShowWindow(Application.Handle,SW_RESTORE)
  else
     Application.BringToFront;

Traer al frente la aplicación estando esta atrás de otra no hay problema, BringTofront lo hace bien, pero el problema es cuando trato de restaurar la ventana cuando está minimizada.

NOTA: Cuando llamo a WindowsState para saber si mi aplicación está minimizada no me detecta su estado, por eso siempre se va al Application.BringToFront, pero dejando solo el ShowWindow (sin el "if"), me marca error de "Access Violation" cuando llamo a ShowWindow.

¿Alguien sabrá que pasa con esto?

Gracias
Responder Con Cita
  #2  
Antiguo 15-02-2010
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
Prueba así:

Código Delphi [-]
if IsIconic(Application.Handle) then
  ShowWindow(Application.Handle, SW_RESTORE)

// Saludos
Responder Con Cita
  #3  
Antiguo 15-02-2010
Avatar de jorosmtz
jorosmtz jorosmtz is offline
Miembro
 
Registrado: dic 2009
Posts: 108
Poder: 15
jorosmtz Va por buen camino
Negativo, si la ventana está minimizada no se restaura.

Como notas adicionales: una, estoy utilizando Delphi 2007, y dos; para saber si estoy abriendo dos veces el mismos programa (doble instancia) utilizo un componente llamado "adpInstanceControl", ¿no será este el problema?

Adjunto el cómponente para ver si le pueden dar una revisada....

Gracias...

Última edición por jorosmtz fecha: 11-04-2010 a las 03:08:51.
Responder Con Cita
  #4  
Antiguo 15-02-2010
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
Al parecer, a partir de esa versión, Delphi cambió la forma en que maneja la ventana principal y la ventana de la aplicación. No termino todavía de entender cuáles son las diferencias pero parecen estar controladas por la propiedad MainFormOnTaskBar que por defecto está en false aunque todas las aplicaciones creadas con Delphi 2007 o superior ponen dicha propiedad en true en el DPR.

Hace mucho tiempo que lidié con este problema en Windows XP y el resultado fue éste. Aquí, utilizaba IsIconic sobre el handle de la aplicación para saber si estaba minimizada. Con la nueva propiedad en true, la ventana de la aplicación no se minimiza, sólo la del formulario principal. Aunque me extraña lo que comentas acerca de que no detecta el estado de la ventana ya que (al menos en Delphi 2010), cuando se minimiza la aplicación se ejecuta lo siguiente:

Código Delphi [-]
if FMainFormOnTaskBar then
begin
  if FMainForm <> nil then
    FMainForm.WindowState := wsMinimized
  else
    FInitialMainFormState := wsMinimized;
end

Bueno, en todo caso, he estado haciendo pruebas, para ver de qué manera podía yo corregir mi unidad uiapp.pas.

Finalmente, creo que lo he logrado, cambiando el procedimiento AppWndProc por este otro:

Código Delphi [-]
function AppWndProc(Handle: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LongInt; stdcall;
var
  FgThreadId  : DWORD; { Hilo de la app. que tenga el foco }
  AppThreadId : DWORD; { Hilo de nuestra aplicación        }

begin
  if Msg = mActivar then
  begin
    { Restaurar la aplicación }
    Application.Restore;

    { Obtener los hilos }
    FgThreadId  := GetWindowThreadProcessId(GetForegroundWindow, nil);
    AppThreadId := GetWindowThreadProcessId(Handle, nil);

    { 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);

    Result := 0;
    end
    else
        { Dejar que el procedimiento original se encargue de los otros mensajes }
        Result := CallWindowProc(PrevWndProc, Handle, Msg, wParam, lParam);
end;

que es más sencillo pues no hace distinción entre el estado iconizado y el normal, y parece que funciona también con Delphi7 por lo que supongo que también funcionará en XP (ahora mismo estoy probando con Vista).

Cabe notar que yo nunca pude hacer funcionar bien esto usando sólo BringToFront, si la instancia original no estaba minimizada. Lo unico que obtenía era el botón de la barra de tareas parpadeando. Pero posiblemente algo se me escapa. El caso es que por eso está el AttachThreadInput en mi código; para poder pasar al frente la aplicación y no sólo restaurarla.

También conviene observar que él método que uso es bastante distinto del que usa el componente que mencionas. En lugar de archivos mapeados en memoria, yo uso un mutex. Y en lugar de crear un componente, mi técnica consiste simplemente en incluir la unidad uiapp al comienzo del archivo dpr del proyecto.

En fin, por si quieres probar, adjunto aquí la unidad modificada. Recuerda que no es un componente sino simplemente un archivo a incluir en tu proyecto.

// Saludos
Archivos Adjuntos
Tipo de Archivo: zip UiApp.zip (1,1 KB, 41 visitas)
Responder Con Cita
  #5  
Antiguo 15-02-2010
Avatar de jorosmtz
jorosmtz jorosmtz is offline
Miembro
 
Registrado: dic 2009
Posts: 108
Poder: 15
jorosmtz Va por buen camino
Ahora mismo voy a hacer pruebas con la unidad que me mandaste para ver si se puede corregir el error. Te comento.

La verdad yo no he tenido problemas con el BringToFront, hasta ahora me ha funcionado muy bien.
Responder Con Cita
  #6  
Antiguo 19-02-2010
cocute cocute is offline
Miembro
 
Registrado: nov 2008
Posts: 403
Poder: 16
cocute Va por buen camino
a mi en Delphi 2010 para que me funcione bien he tenido que cambiar en la unidad Uiapp de Roman:
Application.restore;
por
Application.MainForm.show;

No se por que al usar Application.restore si la aplicación la tenía minimizada me la restauraba pero muchos de los componentes de mi programa que están dentro de paneles y pagecontrols...... no funcionaban, se quedan como inactivos. (si minimizaba y restauraba desde el trayicon ya me iba bien)

El problemilla de usar Application.MainForm.show, aunque funciona bien es que cuando se restaura la ventana de mi aplicación hace como un parpadeo al repintar los componentes. ¿se os ocurre algo para evitarlo? no es que sea muy molesto pero por afinar.

gracias.

Última edición por cocute fecha: 20-02-2010 a las 16:21:54.
Responder Con Cita
  #7  
Antiguo 19-02-2010
Avatar de jorosmtz
jorosmtz jorosmtz is offline
Miembro
 
Registrado: dic 2009
Posts: 108
Poder: 15
jorosmtz Va por buen camino
Saben, no he tenido nada de tiempo de verificar la unidad que nos mandó Roman, denme una chancita para probarla, también soy del área de soporte (no solo programador) y a veces hay oportunidad de programar y a veces no, y esta ha sido una de esas rachas de no poder programar mucho...

Respecto al Application.MainForm.Show no me funcionó, pero como les digo, voy a probar con la unidad de Román, a lo mejor el problema es el componente que yo tengo para probar doble instancia la que no me deja restaurar la ventana.

Saludos y estamos en contacto.
Responder Con Cita
  #8  
Antiguo 20-02-2010
cocute cocute is offline
Miembro
 
Registrado: nov 2008
Posts: 403
Poder: 16
cocute Va por buen camino
lo de Application.MainForm.Show que he dicho, solo he conseguido que funcione modificando el Uiapp de Roman, he probado con varios componentes y códigos para evitar dobles instancias que habia visto por varias webs, y te aseguro que he probado un monton, pero es la única forma que más o menos hace lo que quiero de restaurar la primera instancia si estaba minimizada.
Aunque seguro que aun se puede pulir para que no haga el parpadeo que decía.
Responder Con Cita
  #9  
Antiguo 20-07-2010
Avatar de flystar
flystar flystar is offline
Miembro
 
Registrado: jul 2006
Posts: 184
Poder: 18
flystar Va por buen camino
Question

Di de alta la unidad de roman en mi programa...

Disculpen y ahora...como la mando llamar???



Tambien quiero colocar en primer plano mi aplicacion..
__________________

"Los unicos que no se equivocan son aquellos que no intentan hacer algo."
Iván Caballero Cano...
ivanhalen77@gmail.com
Responder Con Cita
  #10  
Antiguo 20-07-2010
Avatar de flystar
flystar flystar is offline
Miembro
 
Registrado: jul 2006
Posts: 184
Poder: 18
flystar Va por buen camino
Osea quiero decir..como la hecho a andar para que hago eso de poner en primer plano la aplicacion?
__________________

"Los unicos que no se equivocan son aquellos que no intentan hacer algo."
Iván Caballero Cano...
ivanhalen77@gmail.com
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
Ventana minimizada windows babu API de Windows 1 16-02-2009 09:54:08
Ventana minimizada rod203 API de Windows 1 17-11-2008 19:25:45
Canvas (ventana minimizada) ganegri Gráficos 5 17-07-2007 22:45:40
Resaltar una ventana minimizada johncook Varios 2 27-11-2004 14:10:00
Ventana Minimizada diegofhernando Varios 4 16-05-2003 15:32:25


La franja horaria es GMT +2. Ahora son las 23:35:09.


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