Einzelnen Beitrag anzeigen

Jim Carrey
(Gast)

n/a Beiträge
 
#23

AW: Formulare in hohen DPI korrekt anzeigen

  Alt 21. Okt 2016, 13:02
Meine aktuelle Lösung ist die folgende, für alle die, die es interessiert.
Mein Einsatzzweck ist eine multilinguale Software, wo ich die Edits und ComboBoxen nicht am Ende eines Satzes (CheckBox) haben sollte sondern grammatikalisch korrekt mittendrin.

So war es vorher:
Delphi-Quellcode:
LabelX.Caption := 'Das hier ist ein ganz langer Satz mit gefühlt....................völlig nutzlosen Zeichen!'; // statt den Punkten natürlich Leerzeichen
Edit1.Left := 123;
So ist es jetzt:
Delphi-Quellcode:
LabelX.Caption := 'Das hier ist ein ganz langer Satz mit gefühlt ' + calcSpacesNeeded(Edit1) + ' völlig nutzlosen Zeichen!';
setControlToPosition(Edit1, LabelX);
Delphi-Quellcode:
function getTextWidth(const aString: string; aForm: TForm): Integer;
var
 iRes: Integer;
 // Canvas: TCanvas;
begin
 iRes := 0;

 if aString <> 'then
  begin
   // Canvas := TCanvas.Create;

   // try
   // Canvas.Handle := GetDC(0);

   // try
   // Canvas.Font := aForm.Font;
   iRes := aForm.Canvas.TextWidth(aString); // nur diese Zeile wird benötigt, da aForm schon ein Canvas hat
   // finally
   // ReleaseDC(0, Canvas.Handle);
   // end;
   // finally
   // Canvas.Free;
   // end;
  end;

 Result := iRes;
end;

function calcSpacesNeeded(aControl: TControl): string;
var
 i, iTmpWidth, iSpaceWidth: Integer;
 sTmp: string;
begin
 iSpaceWidth := getTextWidth(' ', TForm(GetParentForm(aControl)));

 sTmp := '';
 iTmpWidth := aControl.Width div iSpaceWidth;

 for i := 0 to iTmpWidth do
  begin
   sTmp := sTmp + ' ';
  end;

 if aControl.ClassType = TEdit then
  sTmp := sTmp + ' // 6
 else if aControl.ClassType = TComboBox then
  sTmp := sTmp + ' // 4
 else
  sTmp := sTmp + ' '; // 2

 Result := sTmp;
end;

procedure setControlToPosition(aControlToSet, aControlSource: TControl);
var
 iSpacePosition, iCaptionWidth, iTmp: Integer;
 sCaption, sTmp: string;
begin
 if aControlSource.ClassType = TEdit then
  sCaption := (aControlSource as TEdit).Text
 else if (aControlSource.ClassType = TCheckBox) or (aControlSource.ClassType = TRadioButton) then
  sCaption := (aControlSource as TCheckBox).Caption
 else if (aControlSource.ClassType = TLabel) then
  sCaption := (aControlSource as TLabel).Caption;

 iSpacePosition := PosEx(' ', sCaption, 1) + 2;

 if iSpacePosition > 0 then
  begin
   sTmp := Copy(sCaption, 1, iSpacePosition);

   iCaptionWidth := getTextWidth(sTmp, TForm(GetParentForm(aControlToSet)));

   iTmp := aControlToSet.Width;
   if aControlSource.ClassType = TLabel then
    iTmp := aControlToSet.Width div 2;

   if aControlToSet.ClassType = TEdit then
    iTmp := iTmp + 2
   else if aControlToSet.ClassType = TComboBox then
    iTmp := iTmp - 4
   else
    iTmp := iTmp - 6;

   aControlToSet.Left := iCaptionWidth + iTmp;
  end;
end;
Das Resultat ist, dass Edit1 immer korrekt bei jeglicher DPI genau da im darunterliegenden Text-Control angezeigt wird, wo die Leerzeichen sind.

Geändert von Jim Carrey (21. Okt 2016 um 16:21 Uhr)
  Mit Zitat antworten Zitat