Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Formular Position speichern (https://www.delphipraxis.net/186030-formular-position-speichern.html)

Perlsau 29. Jul 2015 13:10

AW: Formular Position speichern
 
Zitat:

Zitat von Mavarik (Beitrag 1310139)
Sollten die Daten 1. Computernamen bezogen gespeichert werden und bei laden getestet werden ob es die Top/Left Positions auf dem aktuellen Computer gibt...

Eine vortreffliche Ergänzung, die mir bislang nicht in den Sinn gekommen ist. Dafür danke ich dir herzlich :thumb:

In der Tat hatte ich gelegentlich Rückfragen von Kunden zu bearbeiten, die sich darüber beschwerten, daß ein Formular, das sie zur Anzeige gewählt hatten, nicht sichtbar sei. Ich habe dann natürlich jedesmal erklärt, daß das Formular nur deshalb nicht zu sehen sei, weil es sich außerhalb des Bildschirms befände und anschließend erläutert, wie man dieses Formular via Tastatur wieder in den sichtbaren Bereich herüberziehen kann. Diese Problematik hat sich mit deiner Hilfe nun endgültig erledigt :thumb:

Mavarik 29. Jul 2015 13:16

AW: Formular Position speichern
 
Zitat:

Zitat von Perlsau (Beitrag 1310143)
Dafür danke ich dir herzlich :thumb:

Danke... Kurze Ergänzung:

Ein Formular kann schon über den Bildschirmrand hinaus gehen... Man sollte testen ob die Titelleiste
per Maus greifbar ist, damit der Kunde nicht die F10 usw... Tastaturbedienung zum Fensterverschieben lernen muss...

Bedeutet bei "links raus" die Weite der minimize,maximize und close Schaltflächen abzuziehen...

Es hat sich auch bewährt im Menue neben der Window-Liste einen Reset-Positionsaufruf ins Mainmenue zu übernehmen...

Perlsau 29. Jul 2015 13:30

AW: Formular Position speichern
 
Im Grunde sollte es genügen zu überprüfen, ob der Left-Wert größer ist als ScreenMax. Ist noch was vom Fenster zu sehen, kann der Anwender sich in der Regel selbst behelfen. Oder man prüft gleich in Einstellungen_Lesen, ob der Left-Wert plus Fensterbreite größer ist als ScreenMax und korrigiert dann sofort. Das werde ich demnächst mal genauer ausbaldowern müssen. Das Formular kann ja auch in Minusbereich des Screens (unsichtbar) "erscheinen", je nachdem, wie die Anordnung der verschiedenen Bildschirme zuvor aussah. Bei Releases hab ich immer darauf geachtet, daß die mitgelieferte Datenbank keine Formulare auf möglicherweise unsichtbaren Screens öffnet, indem ich die Positionen entweder von Hand in der DB geändert habe oder beim letzten Test vor dem Versenden die entsprechenden Formulare einfach richtig positionierte. Das ist natürlich umständlich, was sich mit deinem Vorschlag jetzt erledigt hat.

Dejan Vu 29. Jul 2015 14:32

AW: Formular Position speichern
 
Hmmm..

Delphi-Quellcode:
Function TMyFormDataModule.LoadFormPos (Form : TForm);
Begin
  // Damit die Position nur 1x gesetzt wird.
  If Form.Tag=1 then Exit;
  Form.Tag := 1;

  FormPosition.Active := False;
  // FormPosition.SQL := 'select * from FormPositionen '
  //                    +'where UserName = :UserName and FormName = :FormName';

  FormPosition.Parameters.ParamByName['UserName'] := Self.TheUserName;
  FormPosition.Parameters.ParamByName['FormName'] := Form.Name;
  FormPosition.Open;

  If FormPosition.IsEmpty then Exit;

  Form.Left := FormPosition['Left'];
  Form.Top := FormPosition['Top'];
  Form.Width := FormPosition['Width'];
  Form.Height := FormPosition['Height'];
  DemandFormOnScreen(Form); // Stellt sicher, das das Formular sichtbar ist.
End;
Abspeichern geht dann analog.

In jedem Formular...

Delphi-Quellcode:
Procedure TMyForm.FormActivate(Sender : TObject);
Begin
  MyFormDataModule.LoadFormPos (Self);
End;
Getippt und nicht getestet, sollte aber so oder ähnlich laufen.

bernau 29. Jul 2015 15:00

AW: Formular Position speichern
 
Zitat:

Zitat von Dejan Vu (Beitrag 1310172)
Hmmm..

Delphi-Quellcode:
Function TMyFormDataModule.LoadFormPos (Form : TForm);
Begin
  // Damit die Position nur 1x gesetzt wird.
  If Form.Tag=1 then Exit;
  Form.Tag := 1;

  FormPosition.Active := False;
  // FormPosition.SQL := 'select * from FormPositionen '
  //                    +'where UserName = :UserName and FormName = :FormName';

  FormPosition.Parameters.ParamByName['UserName'] := Self.TheUserName;
  FormPosition.Parameters.ParamByName['FormName'] := Form.Name;
  FormPosition.Open;

  If FormPosition.IsEmpty then Exit;

  Form.Left := FormPosition['Left'];
  Form.Top := FormPosition['Top'];
  Form.Width := FormPosition['Width'];
  Form.Height := FormPosition['Height'];
  DemandFormOnScreen(Form); // Stellt sicher, das das Formular sichtbar ist.
End;
Abspeichern geht dann analog.

Das sind aber geringfügig mehr als die max. 7-10 Zeilen in einer Procedure wie du im deinem Post aus dem anderen Thread behauptest.

SCNR :lol:

Sir Rufo 29. Jul 2015 15:45

AW: Formular Position speichern
 
Zitat:

Zitat von bernau (Beitrag 1310184)
Das sind aber geringfügig mehr als die max. 7-10 Zeilen in einer Procedure wie du im deinem Post aus dem anderen Thread behauptest.

SCNR :lol:

Ich sehe hier aber auch in keinster Weise irgendwo Clean Code, sondern wie angekündigt einfach nur mal so schnell getippt für einen ungefähren Anhaltspunkt.

Clean Code wäre eher etwas in dieser Richtung:
Delphi-Quellcode:
unit Services;

interface

uses
  System.Classes;

type
  IFormSettingsService = interface
    [ '{37C1665C-8C12-4430-9820-83D82DB76366}' ]
    function GetBlock( const BlockName: string; const ABlockData: TStream ): Boolean;
    function SetBlock( const BlockName: string; const ABlockData: TStream ): Boolean;
  end;

implementation

end.
Delphi-Quellcode:
unit Services.Impl;

interface

uses
  System.Classes,
  Services;

type
  TIniFormSettingsService = class( TInterfacedObject, IFormSettingsService )
  private
    FFileName: string;
    FSection: string;
  public
    constructor Create( const AFileName, ASection: string );
    function GetBlock( const BlockName: string; const ABlockData: TStream ): Boolean;
    function SetBlock( const BlockName: string; const ABlockData: TStream ): Boolean;
  end;

implementation

uses
  System.IniFiles;

{ TIniFormSettingsService }

constructor TIniFormSettingsService.Create( const AFileName, ASection: string );
begin
  inherited Create;
  FFileName := AFileName;
  FSection := ASection;
end;

function TIniFormSettingsService.GetBlock( const BlockName: string; const ABlockData: TStream ): Boolean;
var
  LIniFile: TIniFile;
begin
  LIniFile := TIniFile.Create( FFileName );
  try
    if LIniFile.SectionExists( FSection ) and LIniFile.ValueExists( FSection, BlockName ) then
    begin
      LIniFile.ReadBinaryStream( FSection, BlockName, ABlockData );
      Result := True;
    end
    else
      Result := False;
  finally
    LIniFile.Free;
  end;
end;

function TIniFormSettingsService.SetBlock( const BlockName: string; const ABlockData: TStream ): Boolean;
var
  LIniFile: TIniFile;
begin
  LIniFile := TIniFile.Create( FFileName );
  try
    ABlockData.Seek( 0, soFromBeginning );
    LIniFile.WriteBinaryStream( FSection, BlockName, ABlockData );
    Result := True;
  finally
    LIniFile.Free;
  end;
end;

end.
Delphi-Quellcode:
unit Configuration;

interface

implementation

uses
  FMX.Platform,
  Services,
  Services.Impl;

initialization

TPlatformServices.Current.AddPlatformService( IFormSettingsService, TIniFormSettingsService.Create( '.\foo.ini', 'forms' ) ); // ja, ja, das ist ein Unding mit dem relativen Pfad :o)

end.
Delphi-Quellcode:
unit Form.BaseForm;

interface

uses
  Services,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TBaseForm = class( TForm )
  private
    FLoaded: Boolean;
    procedure InternalLoadSettings( Service: IFormSettingsService );
    procedure InternalStoreSettings( Service: IFormSettingsService );
  protected
    function GetBlockName: string; virtual;
    procedure DoClose( var Action: TCloseAction ); override;
    procedure DoShow; override;
    procedure DoLoadSettings( Settings: TBinaryReader ); virtual;
    procedure DoStoreSettings( Settings: TBinaryWriter ); virtual;
  public
    procedure LoadSettings;
    procedure StoreSettings;
  end;

var
  BaseForm: TBaseForm;

implementation

{$R *.dfm}

uses
  FMX.Platform;

{ TBaseForm }

procedure TBaseForm.DoClose( var Action: TCloseAction );
var
  LService: IFormSettingsService;
begin
  inherited;
end;

procedure TBaseForm.DoLoadSettings( Settings: TBinaryReader );
begin
end;

procedure TBaseForm.DoShow;
begin
  if not FLoaded then
    LoadSettings;
  FLoaded := True;
  inherited;
end;

procedure TBaseForm.DoStoreSettings( Settings: TBinaryWriter );
begin

end;

function TBaseForm.GetBlockName: string;
begin
  Result := Self.ClassName;
end;

procedure TBaseForm.InternalLoadSettings( Service: IFormSettingsService );
var
  LBlockData: TMemoryStream;
  LReader: TBinaryReader;
begin
  LBlockData := TMemoryStream.Create;
  try
    if Service.GetBlock( GetBlockName, LBlockData ) then
    begin
      LBlockData.Seek( 0, soFromBeginning );
      LReader := TBinaryReader.Create( LBlockData );
      try
        DoLoadSettings( LReader );
      finally
        LReader.Free;
      end;
    end;
  finally
    LBlockData.Free;
  end;
end;

procedure TBaseForm.InternalStoreSettings( Service: IFormSettingsService );
var
  LBlockData: TMemoryStream;
  LWriter: TBinaryWriter;
begin
  LBlockData := TMemoryStream.Create;
  try
    LWriter := TBinaryWriter.Create( LBlockData );
    try
      DoStoreSettings( LWriter );
    finally
      LWriter.Free;
    end;
    LBlockData.Seek( 0, soFromBeginning );
    Service.SetBlock( GetBlockName, LBlockData );
  finally
    LBlockData.Free;
  end;
end;

procedure TBaseForm.LoadSettings;
var
  LService: IFormSettingsService;
begin
  if TPlatformServices.Current.SupportsPlatformService( IFormSettingsService, LService ) then
    InternalLoadSettings( LService );
end;

procedure TBaseForm.StoreSettings;
var
  LService: IFormSettingsService;
begin
  if TPlatformServices.Current.SupportsPlatformService( IFormSettingsService, LService ) then
    InternalStoreSettings( LService );
end;

end.
Delphi-Quellcode:
unit Form.MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Form.BaseForm, Vcl.StdCtrls;

type
  TMainForm = class( TBaseForm )
    Edit1: TEdit;
  private
  protected
    procedure DoLoadSettings( Settings: TBinaryReader ); override;
    procedure DoStoreSettings( Settings: TBinaryWriter ); override;
  public

  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}
{ TMainForm }

