상세 컨텐츠

본문 제목

클래스 핼퍼를 이용하여 디버깅하기

프로그래밍/Delphi

by ryujt 2019. 11. 23. 12:05

본문

델마당에 올라온 질문에 답하기위해서 오랫만에 블로그에 글을 남겨 봅니다.

질문 내용은 아래와 같습니다.
https://www.delmadang.com/community/bbs_view.asp?bbsNo=17&bbsCat=0&indx=457334&page=1

저의 제안은 클래스 핼퍼를 이용해서 SetFocus를 덮어 써서 자신의 이름을 화면에 표시하는 것입니다. 문제는 SetFocus가 덮어써져서 실제 포커스를 이동하는 기능이 정지되는 것인데요, 이렇게 되면 Invisible 상태에서도 에러가 발생하지 않습니다. 그래서 원래의 SetFocus 코드를 가져와서 그대로 실행해주는 것을 덧 붙였습니다.

unit Unit1;

interface

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

type
  TGetFocusControl = class helper for TWinControl
  public
    procedure SetFocus;
    procedure NewSetFocus;
  end;

  TForm1 = class(TForm)
    Panel1: TPanel;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1.SetFocus;
  Edit2.SetFocus;
end;

{ TGetFocusControl }

[UIPermission(SecurityAction.InheritanceDemand, Window=UIPermissionWindow.AllWindows),
UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
procedure TGetFocusControl.NewSetFocus;
var
  Parent: TCustomForm;
begin
  Parent := GetParentForm(Self);
  if Parent <> nil then
    Parent.FocusControl(Self)
  else if ParentWindow <> 0 then
    Winapi.Windows.SetFocus(Handle)
  else
    ValidParentForm(Self);
end;

procedure TGetFocusControl.SetFocus;
begin
  ShowMessage(Name);
  NewSetFocus;
end;

end.

 

만약 디버깅해야 할 유닛이 너무 많아서 일일히 핼퍼 코드를 복사하기가 싫다면, 별도의 유닛을 만들어서 포커스 때문에 문제가 되는 콤포넌트들을 모두 아래처럼 수정하시면 됩니다.

unit NewWinControl;

interface

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

type
  TEdit = class (Vcl.StdCtrls.TEdit)
  private
  public
    procedure SetFocus; override;
  end;

implementation

{ TNewWinControl }

procedure TEdit.SetFocus;
begin
  ShowMessage(Name);
  inherited;
end;

end.

 

이제 필요한 유닛마다 uses 맨 앞에 방금 만든 유닛을 추가해주시면 됩니다.

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1.SetFocus;
end;

end.

관련글 더보기