2009-08-31 1 views
14

Die Software auf Delphi gebaut 7.Delphi 7 bildet, Anker nicht in Vista arbeiten

Auf meinem XP-Rechner, wird die Größe der Form, wie ich erwartet. Allerdings habe ich auf zwei Vista-Rechnern Komponenten mit Ankern, die auf [akLeft, akTop, akRight, akBottom] eingestellt sind. Wenn ich jedoch die Größe des Formulars ändere, streckten sich die Komponenten nicht mit dem Formular und ließen Leerstellen am rechten und unteren Rand zurück . Auf der XP-Maschine dehnen sich die Komponenten korrekt mit dem Formular.

So scheint es, dass der Vista-Rechner die Ankereigenschaft ignoriert. Irgendwelche Ideen, was das verursacht und wie man es repariert?

Wichtiges Update (François):
Wir hatten das gleiche Problem mit unserer D2007 Anwendung und auf allen x64 Fenster.
Andreas Antwort war in der Tat die Lösung. So ist es nicht D7 noch Vista verwandt.

+0

Unter welcher Version von Windows wurde das Programm kompiliert? – Argalatyr

+0

Kompiliert XP/Delphi 7 – Robo

+1

Siehe Argalatryrs Antwort. Macht das Sinn? – Hemant

Antwort

12

Vielleicht hängt es mit dem Problem "Windows Kernel Stack Overflow" zusammen, das auftritt, wenn Ihr Steuerelement viele Eltern hat. Und wenn Sie es auf einem 64-Bit-System ausführen, passiert der Kernel-Stack-Überlauf viel schneller. (Mehr dazu hier: http://news.jrsoftware.org/news/toolbar2000/msg07779.html)

Auf Embarcadero Codecentral ist eine Abhilfe für diesen Fehler (die auch fast 1 kopiert: 1 in die Delphi 2009 VCL): http://cc.embarcadero.com/Item/25646

+0

Habe ich recht, wenn ich den Eindruck habe, dass dies nur gilt, wenn Sie die Kontrollen etwa 20 Ebenen tief geschachtelt haben? – Argalatyr

+0

Es hängt davon ab, wie viele WH_CALLWNDPROC Window Hooks systemweit installiert sind. (Logitech verwendet zum Beispiel WH_CALLWNDPROC-Hooks, ebenso wie der TActionManager). –

+0

Ich bin gerade in dieses bei der Arbeit gerannt und habe es geschafft, es zu diesem Thema dank Ihrer Post hier zu verfolgen. Danke für die Information und die Lösung, Andreas. Noch eine Feder in deiner schon beträchtlichen Kappe. –

0

Versuchen Sie, das Programm im XP-Kompatibilitätsmodus unter Vista auszuführen. Programme, die von Delphi 7 kompiliert wurden, unterstützen den nativen Modus von Vista möglicherweise nicht vollständig (keine Überraschung, wirklich).

+0

Die Clients werden es lieber im nativen Vista als im Kompatibilitätsmodus ausführen, in der Hoffnung, dass es einen Weg gibt, um das zu umgehen. – Robo

+0

Verstanden. Entschuldigung, ich habe nicht mehr zu bieten - ich benutze D7 nicht mehr und meine Antwort fasst mein Verständnis der Situation zusammen. Ich hoffe du findest eine Lösung! – Argalatyr

+2

Wenn Sie volle Unterstützung von Vista wollen, müssen Sie upgraden. Es ist ein Feature seit Delphi 2007. Wenn Sie wirklich aktuell bleiben wollen, sollten Sie Delphi 2010, das letzte Woche herauskam, erhalten. Es hat volle Unterstützung für Windows 7 sowie Vista. –

2

Es könnte wegen des transparenten Rahmens sein, der von Vista gezeigt wird. (Um verschiedene Fenstern gleiches transparentes Aussehen zu verleihen.

Versuchen „Ausrichten“ (alClient) anstelle von Dübeln. Da Sie alle Anker verwenden, dass mehr Sinn macht.

+0

Das funktioniert nicht, da das Steuerelement den gesamten Bildschirm einnimmt und andere Steuerelemente abdeckt. – Robo

+1

Zum Beispiel haben Sie eine Notiz, die den größten Teil Ihres Bildschirms abdeckt, und Sie haben einige Knöpfe am unteren Rand des Formulars. Sie platzieren zuerst ein Panel und legen die Align-Eigenschaft auf alBottom fest. Sie platzieren Ihre Steuerelemente in diesem Bereich. Dann platzieren Sie das Memo-Steuerelement und legen die align-Eigenschaft auf alClient fest (dadurch wird das Formular ausgefüllt, aber das untere Feld bleibt erhalten). – Hemant

+0

+1 das funktioniert (mit Hemants Zusatzkommentar). Sehen Sie Arbeitscode in meiner Antwort als ein Beispiel (Ich hätte Hemants Antwort bearbeitet, aber besorgt, dass das unhöflich sein könnte). – Argalatyr

2

Vor Anker in Delphi eingeführt wurde 4 wir Komponenten dynamisch den gleichen Effekt zu erzielen Größe verändert werden. Sie können ganz einfach die Komponenten in dem onresize-Ereignisse des Formulars.

Festlegen des doublebuffered Eigenschaft des Formulars auf true reduzieren können Flimmern bewegen/justieren, durch Pufferung der paint Methode. ich erinnere mich, wir verwenden das auch selbst umsetzen zu müssen!

1

Als Alternative zum dynamischen Ändern der Größe I vorgeschlagen, basierend auf Hemants Vorschlag habe ich einen Arbeitscode zusammengefügt (unten). Erstellen Sie einfach eine VCL-Formularanwendung, legen Sie eine tpanel, die keine Kante des Formulars berührt (standardmäßig Align = alNone) und ersetzen Sie Unit1 durch den folgenden Code. Wenn Sie es ausführen, sehen Sie vier gelbe Felder, die das ursprünglich hinzugefügte Element umgeben, und das zentrale Feld wird mit dem Formular skaliert (als ob alle Anker true wären).

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

Schön (und gründlich) Schnipsel! – Hemant

0

Es sieht dieses hübsche alte Frage ist, dann ist sowieso hier die einzige im Universum für dieses Problem eine Lösung: Verwenden Sie die alten Stil-Methode Windows-Programmierung Schlichte API WM_SIZE und WM_SIZING Trapping, das ist die infalible ein und funktioniert In jedem Windows wirst du es wissen.

Natürlich bedeutet dies, dass Sie hauptsächlich GetClientRect() verwenden müssen, um Withdhs und Höhen zu bestimmen und dann die Größe basierend auf solchen Werten zu ändern, sicher, dass es wie ein Raumschiff zu klingen scheint, aber es ist das Beste.

Sonst könnte man etwas mehr praktisch und schnell in einem Verkleinerungsprozess wie zu tun:

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

ich in nur alle Windows diese Art der Codierung und Funktionen tun, egal weicht Version wäre es.

Sie brauchen nur einige Werte auf der Bildschirmauflösung als Referenz etwas wie dies zu tun:

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; 

Hoffnung hilft jemand anderes!

Prost!