Einzelnen Beitrag anzeigen

DevilsCamp
(Gast)

n/a Beiträge
 
#1

Controls nicht da, wo sie sein sollen

  Alt 3. Aug 2006, 09:05
Ich möchte in einem Projekt dem Benutzer die Möglichkeit geben, in einem Dialog einen Wert einzugeben. Leider öffnet mir die Funktion InputBox aus QDialogs das Fenster ständig in der Mitte des Desktops. Bei einem Monitor ja noch erträglich, doch bei zwei Monitoren wird das Fenster dann zur Hälfte auf Monitor 1 und die andere auf Monitor 2 angezeigt (sofern sie nebeneinander stehen).
Daher habe ich mir eine eigene Form geschrieben, die ich dann entsprechend ausrichten kann:

Delphi-Quellcode:
unit frm_InputDialog;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TfrmInputDialog = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    FMaxLength: Integer;
    FNumbersOnly: Boolean;
    FLabAnzeige: TLabel;
    FEdEdit: TEdit;
    FOkButton: TButton;
    FAbbButton: TButton;
    procedure SetMaxLength(const Value: Integer);
    procedure SetNumbersOnly(const Value: Boolean);
    function GetAnzeige: string;
    procedure SetAnzeige(const Value: string);
    function GetInput: string;
    procedure SetInput(const Value: string);
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property MaxLength: Integer read FMaxLength write SetMaxLength;
    property NumbersOnly: Boolean read FNumbersOnly write SetNumbersOnly default false;
    property Anzeige: string read GetAnzeige write SetAnzeige;
    property Input: string read GetInput write SetInput;
  end;

var
  frmInputDialog : TfrmInputDialog;

implementation

{$R *.dfm}

constructor TfrmInputDialog.Create(AOwner: TComponent);
begin
  inherited;

  FNumbersOnly := false;
end;

destructor TfrmInputDialog.Destroy;
begin
  FLabAnzeige.Free;
  FEdEdit.Free;
  FOkButton.Free;
  FAbbButton.Free;

  inherited;
end;

procedure TfrmInputDialog.FormCreate(Sender: TObject);
begin
  FLabAnzeige := TLabel.Create(Self);
  with FLabAnzeige do
  begin
    Name := 'Lab1';
    Parent := Self;
    Left := 8;
    Top := 14;
    Width := 32;
    Height := 13;
    Caption := 'Label1';
  end;

  FEdEdit := TEdit.Create(Self);
  with FEdEdit do
  begin
    Name := 'Ed1';
    Parent := Self;
    Left := 8;
    Top := 39;
    Width := 244;
    Height := 21;
    Anchors := [akLeft, akRight];
    TabOrder := 0;
    Text := '';
  end;

  FOkButton := TButton.Create(Self);
  with FOkButton do
  begin
    Name := 'OKButton1';
    Parent := Self;
    Tag := 60;
    Left := 25;
    Top := 77;
    Width := 100;
    Height := 25;
    Anchors := [akLeft, akBottom];
    Caption := '&OK';
    ModalResult := 1;
    TabOrder := 0;
  end;

  FAbbButton := TButton.Create(Self);
  with FAbbButton do
  begin
    Name := 'AbbButton2';
    Parent := Self;
    Tag := 63;
    Left := 135;
    Top := 77;
    Width := 100;
    Height := 25;
    Anchors := [akRight, akBottom];
    Caption := '&Cancel';
    ModalResult := 2;
    TabOrder := 0;
  end;

  Caption := Format('%d %d', [FOkButton.Left, FOkButton.Top]);
end;

function TfrmInputDialog.GetAnzeige: string;
begin
  Result := FLabAnzeige.Caption;
end;

function TfrmInputDialog.GetInput: string;
begin
  Result := FEdEdit.Text;
end;

procedure TfrmInputDialog.SetAnzeige(const Value: string);
begin
  if (Value <> FLabAnzeige.Caption) then
  begin
    FLabAnzeige.Caption := Value;
    ClientWidth := FLabAnzeige.Width + 16;
  end;
end;

procedure TfrmInputDialog.SetInput(const Value: string);
var
  i : Integer;
begin
  if (Value <> FEdEdit.Text) then
  begin
    if FNumbersOnly then
    begin
      try
        i := StrToInt(Value);
        FEdEdit.Text := Value;
        SetMaxLength(FMaxLength);
      except
      end;
    end;
  end;
end;

procedure TfrmInputDialog.SetMaxLength(const Value: Integer);
var
  s : string;
begin
  FMaxLength := Value;
  FEdEdit.MaxLength := FMaxLength;
  s := FEdEdit.Text;
  Delete(s, MaxLength + 1, Length(s));
  FEdEdit.Text := s;
end;

procedure TfrmInputDialog.SetNumbersOnly(const Value: Boolean);
var
  l : Integer;
begin
  if (Value <> FNumbersOnly) then
  begin
    FNumbersOnly := Value;
    l := GetWindowLong(FEdEdit.Handle, GWL_STYLE);
    l := l or ES_NUMBER;

    if (not Value) then
      l := l xor ES_NUMBER;

    SetWindowLong(FEdEdit.Handle, GWL_STYLE, l);
  end;
end;

procedure TfrmInputDialog.FormShow(Sender: TObject);
begin
  FEdEdit.SetFocus;
end;

end.
und noch die entsprechende DFM-Datei:
Delphi-Quellcode:
object frmInputDialog: TfrmInputDialog
  Left = 541
  Top = 440
  Width = 268
  Height = 142
  Color = clBtnFace
  Constraints.MaxHeight = 142
  Constraints.MinHeight = 142
  Constraints.MinWidth = 268
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  Scaled = False
  OnCreate = FormCreate
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
end
Doch leider gibt es da ein Problem:
Solange ich die Anchors setze, werden die erstellten Controls zwar erst richtig auf die Form gelegt, sobald sie aber angezeigt werden soll ändern sich ihre Left und Top Werte und die Anzeige wird fehlerhaft. Siehe Anhänge.

Eine Abhilfe wäre in der Methode FormShow die Werte neu zu setzen, aber das ist für mich eine nicht zufriedenstellende Lösung, da ich ja die Koordinaten richtig eingegeben habe und sie auch nicht verändere.

Die Werte, die in der Titelleiste zusehen sind, sind die Left und Top Werte des OK-Buttons, ausgelesen direkt nach der Erstellung.

Dieses Problem habe ich auch, wenn ich die Unit in anderen Projekten benutze.

Ich hoffe, einer von euch kann mir helfen.
Miniaturansicht angehängter Grafiken
falsch_147.jpg   richtig_152.jpg  
  Mit Zitat antworten Zitat