2009-08-31 5 views
14

Il software è costruito su Delphi 7.Delphi 7 forme, non ancore lavorare in Vista

Sulla mia macchina XP, il modulo viene ridimensionato come mi aspetto. Tuttavia, su due macchine Vista, ho componenti con ancore impostate su [akLeft, akTop, akRight, akBottom], ma quando ridimensiono il modulo, i componenti non si allungano con il modulo, lasciando spazi vuoti sul margine destro e inferiore . Sulla macchina XP, i componenti si allungano correttamente con il modulo.

Quindi, sembra che la macchina Vista stia ignorando la proprietà di ancoraggio. Qualche idea su cosa sta causando questo e come risolverlo?

Importante aggiornamento (François):
abbiamo avuto lo stesso problema con il nostro D2007 applicazione e su tutte le finestre x64.
La risposta di Andreas era davvero la soluzione. Quindi non è collegato a D7 né a Vista.

+0

In quale versione di Windows è stato compilato il programma? – Argalatyr

+0

Compiled XP/Delphi 7 – Robo

+1

Vedere la risposta di Argalatyr. Ha senso? – Hemant

risposta

12

Forse è correlato al problema "Overflow dello stack di Windows Kernel" che si verifica se il controllo ha molti genitori. E se lo si esegue su un sistema a 64 bit, l'overflow dello stack del kernel avviene molto più velocemente. (Di più su questo qui: http://news.jrsoftware.org/news/toolbar2000/msg07779.html)

Su CodeCentral di Embarcadero è una soluzione per questo bug (che è anche copiato quasi 1: 1 in Delphi 2009 VCL): http://cc.embarcadero.com/Item/25646

+0

Ho ragione ad avere l'impressione che ciò si applichi solo se i controlli sono annidati a circa 20 livelli di profondità? – Argalatyr

+0

Dipende dal numero di hook della finestra WH_CALLWNDPROC installati in tutto il sistema. (Ad esempio, Logitech utilizza gli hook WH_CALLWNDPROC e così anche TActionManager). –

+0

Mi sono imbattuto in questo al lavoro e sono riuscito a rintracciare questo problema grazie al tuo post qui. Grazie per le informazioni e la correzione, Andreas. Ancora un'altra piuma nel tuo cappello già considerevole. –

0

Provare a eseguire il programma in modalità di compatibilità XP su Vista. I programmi compilati da Delphi 7 potrebbero non supportare completamente la modalità nativa di Vista (non c'è da stupirsi, davvero).

+0

I client vorranno eseguirlo in modalità Vista nativa piuttosto che in modalità compatibilità, sperando che ci sia un modo per aggirarlo. – Robo

+0

Capito. Scusa non ho più da offrire - Non uso più D7, e la mia risposta riassume la mia comprensione della situazione. Spero che tu trovi una soluzione! – Argalatyr

+2

Se si desidera il supporto completo per Vista, è necessario eseguire l'aggiornamento. È stata una caratteristica da Delphi 2007. In effetti, se vuoi davvero rimanere aggiornato, dovresti ottenere Delphi 2010, che è uscito la settimana scorsa. Ha pieno supporto per Windows 7 e Vista. –

2

Potrebbe essere a causa della cornice trasparente mostrata da Vista. (Al fine di dare diverse finestre stesso aspetto trasparente.

Prova a usare "Allinea" (alClient) al posto di ancoraggi. Dal momento che si sta utilizzando tutte le ancore, che ha più senso.

+0

Ciò non funzionerà perché il controllo occuperà l'intero schermo, coprendo altri controlli. – Robo

+1

Ad esempio hai un promemoria che copre la maggior parte dello schermo e hai alcuni pulsanti nella parte inferiore del modulo. Il pugno posiziona un pannello e imposta la proprietà Align su alBottom. Metti i tuoi controlli su quel pannello. Quindi si posiziona il controllo memo e si imposta la proprietà align su alClient (questo riempirà il modulo ma lascerà il pannello in basso). – Hemant

+0

+1 funziona (con il commento aggiuntivo di Hemant). Vedere il codice di lavoro nella mia risposta come esempio (avrei modificato la risposta di Hemant, ma preoccupato che potrebbe essere scortese). – Argalatyr

2

Prima ancore sono state introdotte in Delphi 4 , abbiamo ridimensionato i componenti in modo dinamico per ottenere lo stesso effetto. si può facilmente spostare/regolare i componenti nel caso del form onresize.

impostazione di proprietà della maschera doublebuffered per true può ridurre lo sfarfallio, tamponando il metodo paint. ricordo che abbiamo usato doverlo implementare anche noi!

1

In alternativa al ridimensionamento I dinamica suggerito, basandomi sul suggerimento di Hemant, ho schiaffeggiato un codice funzionante (sotto). Basta creare un'applicazione per moduli VCL, rilasciare un tpanel che non tocchi alcun lato del modulo (per impostazione predefinita, Align = alNone) e sostituire l'Unità1 con il codice riportato di seguito. Quando lo esegui, vedrai 4 pannelli gialli attorno a quello inizialmente aggiunto, e il pannello centrale verrà ridimensionato con il modulo (come se tutti gli ancoraggi fossero 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

Snippet piacevole (e approfondito)! – Hemant

0

E sembra questo è abbastanza vecchia questione, in ogni caso ecco la sola soluzione per questo problema nell'Universo: Utilizzare il metodo di programmazione di ridimensionamento di Windows vecchio stile utilizzando API intrappolando WM_SIZE e WM_SIZING, questa è l'unica infalible e funzionerà in ogni Windows lo saprai.

Ovviamente ciò significa che è necessario utilizzare principalmente GetClientRect() per determinare witdhs e heights e quindi ridimensionare i controlli in base a tali valori, certo che potrebbe sembrare di provare a innescare un'astronave ma è il migliore.

In caso contrario si potrebbe fare qualcosa di più pratico e rapido in una procedura di ridimensionamento come:

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

faccio quel tipo di codifica e funzioni in un solo tutti i Windows versione non importa wich che sarebbe stato.

Hai solo bisogno di alcuni valori sulla risoluzione dello schermo di riferimento a fare qualcosa di simile:

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; 

speranza aiuta a qualcun altro!

Cheers!

Problemi correlati