2009-08-31 16 views
14

El software se basa en Delphi 7.Delphi 7 forma, no anclas de trabajo en Vista

En mi máquina XP, cambia el tamaño de la forma como espero. Sin embargo, en dos máquinas Vista, tengo componentes con anclajes establecidos en [akLeft, akTop, akRight, akBottom], pero cuando cambio el tamaño del formulario, los componentes no se estiran con el formulario, dejando espacios en blanco en el borde derecho e inferior . En la máquina XP, los componentes se estiran correctamente con el formulario.

Parece que la máquina de Vista está ignorando la propiedad de anclaje. ¿Alguna idea de lo que está causando esto y cómo solucionarlo?

Importante actualización (François):
Tuvimos el mismo problema con nuestra D2007 aplicación y en todas las ventanas x64.
La respuesta de Andreas fue de hecho la solución. No está relacionado con D7 ni Vista.

+0

¿Bajo qué versión de Windows se compiló el programa? – Argalatyr

+0

XP compilado/Delphi 7 – Robo

+1

Consulte la respuesta del autorizador. ¿Tiene sentido? – Hemant

Respuesta

12

Quizás esté relacionado con el problema "Desbordamiento de pila del Kernel de Windows" que ocurre si el control tiene muchos elementos principales. Y si lo ejecuta en un sistema de 64 bits, el desbordamiento de la pila del kernel ocurre mucho más rápido. (Más sobre esto aquí: http://news.jrsoftware.org/news/toolbar2000/msg07779.html)

En CodeCentral de Embarcadero es una solución de este error (que también se copian casi 1: 1 en el Delphi 2009 VCL): http://cc.embarcadero.com/Item/25646

+0

¿Tengo razón al darme la impresión de que esto solo se aplica si tiene controles anidados a unos 20 niveles de profundidad? – Argalatyr

+0

Depende de cuántos ganchos de ventana WH_CALLWNDPROC están instalados en todo el sistema. (Logitech, por ejemplo, utiliza los ganchos WH_CALLWNDPROC, y también lo hace el TActionManager). –

+0

Acabo de encontrarme con este en el trabajo y logré rastrear este problema gracias a su publicación aquí. Gracias por la información y la solución, Andreas. Otra pluma en tu ya considerable gorra. –

0

Intenta ejecutar el programa en modo de compatibilidad XP en Vista. Los programas compilados por Delphi 7 pueden no ser totalmente compatibles con el modo nativo de Vista (no es sorprendente, en realidad).

+0

Los clientes querrán ejecutarlo en Vista nativa en lugar de hacerlo en modo compatibilidad, esperando que haya alguna forma de evitarlo. – Robo

+0

Entendido. Lo siento, no tengo más para ofrecer, ya no uso D7 y mi respuesta resume mi comprensión de la situación. ¡Espero que encuentres una solución! – Argalatyr

+2

Si quieres compatibilidad total con Vista, vas a tener que actualizar. Ha sido una característica desde Delphi 2007. De hecho, si realmente quieres estar al día, deberías obtener Delphi 2010, que salió la semana pasada. Tiene soporte completo para Windows 7 y Vista. –

2

Puede ser debido al marco transparente que se muestra en Vista. (Con el fin de dar diferentes ventanas misma apariencia transparente.

Trate de usar "Align" (alClient) en lugar de los anclajes. Puesto que usted está utilizando todos los anclajes, que tiene más sentido.

+0

Eso no funcionará porque el control ocupará toda la pantalla, cubriendo otros controles. – Robo

+1

Por ejemplo, tiene una nota que cubre la mayor parte de su pantalla y tiene algunos botones en la parte inferior del formulario. Primero coloca un panel y establece su propiedad Align en alBottom. Usted coloca sus controles en ese panel. A continuación, coloca el control de notas y establece su propiedad de alineación a alClient (esto completará el formulario pero saldrá del panel inferior). – Hemant

+0

+1 esto funciona (con el comentario adicional de Hemant). Ver el código de trabajo en mi respuesta como un ejemplo (habría editado la respuesta de Hemant, pero me preocupaba que pudiera ser grosero). – Argalatyr

2

Antes de anclas fueron introducidos en Delphi 4 , hemos cambiado el tamaño de los componentes de forma dinámica para lograr el mismo efecto. Es fácil mover/ajustar los componentes en el evento de la forma onresize.

Configuración de propiedades del formulario doublebuffered a true puede reducir el parpadeo, amortiguando el método paint. recuerdo que usamos ¡tener que implementar eso nosotros también!

1

Como una alternativa al cambio de tamaño me dinámico sugerí, basado en la sugerencia de Hemant, que redacté un código de trabajo (abajo). Simplemente cree una aplicación de formularios VCL, coloque en un tpanel que no toque ningún borde del formulario (de forma predeterminada, Align = alNone) y reemplace Unit1 con el código siguiente. Cuando lo ejecute, verá 4 paneles amarillos alrededor del que se agregó inicialmente, y el panel central cambiará el tamaño del formulario (como si todos los anclajes fueran true).

unit Unit1; 

interface 

uses 
    Windows, Classes, Controls, Forms, ExtCtrls, Graphics; 

type 
    TPanelPos = (ppLeft, ppRight, ppTop, ppBottom); 
    TForm1 = class(TForm) 
    Panel1: TPanel; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    private 
    { Private declarations } 
    Panels : array[TPanelPos] of tpanel; 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
var 
    PanelPos : TPanelPos; 
begin 
    for PanelPos := ppLeft to ppBottom do 
    begin 
    Panels[PanelPos] := tpanel.Create(Form1); 
    Panels[PanelPos].Parent := Form1; 
    Panels[PanelPos].Color := clYellow; 
    case PanelPos of 
    ppLeft : 
     begin 
     Panels[PanelPos].Align := alLeft; 
     Panels[PanelPos].Width := Panel1.Left - 1; 
     end; 
    ppRight : 
     begin 
     Panels[PanelPos].Align := alRight; 
     Panels[PanelPos].Width := Form1.Width - Panel1.Left - Panel1.Width; 
     end; 
    ppTop : 
     begin 
     Panels[PanelPos].Align := alTop; 
     Panels[PanelPos].Height := Panel1.Top - 1; 
     end; 
    ppBottom : 
     begin 
     Panels[PanelPos].Align := alBottom; 
     Panels[PanelPos].Height := Form1.Height - Panel1.Top - Panel1.Height; 
     end; 
    end; 
    Panel1.Align := alClient; 
    end; 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
var 
    PanelPos : TPanelPos; 
begin 
    for PanelPos := ppLeft to ppBottom do 
    Panels[PanelPos].Free; 
end; 

end. 
+1

¡Fragmento agradable (y minucioso)! – Hemant

0

Parece que esto es bastante vieja cuestión, de todos modos aquí es la única solución para este problema en el Universo: Utilice el método de dimensionamiento de programación viejo estilo de Windows utilizando la API atrapando WM_SIZE y WM_SIZING, esa es la que infalible y funcionará en cada Windows lo sabrás.

Por supuesto, esto significa que tiene que usar principalmente GetClientRect() para determinar alturas y alturas y luego cambiar el tamaño de los controles en función de dichos valores, seguro que puede sonar como intentar encender una nave espacial pero es lo mejor.

De lo contrario se podría hacer algo más práctico y rápido en un procedimiento de cambio de tamaño como:

Control1.Left := Control2.Left + (buttonControl.Width div 2) - (buttonControl3.Width div 2); 
//for example widths 
Control4.Width := (Control.Width * 4) + (Control.Left * 8) + 54 ; 

hago ese tipo de codificación y funciones en tan sólo todos los Windows versión no importa wich que sería.

Sólo se necesitan algunos valores en la resolución de la pantalla para referencia haciendo algo como esto:

iCXSCREEN := GetSystemMetrics(SM_CXSCREEN); 
iCYSCREEN := GetSystemMetrics(SM_CYSCREEN); 

    if ((iCXSCREEN = 1280) and (iCYSCREEN = 720)) or ((iCXSCREEN = 1280) and (iCYSCREEN = 700)) or ((iCXSCREEN = 1280) and (iCYSCREEN = 600)) then begin 

// blah blah 

end; 

Esperanza ayuda a otra persona!

¡Salud!

Cuestiones relacionadas