2017-06-28 2 views
1

Ich habe folgende Beispiel TForm1 Form mit zwei Tasten (BitBtn):Wie kann ich visuelle Vererbung mit hohen dpi-Werten arbeiten?

base form

Zusätzlich habe ich eine zweite Form TForm2 die sich von der ersten Form abgeleitet ist. Die zweite Taste nach links bewegt wird, und eine andere Taste hinzugefügt:

derived form

Zur Laufzeit (Windows 7), sieht die zweite Form wie folgt aus:

standard font size

Wenn ich ändern Schrift Skalierung auf 125%, sieht mein Formular so aus:

increased font size

Irgendwie hat der neue Knopf die falsche Position und die falsche Größe. Was kann ich dagegen tun?

ich verwendet, um die folgenden .dfm Dateien (verkürzt):

object Form1: TForm1 
    Left = 0 
    Top = 0 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    PixelsPerInch = 96 
    TextHeight = 13 
    object BitBtn1: TBitBtn 
    Left = 8 
    Top = 8 
    Width = 105 
    Height = 105 
    Caption = 'BitBtn1' 
    end 
    object BitBtn2: TBitBtn 
    Left = 359 
    Top = 8 
    Width = 105 
    Height = 105 
    Caption = 'BitBtn2' 
    end 
end 

inherited Form2: TForm2 
    Caption = 'Form2' 
    PixelsPerInch = 96 
    TextHeight = 13 
    inherited BitBtn2: TBitBtn 
    Left = 191 
    Top = 7 
    ExplicitLeft = 191 
    ExplicitTop = 7 
    end 
    object BitBtn3: TBitBtn 
    Left = 359 
    Top = 8 
    Width = 105 
    Height = 104 
    Caption = 'BitBtn3' 
    end 
end 

Class-Dateien unverändert bleiben, wie der Designer sie erzeugt. Sie enthalten keinen relevanten Code.

Antwort

2

fand ich eine mögliche Lösung selbst:

procedure TForm2.ReadState(Reader: TReader); 
begin 
    IntPtr(FReserved) := 0; 
    inherited; 
end;  

Das sieht seltsam: ein ReadState mit den folgenden Code zu überschreiben. Wie funktioniert es?

Ich schaute auf den VCL Quellcode und fand , dass die Skalierung nach dem Laden von Formularen erfolgt in TForm.ReadState(...). Apparrently, ein Feld FReserved von TControl geschützt wird verwendet, um die zur Zeit angewendet DPI Wert zu speichern:

  • zunächst alle Komponenten meiner Basisklasse dfm gelesen
  • dann werden sie skaliert und positioniert richtig
  • und der aktuell angewendete DPI Wert wird in FReserved
  • gespeichert, danach wird ReadState erneut aufgerufen, für die dfm Datei der abgeleiteten Klasse
  • aber wegen des Wertes in FReserved, Skalierung auf Komponenten der abgeleiteten Form nicht angewandt wird

So würde eine Idee, die im Cache gespeicherten DPI Wert zurückgesetzt werden, bevor die Komponenten zu lesen. Es skaliert die Komponenten von Form1 zweimal, aber das tut nicht weh, da die ursprünglichen Größen und Positionen als Basiswert für die Skalierung gespeichert werden und das Ergebnis genau gleich ist.

+5

Sie sollten dies an Embarcadero melden, damit sie es beheben können. –

+0

Ich hätte es gemeldet, aber wie sich herausstellt [es ist bereits gemeldet] (https://quality.embarcadero.com/browse/RSP-12971). Eine der lästigsten Konsequenzen, die eine Anmeldung für das Qualitätsportal erfordert, ist, dass Suchmaschinen den Inhalt nicht indexieren können. Obwohl ich das Problem mit meiner ersten Suchanfrage gefunden habe, funktioniert die interne Suchmaschine ordnungsgemäß. – ventiseis

+0

Zusätzlich scheint dies mit 'Delphi 10.1 Berlin' behoben worden zu sein. – ventiseis

Verwandte Themen