trabajo trabajar toda tamaƱo solo reducir que pantalla ocupe ocultar navegar mostrar maximizar formularios formulario con completa como abrir delphi delphi-7 vcl delphi-5

delphi - trabajar - maximizar formulario access



Los formularios wsMaximized no aparecen maximizados (5)

¡Guauu! no vi en la publicación:

ShowWindowAsync (Handle, SW_MAXIMIZE);

Gracias por eso, con eso mi problema se resuelve mucho mejor que con un temporizador, pero no perfecto, todavía causa un pequeño parpadeo (la ventana se muestra en el render incompleto, luego va al estado maximizado), es mucho mejor que el temporizador , menos tiempo mostrado en estado no maximizado.

Y es compatible con un SetBounds anterior () en el método OnShow.

Deseo: establecer el tamaño inicial (ancho, alto) y tal vez también la posición inicial (izquierda, arriba) de un formulario antes de mostrarlo, pero ese formulario debe mostrarse maximizado; tal posición y tamaño son para cuando el usuario no maximiza la ventana.

Ese ShowWindowAsync funciona perfecto para tal objetivo, y no es necesario agregar un temporizador feo (con interval = 1 y .Enabled = False en su código como primera oración).

¡Cómo podría extrañarlo cuando leí la publicación!

Entonces, ahora voy a usar (solo como ejemplo, el tamaño inicial relativo al monitor):

procedure TtheForm.FormShow(Sender: TObject); var theInitialDefaultWidth,theInitialDefaultHeight:Integer; begin theInitialDefaultWidth:=Round(Screen.Width*3/5); theInitialDefaultHeight:=Round(Screen.Height*3/5); WindowState:=wsNormal; // So it can still have at design time wsMaximized, this is for the SetBounds to work on a non maximized state SetBounds((Screen.Width-theInitialDefaultWidth)div 2,(Screen.Height-theInitialDefaultHeight)div 2,theInitialDefaultWidth,theInitialDefaultHeight); // Set default position and default size as i wish ShowWindowAsync(Handle,SW_MAXIMIZE); // Make the window to be shown maximized when it will be visible // ... // Rest of actions for the FormShow method end;

Funciona perfecto! No necesito tocar las propiedades del tiempo de diseño, puedo dejarlas tal como están (WindowState = wsMaximized, Position = poScreenCenter, etc.). Solución de código 100% para el problema.

¡Muchas gracias!

PD: ¿Funcionará en Linux? Quiero decir, cuando el código se compila para Linux (en Lazarus), debo probarlo y ver si funciona, será un gran avance en lo que estaba usando hasta ahora.

Establecer un formulario para WindowState = wsMaximized a veces hará que el formulario se maximice pero no:

Error de larga duración: esta es una pregunta que hice por primera vez en los grupos de noticias de Borland en 2003:

y luego nuevamente en 2006:

y luego nuevamente en 2008:

Alguien lo preguntó en los foros de Embarcadero en 2012:

Ahora es el momento de convertir el error de 18 años a Stackoverflow. Quizás alguien finalmente descubrió una solución alternativa.

Pasos para reproducirse :

Mis publicaciones contenían media docena de modos de falla, pero la más fácil es:

  • Coloque una Label y una Edit en un formulario:

  • Agregue un evento OnEnter para el TEdit :

    procedure TForm1.Edit1Enter(Sender: TObject); begin Label1.Font.Style := Label1.Font.Style + [fsBold]; end;

  • y establecer la forma:

    • WindowState a wsMaximized
    • AutoScroll a falso

Y bazinga, falla.

Uno de los otros pasos de la publicación de 2008:

  1. Crea una nueva aplicación y un formulario.
  2. Establezca el formulario maximizado (WindowState = wsMaximized) en el momento del diseño.
  3. Coloque un control ListView en el formulario
  4. Durante OnShow, agregue 20 elementos vacíos a la vista de lista:

    procedure TForm1.FormShow(Sender: TObject); var i: Integer; begin for i := 1 to 20 do ListView1.Items.Add; end;

  5. Establezca la propiedad AutoScroll del formulario en false (AutoScroll = False) en el momento del diseño

