Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   TEdit (FMX) pastefromClipboard verhindern (https://www.delphipraxis.net/209224-tedit-fmx-pastefromclipboard-verhindern.html)

AndreasSt 12. Nov 2021 10:47

TEdit (FMX) pastefromClipboard verhindern
 
Hallo,
Ich möchte in einem TEdit verhindern dass eine Eingabe über die Zwischenablage möglich ist.
Das Event das da getriggert wird ist procedure TCustomEdit.PasteFromClipboard; in FMX.Edit
Kann ich das irgendwie ableiten oder gibt es andere Wege mein Ziel zu erreichen?
Es muss sowohl unter Windows als auch Android funktionieren.
vielen Dank

Rollo62 12. Nov 2021 15:01

AW: TEdit (FMX) pastefromClipboard verhindern
 
Man könnte das auf diese Art versuchen, indem man ein neues, StyledControl dafür anlegt.
Ich kombiniere sowas gerne mit Interposern, um dann dem Edit neue Funktionalität zu geben.
Ansonsten müsste man ein CustomControl anlegen, aber das ist mir zu viel Aufwand.
Man muss das mal mit allen Platformen Testen, das hier sollte erstmal mit Windows Ctrl-V funktionieren.


TStyledEditNoPaste
Delphi-Quellcode:
unit S4.FMX.Edit.Style;

interface

uses
    System.Classes
  , System.UITypes
  //
  , FMX.Edit.Style
  //
  , S4.FMX.Edit
  ;



//##
//## !! Custom Styled control
//##
type
     // custom Styled edit
     TStyledEditNoPaste = class( FMX.Edit.Style.TStyledEdit )
        private
            FPasteAllowed : Boolean;

        protected
            procedure KeyDown(var Key: Word; var KeyChar: System.WideChar; Shift: TShiftState); override;

        public
          constructor Create(AOwner: TComponent); override;

          property PasteAllowed : Boolean read FPasteAllowed write FPasteAllowed;
     end;








implementation

Uses
    FMX.Controls
  , FMX.Presentation.Style
  , FMX.Presentation.Factory
  ;



{ TStyledEditNoPaste }

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

    FPasteAllowed := True; // Default as normal Edit
end;

procedure TStyledEditNoPaste.KeyDown(var Key: Word; var KeyChar: System.WideChar; Shift: TShiftState);
var
    LIsCtrlOrCmd : Boolean;
begin

    LIsCtrlOrCmd := Shift * [ssCtrl, ssCommand] <> [];

    case Key of
      vkV:
          if LIsCtrlOrCmd then
          begin
              //Edit.PasteFromClipboard;
              if not FPasteAllowed then
              begin
                  //if KeyHandled then
                  Key    := 0;
                  KeyChar := #0;

                  Exit; //<====================================================
              end;
          end;
    end;


    inherited;
end;


initialization
    TPresentationProxyFactory.Current.Register(  'Edit-no-paste',             TStyledPresentationProxy< TStyledEditNoPaste > );

finalization
    TPresentationProxyFactory.Current.Unregister( 'Edit-no-paste',            TStyledPresentationProxy< TStyledEditNoPaste > );

end.

Ein Interposer TEdit, welcher die neue Funktionalität dabei hat
Delphi-Quellcode:
unit S4.FMX.Edit;

interface

uses
    System.SysUtils
  , System.Classes
  , System.UITypes
  , System.Types
  //
  , FMX.Types
  , FMX.Controls
  , FMX.Edit
  ;



//##
//## !! Class devive and override, to allow usage with fields in class helper
//##
type
     // type interposer for TEdit
     TEdit = class( FMX.Edit.TEdit )
  private
       function GetPasteAllowed             : Boolean;
       procedure SetPasteAllowed( const Value : Boolean );

     protected
        function DefinePresentationName                          : string; override;

     public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy;                   override;

        property PasteAllowed : Boolean read GetPasteAllowed write SetPasteAllowed;
     end;








implementation

Uses
    S4.FMX.Edit.Style
  ;



{ TEdit }

constructor TEdit.Create(AOwner: TComponent);
begin
    inherited;
end;


destructor TEdit.Destroy;
begin
    inherited;
end;


function TEdit.DefinePresentationName : string;
begin
    Result := 'Edit-no-paste';
end;


function TEdit.GetPasteAllowed : Boolean;
var
    LProxy : TStyledEditNoPaste;
    LCtrl : TControl;
begin
    Result := False;

    if not HasPresentationProxy then
    begin
        Exit;
    end;

    if not Assigned( Self.Presentation ) then
    begin
        Exit;
    end;

    if not ( Self.Presentation is TStyledEditNoPaste ) then
    begin
        Exit;
    end;

    LProxy := Self.Presentation as TStyledEditNoPaste;

    Result := LProxy.PasteAllowed;
end;

procedure TEdit.SetPasteAllowed( const Value : Boolean );
var
    LProxy : TStyledEditNoPaste;
    LCtrl : TControl;
begin

    if not HasPresentationProxy then
    begin
        Exit;
    end;

    if not Assigned( Presentation ) then
    begin
        Exit;
    end;

    if not ( Self.Presentation is TStyledEditNoPaste ) then
    begin
        Exit;
    end;

    LProxy := Self.Presentation as TStyledEditNoPaste;

    LProxy.PasteAllowed := Value;
end;


end.

Benutzt werden kann es dann so, wenn in den Uses der Interposer immer hinter den System-Units kommt,
dann kann die neue Funktion genutzt werden.
Das Edit kann normal im Designer benutzt werden, ist ja noch dasselbe,
ist jetzt nur um eine neue Funktionalität ergänzt.

Delphi-Quellcode:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.Memo.Types,
  FMX.ScrollBox, FMX.Memo, FMX.Edit
  //
  , S4.FMX.Edit     //<= INTERPOSER IMMER HINTER SYSTEM UNITS =================
  ;

type
  TForm1 = class(TForm)
    Layout1: TLayout;
    Button1: TButton;
    Memo1: TMemo;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
    Edit1.PasteAllowed := not Edit1.PasteAllowed; //<== NEUE FUNKTIONALITÄT ========

    if Edit1.PasteAllowed then
        Memo1.Lines.Insert( 0, 'Edit1 can paste '   + FormatDateTime( 'hh:nn:ss', Now ) )
    else
        Memo1.Lines.Insert( 0, 'Edit1 cannot paste ' + FormatDateTime( 'hh:nn:ss', Now ) );

end;

end.

Rollo62 12. Nov 2021 15:33

AW: TEdit (FMX) pastefromClipboard verhindern
 
Hab nochmal gerade in die System-Units reingeschaut,
das wird wohl unter Android daran scheitern dass in FMX.Edit.Style.pas "procedure DoPaste(Sender: TObject);" nicht virtuell ist.
Muss man dann notfalls eine lokale Kopie mit Patches anlegen, oder sonstwie hacken.

Ich bin mal gespannt ob es noch einfachere Lösungen gibt, ausser CustomControl,
das irgendwie mit RTTI zu mocken, oder sowas.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:20 Uhr.

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