C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[901] [Controls] TEdit에 MouseClick으로 Focus이동시 Text 전체선택 하기
장성호 [nasilso] 10961 읽음    2009-07-02 01:31
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;




그럼...
아제나 [azena]   2009-07-03 13:49 X
Edit 컴퍼넌트 안에 내용을 클립보드에 담고 싶을 때 사용하는 CopyToClipboard() 라는 함수가 있습니다.
Edit 컴퍼넌트에 매소드인데요.
이것을 사용 하실 때도 함수 사용전에 반드시 SelectAll()을 해줘야 합니다.
Select 영역이 없으면 클립보드로 복사가 안 되더군요 ㅡㅡㅋ
장성호 [nasilso]   2009-07-03 16:16 X
그렇네요
procedure TCustomEdit.CopyToClipboard;
begin
  SendMessage(Handle, WM_COPY, 0, 0);
end;

TEdit 의 CopyToClipboard()  함수는 그냥 Ctrl+C 랑 똑같네요.

그냥 CopyToClipboard() 함수를 쓰면 TEdit의 Select된것과 상관없이 Text전체를
ClipBoard로 copy하도록 만들어 뒀으면 더 유익할것 같은데..

아루스 [tinydew4]   2010-07-19 15:08 X
Clipboard()->AsText 를 쓰면 SelText 에 영향을 주지 않고 복사가 되겠지요.

+ -

관련 글 리스트
901 [Controls] TEdit에 MouseClick으로 Focus이동시 Text 전체선택 하기 장성호 10961 2009/07/02
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.