TEdit에 MouseClick으로 Focus이동시 Text 전체선택 하기
TEdit의 Text를 전체선택하려면..
- Double-Click하면되구
- Tab으로 Focus를 옮겨도 되구
- Ctrl+A 클릭해도 되구
- Caret 처음이나 끝에 두고 Shift+End 또는 Shift+Home을 클릭해도 되죠
Mouse-click으로 Edit의 Focus를 이동할때 전체가 선택되지는 않습니다.
별것 아닌데, 별난 고객이 요구할수도 있죠.
개인적으로 예전에 그런 경험이 있었구요
또 커뮤니티에 그런 질문이 올라오기도 해서 만들어 봤습니다.
Edit의 Text 전체 선택 함수
TEdit의 전체 Text를 선택하는 함수는 SelectAll()이라고 있습니다.
Edit1->SelectAll();
위와같이 쓰면 되죠.
그런데 MouseClick으로 Edit에 Focus가 오는 시점에만 SelectAll해야하는데..
그시점을 잡기가 힘들죠
TEdit의 OnEnter 이벤트가 바로 그시점인데
이상하게 아래와 같이 OnEnver이벤트에 SelectAll해보면 되지가 않습니다.
void __fastcall TForm1::Edit1Enter(TObject *Sender)
{
Edit1->SelectAll();
}
//---------------------------------------------------------------------------
WM_LBUTTONDOWN 메세지에 해도 문제가 됩니다.
FOCUS가 이미 와 있는 상태에서 CARET를 이동하고자 마우스를 클릭할때 SelectAll이 되지 말아야 하니까요
TEdit에 MouseClick으로 Focus이동시 Text 전체선택 하기
그래서 OnEnter이벤트에 PostMessage를 이용해 구현해 보았습니다.
void __fastcall TForm1::Edit1Enter(TObject *Sender)
{
PostMessage(Handle,WM_USER+1,0,0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::EditSelectAllMsgProc(TMessage &Msg)
{
Edit1->SelectAll();
}
위와같이 하니 잘되네요
다음은 델파이 버젼
procedure TForm1.Edit1Enter(Sender: TObject);
begin
PostMessage(Handle,WM_USER+1,0,0);
end;
procedure TForm1.EditEnter(var Msg: TMessage);
begin
Edit1.SelectAll;
end;
여러개의 Edit에 적용하기
근데 만약 Form에 Edit가 여러개인경우 어떻게 구현해야할까요?
일일이 Edit에 OnEnter이벤트를 위와같이 걸어서 구현하면 되겠지만.. 좀 그렇죠..
다음과 같이 여러개의 Edit를 하나함수에 OnEnter이벤트 핸들러를 걸어서
구현하면 좀더 심플하겠죠
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Edit1->OnEnter=EditOnEnter;
Edit2->OnEnter=EditOnEnter;
Edit3->OnEnter=EditOnEnter;
Edit4->OnEnter=EditOnEnter;
Edit5->OnEnter=EditOnEnter;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::EditOnEnter(TObject *Sender)
{
PostMessage(Handle,WM_USER+2,(WPARAM)Sender,0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::EditSelectAllMsgProcEx(TMessage &Msg)
{
TEdit *edt=(TEdit *)Msg.WParam;
if(edt) edt->SelectAll();
}
//델파이 버젼
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.OnEnter:=EditOnEnter;
Edit2.OnEnter:=EditOnEnter;
Edit3.OnEnter:=EditOnEnter;
Edit4.OnEnter:=EditOnEnter;
Edit5.OnEnter:=EditOnEnter;
Edit6.OnEnter:=EditOnEnter;
end;
procedure TForm1.EditOnEnter(Sender: TObject);
begin
PostMessage(Handle,WM_USER+2,cardinal(Sender),0);
end;
procedure TForm1.EditSelectAllMsgProcEx(var Msg: TMessage);
var
edt: TEdit;
begin
edt:= TEdit(Msg.WParam);
if Assigned(edt) then edt.SelectAll;
end;
여러개의 Edit에 적용하기 2
근데 TEdit에 일일이 OnEnter이벤트를 거는게 불편하네요
Design-time에 Envent를 연결하는것은 더욱 불편할것 같구..
VCL소스를 보니 CM_ENTER 메시지가
TCustomForm의 SetFocusedControl 함수에서 Send하는군요
그래서 SetFocusedControl 함수를 override하여서 다음과 같이
더욱간단해 지네요
//CBuilder
bool __fastcall TForm1::SetFocusedControl(TWinControl *Control)
{
bool rslt=TCustomForm::SetFocusedControl(Control);
if(Control->InheritsFrom(__classid(TEdit)))
{
PostMessage(Handle,WM_USER+2,(WPARAM)Control,0);
}
return rslt;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::EditSelectAllMsgProcEx(TMessage &Msg)
{
TEdit *edt=(TEdit *)Msg.WParam;
if(edt) edt->SelectAll();
}
//---------------------------------------------------------------------------
//델파이
function TForm1.SetFocusedControl(Control: TWinControl): Boolean;
begin
Result:=Inherited SetFocusedControl(Control);
if Control is TEdit then
begin
PostMessage(Handle,WM_USER+2,cardinal(Control),0);
end;
end;
procedure TForm1.EditSelectAllMsgProcEx(var Msg: TMessage);
var
edt: TEdit;
begin
edt:= TEdit(Msg.WParam);
if Assigned(edt) then edt.SelectAll;
end;
그럼...
Edit 컴퍼넌트에 매소드인데요.
이것을 사용 하실 때도 함수 사용전에 반드시 SelectAll()을 해줘야 합니다.
Select 영역이 없으면 클립보드로 복사가 안 되더군요 ㅡㅡㅋ