procedure TMainForm.DoLoadSettings( Settings: TBinaryReader );
begin
  inherited;
  Top := Settings.ReadInteger;
  Left := Settings.ReadInteger;
  Height := Settings.ReadInteger;
  Width := Settings.ReadInteger;
  Edit1.Text := Settings.ReadString;
end;

procedure TMainForm.DoStoreSettings( Settings: TBinaryWriter );
begin
  inherited;
  Settings.Write( Top );
  Settings.Write( Left );
  Settings.Write( Height );
  Settings.Write( Width );
  Settings.Write( Edit1.Text );
end;

end.
Aber so schön Clean das auch ist, es löst nicht das eigentliche Problem!

Ein Anfang ist es aber schon mal ;)

bernau 29. Jul 2015 16:02

AW: Formular Position speichern
 
Rofl

uligerhardt 29. Jul 2015 16:05

AW: Formular Position speichern
 
Zitat:

Zitat von Mavarik (Beitrag 1310139)
Es Fehlt dann nur noch die Überprüfung ob der Monitor noch existiert...

Besonders Interessant, wenn der User per Datensicherung die Daten auf einen anderen PC/Laptop übertragen will...

Sollten die Daten 1. Computernamen bezogen gespeichert werden und bei laden getestet werden ob es die Top/Left Positions auf dem aktuellen Computer gibt...

Dafür gibt's unter Windows MSDN-Library durchsuchenGetWindowPlacement/MSDN-Library durchsuchenSetWindowPlacement.

Mikkey 29. Jul 2015 16:23

AW: Formular Position speichern
 
Zitat:

Zitat von Sir Rufo (Beitrag 1310201)
Aber so schön Clean das auch ist, es löst nicht das eigentliche Problem!

Auch darin lassen sich bis zu 15 Codezeilen zählen.

SCNRT

Mavarik 29. Jul 2015 16:38

AW: Formular Position speichern
 
Zitat:

Zitat von uligerhardt (Beitrag 1310203)
Zitat:

Zitat von Mavarik (Beitrag 1310139)
Es Fehlt dann nur noch die Überprüfung ob der Monitor noch existiert...

Besonders Interessant, wenn der User per Datensicherung die Daten auf einen anderen PC/Laptop übertragen will...

Sollten die Daten 1. Computernamen bezogen gespeichert werden und bei laden getestet werden ob es die Top/Left Positions auf dem aktuellen Computer gibt...

Dafür gibt's unter Windows MSDN-Library durchsuchenGetWindowPlacement/MSDN-Library durchsuchenSetWindowPlacement.

Und was soll das bringen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:45 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz