パスワード漏洩防止_サブクラス化

6981 ワード

unit Unit1;

interface

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

type
  TMyEdit=class(TEdit)
    private
    public
      procedure DefaultHandler(var Message); override;
  end;

  TForm1 = class(TForm)
    edt1: TEdit;
    lbl1: TLabel;
    lbl2: TLabel;
    btn1: TButton;
    lbl3: TLabel;
    lbl4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    myEdit:TMyEdit;
  end;

var
  Form1: TForm1;



implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  myEdit:= TMyEdit.Create(nil);

  myEdit.Parent:= Form1;
  myEdit.Left:= edt1.Left;
  myEdit.Top:= lbl2.Top;
  myEdit.Width:= edt1.Width;
  myEdit.PasswordChar:= '#';
  myEdit.Visible:= true;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if myEdit<>nil then
    FreeAndNil(myEdit);
end;


{ TMyEdit }

procedure TMyEdit.DefaultHandler(var Message);
begin
  //inherited;
  if (csDesigning in ComponentState)or(csCreating in ControlState) then
    inherited
  else
  begin
    with Tmessage(message) do
    begin
      case Msg of
        WM_GETTEXT,EM_SETPASSWORDCHAR:inherited;
      else
        inherited;
      end;
    end;
  end;
end;


procedure TForm1.btn1Click(Sender: TObject);
var
  pBuffer,pBuffer2:pchar;
  iLen,iLen2:Integer;
begin
  ilen:= GetWindowTextLength(edt1.Handle);
  GetMem(pBuffer,ilen+1); //ascii    '\0'  

  ilen2:= GetWindowTextLength(myEdit.Handle);
  GetMem(pBuffer2,ilen2+1);
  try
    SendMessage(edt1.Handle,WM_GETTEXT,iLen+1,Integer(pBuffer));
    lbl3.Caption:= StrPas(pBuffer);


    SendMessage(myEdit.Handle,WM_GETTEXT,iLen2+1,Integer(pBuffer2));
    lbl4.Caption:= StrPas(pBuffer2);
  finally
    FreeMem(pBuffer);
    FreeMem(pBuffer2);
  end;
end;
end.