Por supuesto, lo que no busco es "arreglado en la versión n de RadStudio. Solo use eso" . Estoy buscando una solución real (si hay una); que podría incluir la cita de cambios relevantes a la fuente de VCL cuando CodeGear finalmente lo solucionó. (Si es incluso fijo).

Nota: Cambiar la Position de poDesigned a cualquier otra cosa no lo soluciona.

Solución

Una solución horrible, fea, horrible, repugnante, que había estado usando era iniciar un temporizador durante OnShow , y luego, cuando el temporizador se dispara, maximiza la forma:

procedure TForm1.tmrVclMaximizeHackTimer(Sender: TObject); begin Self.WindowState := wsMaximized; end;

Más tarde, mejoré este truco para publicar un mensaje durante OnShow ; que es esencialmente lo mismo que un mensaje de temporizador, sin tener que usar un temporizador:

const WM_MaximizeWindow = WM_APP + $03; procedure TForm1.FormShow(Sender: TObject); begin if (Self.WindowState = wsMaximized) then begin Self.WindowState := wsNormal; PostMessage(Self.Handle, WM_MaximizeWindow , 0, 0); end; end; private procedure WMMaximizeWindow(var Message: TMessage); message WM_MaximizeWindow; procedure TForm1.WMMaximizeWindow(var Message: TMessage); begin Self.WindowState := wsMaximized; end;

A veces invento el evento OnAfterShow que Delphi nunca hizo:

const WM_AfterShow = WM_APP + $02; procedure TForm1.FormShow(Sender: TObject); begin PostMessage(Self.Handle, WM_AfterShow, 0, 0); if (Self.WindowState = wsMaximized) then begin Self.WindowState := wsNormal; FMaximizeNeeded := True; end; end; private procedure WMAfterShow(var Message: TMessage); message WM_AfterShow; procedure TForm1.WMAfterShow(var Message: TMessage); begin if FMaximizeNeeded then begin FMaximizeNeeded := False; Self.WindowState := wsMaximized; end; end;

Pero ningún hack es mejor que hacks.


Espero que la solución que uso ayude a otros (la ventana conocida se muestra por primera vez con el tamaño del tiempo de diseño):

  • Agregue un temporizador con intervalo tan solo como 1 (no ponga 0).
  • Código para ello: theTimer.Enabled:=False;WindowState:=wsMaximized;

Nunca me falla.

Tan pronto como se muestre la forma y todas las tareas pendientes para dicho espectáculo hayan finalizado, se activarán los disparadores del temporizador y se maximizará la ventana.

Hace algún tiempo, estaba usando el truco de enviar un clic del mouse donde estaba el botón Maximizar, pero descubrí que comprobar la versión del sistema operativo Windows, los complementos (en Linux), etc. hace que la cosa sea tan difícil. Ese trabajó exactamente como si el usuario pidiera maximizar la ventana.

El temporizador que uso ahora hace exactamente lo mismo, pero evita la verificación del sistema operativo, etc.

Sin mencionar: Ponga WindowState en wsNormal en DesignTime (no lo configure en wsMinimized ni en wsMaximized).


No creo que esto sea un error en Delphi, sino un error (o simplemente un comportamiento extraño) en la función Windows CreateWindow. Si busca CreateWindow y WS_MAXIMIZE que no funciona, encontrará conversaciones y discusiones muy similares entre personas que llaman a CreateWindow o CreateWindowEx pasando WS_MAXIMIZE en el parámetro de estilo y no viendo una ventana maximizada cuando ejecutan la aplicación.

Extracto de un viejo hilo de gamedev.net

el problema es que WS_MAXIMIZE aparentemente no se aplica cuando se usa WS_OVERLAPPEDWINDOW. si reemplaza WS_OVERLAPPEDWINDOW con WS_POPUP, obtendrá una ventana maximizada. por supuesto, esto puede no aplicarse a todas las versiones de Windows, o incluso a todas las versiones de la interfaz de usuario del shell de Windows.

