Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Restaurar ventana previamente minimizada (https://www.clubdelphi.com/foros/showthread.php?t=66346)

jorosmtz 15-02-2010 16:09:31

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

roman 15-02-2010 17:39:27

Prueba así:

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

// Saludos

jorosmtz 15-02-2010 18:43:02

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...

roman 15-02-2010 22:20:40

1 Archivos Adjunto(s)
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

jorosmtz 15-02-2010 23:27:25

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.

cocute 19-02-2010 11:20:03

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.

jorosmtz 19-02-2010 22:18:55

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.

cocute 20-02-2010 16:20:17

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.

flystar 20-07-2010 19:03:45

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

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

:confused::confused::confused:

Tambien quiero colocar en primer plano mi aplicacion..

flystar 20-07-2010 19:04:27

Osea quiero decir..como la hecho a andar para que hago eso de poner en primer plano la aplicacion?


La franja horaria es GMT +2. Ahora son las 01:19:07.

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