WS_OVERLAPPEDWINDOW es el "tipo" de ventana predeterminado de MS y aparentemente codificó CreateWindow / Ex para ignorar ciertos estilos, pensando que ShowWindow se llamaría con SW_SHOWDEFAULT, lo que hace que la ventana se muestre de acuerdo con los parmetros de información de inicio de CreateProcess. esto finalmente le da al usuario el control de cómo se mostraría la ventana principal de una aplicación utilizando la configuración de acceso directo del shell.

La solución alternativa es simplemente llamar a ShowWindow. Debería funcionar en Delphi, también:

procedure TForm1.FormShow(Sender: TObject); begin ShowWindow(Handle, SW_MAXIMIZE); end;


Puedo reproducir con D7 / Win7.

No utilizo wsMaximized en absoluto (problemas aleatorios similares a los que describes).

Solución alternativa: use OnActivate -> ShowWindow(Handle, SW_MAXIMIZE) por ejemplo:

procedure TForm1.FormActivate(Sender: TObject); begin // Maximize only once when the Form is first activated if not FMaxsimized then begin FMaxsimized := True; ShowWindow(Handle, SW_MAXIMIZE); end; end;

Este método no funcionará durante OnShow .

Mejor solución alternativa: use ShowWindowAsync durante OnShow o OnCreate por ejemplo:

procedure TForm1.FormCreate(Sender: TObject); begin ShowWindowAsync(Handle, SW_MAXIMIZE); end;

Esto establece el estado del espectáculo de una ventana sin esperar a que se complete la operación.


Solo probé la primera carcasa de reproducción (con D7, D2007, XE2) y puedo duplicar el problema con D7 y D2007 pero no con XE2.

El problema, según lo veo, es que la etiqueta, al cambiar su fuente, solicita a su padre que se vuelva a alinear. Esto finalmente lleva a una llamada a SetWindowPos en el formulario (en TWinControl.AdjustSize ) con ancho / alto restaurado aunque el formulario ya esté maximizado, lo que lleva a que la forma extraña, maximizada en el comportamiento pero no maximizada visualmente , se asiente en la pantalla.

Rastreé el código en D2007 y XE2 para poder ver qué es diferente. El código en TWinControl.AlignControls es diferente entre las dos versiones. Lo que importa específicamente es la última declaración.

D2007:

procedure TWinControl.AlignControls(AControl: TControl; var Rect: TRect); .. { Apply any constraints } if Showing then AdjustSize; end;

XE2:

procedure TWinControl.AlignControls(AControl: TControl; var Rect: TRect); .. // Apply any constraints if FAutoSize and Showing then DoAdjustSize; end;

Espero que esto, de alguna manera, te ayude a diseñar / decidir qué solución usar.


La solución alternativa que podría sugerir (aunque no lo he probado a fondo) es forzar a mostrar la forma maximizada tempranamente:

procedure TForm1.FormCreate(Sender: TObject); var wplc: TWindowPlacement; begin if not AutoScroll and (WindowState = wsMaximized) then begin wplc.length := SizeOf(wplc); GetWindowPlacement(Handle, @wplc); wplc.rcNormalPosition.Right := wplc.rcNormalPosition.Left + Width; wplc.rcNormalPosition.Bottom := wplc.rcNormalPosition.Top + Height; wplc.showCmd := SW_MAXIMIZE; SetWindowPlacement(Handle, @wplc); end; end;

Lo anterior funciona porque obliga a establecer el foco en el control de edición (evento OnEnter ) antes de que la VCL establezca el indicador visible para la forma. A su vez, la solicitud de alineación de la etiqueta no da como resultado el ajuste del tamaño del formulario. Además, dado que, cuando VCL llama a ShowWindow la ventana del formulario ya está visible, no hace que el formulario se muestre en estado restaurado en ningún momento.

Sin embargo, no sé si ayudaría con diferentes escenarios de reproducción.

Finalmente, aunque puedo ver que el comportamiento se corrige en las versiones más nuevas de Delphi, no consideraría que esto sea un error en el VCL. En mi opinión, el código de usuario debe ser responsable de no causar el ajuste de la ventana mientras que la ventana que muestra el estado está cambiando. El curso de acción que tomaría para el escenario específico sería diferir para modificar la fuente de la etiqueta hasta que el VCL termine de mostrar el formulario.