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

C++빌더 Q&A
C++Builder Programming Q&A
[69631] Re:Re:Re:Re: 오호 지나다가님. 신기하게 잘됩니다
aa [] 2465 읽음    2013-06-11 17:09
저도 2010 쓰고 있어서 지나다가님이 알려주신 방법대로 TApplication.ProcessMessage을
오버라이드 해서 컴파일해봤는데 잘되네요. 대단하시네요. 고수의 아우라가 팍팍 느꺼지는 





지나다가 님이 쓰신 글 :
: RAD 2010 VCL 라이브러리 소스를 보면
:
:
: function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
: var
:   Handled: Boolean;
:   Unicode: Boolean;
:   MsgExists: Boolean;
: begin
:   Result := False;
: 
:   MsgExists := PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);
: 
:   if MsgExists or PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then
:   begin
:     Unicode := (Msg.hwnd = 0) or IsWindowUnicode(Msg.hwnd);
: 
:     if not MsgExists then
:     begin
:       if Unicode then
:         MsgExists := PeekMessageW(Msg, 0, 0, 0, PM_REMOVE)
:       else
:         MsgExists := PeekMessageA(Msg, 0, 0, 0, PM_REMOVE);
:     end;
: 
:     if MsgExists then
:     begin
:       Result := True;
:       if Msg.Message <> WM_QUIT then
:       begin
:         Handled := False;
:         if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
:         if not IsPreProcessMessage(Msg) and not IsHintMsg(Msg) and
:           not Handled and not IsMDIMsg(Msg) and
:           not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
:         begin
:           TranslateMessage(Msg);
:           if Unicode then
:             DispatchMessageW(Msg)
:           else
:             DispatchMessageA(Msg);
:         end;
:       end
:       else
:       begin
:   {$IF DEFINED(CLR)}
:         if Assigned(FOnShutDown) then FOnShutDown(self);
:         DoneApplication;
:   {$IFEND}
:         FTerminate := True;
:       end;
:     end;
:   end;
: end;
: 

:
: 위와 같이 되어있는데,
:
: IME 와 Edit Control은 서로 별개의 윈도우 이기 때문에, Edit 콘트롤이 Focus Out 되는 것을 IME 윈도우 쪽에서는
: 알수 없어서, IME Completion 과정에서 발생하는 메세지 셋이 라우팅 될수 있도록 Message Dispatch 루틴을
: 만들 때 그런 부분을 고려했어야 하는데
:
: VCL 라이브러리 소스를 보면 마우스 이벤트에 대해 선행처리 한답시고 닭짓을 하고 있기 때문에 문제가 발생하는 것임.
:
:     if MsgExists then
:
: 윗부분의 코드를 걷어내고 다음과 같이 작성했더라면 전혀 질문에 언급된 문제가 발생하지 않았을 것임.
:
:
: function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
: var
:   Handled: Boolean;
:   Unicode: Boolean;
:   MsgExists: Boolean;
: begin
:   Result := False;
: 
:   if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then
:   begin
:     Unicode := (Msg.hwnd = 0) or IsWindowUnicode(Msg.hwnd);
:     if Unicode then
:       MsgExists := PeekMessageW(Msg, 0, 0, 0, PM_REMOVE)
:     else
:       MsgExists := PeekMessageA(Msg, 0, 0, 0, PM_REMOVE);
: 
:     if MsgExists then
:     begin
:       Result := True;
:       if Msg.Message <> WM_QUIT then
:       begin
:         Handled := False;
:         if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
:         if not IsPreProcessMessage(Msg) and not IsHintMsg(Msg) and
:           not Handled and not IsMDIMsg(Msg) and
:           not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
:         begin
:           TranslateMessage(Msg);
:           if Unicode then
:             DispatchMessageW(Msg)
:           else
:             DispatchMessageA(Msg);
:         end;
:       end
:       else
:       begin
: // 이하 생략
: 

:
: VCL 라이브러리 소스코드를 수정해서 사용하는 게 불편 하면
:
:
: void __fastcall TForm1::Edit1Exit(TObject *Sender)
: {
:          Application->ProcessMessages();
: }
: 

:
: 위와 같이 작성하면 됨.
:
:
:
:
:
:
: : 장성호 님이 쓰신 글 :
: : : Edit에 입력중에
: : : 코딩으로 강제로 Focus를 옮기며, 곧바로 입력중이던 Edit의 값을 읽어오면
: : : 그런현상이 발생합니다.
: : :
: : : [문제 원인]
: : : Edit1에 입력중인데..
: : :
: : :
: : :  Edit2->SetFocus(); 
: : :  String str=Edit1->Text;
: : :  // 이때 str에 내용은 아직 완성이 안된 문자열이 될수 있습니다
: : : 

: : :
: : : Edit1입력중에 다른 Control로 Focus를 강제로 옮기면
: : : Edit1에 Char완성메세지(WM_CHAR) 와 화면갱신메세지(WM_PAINT)가 발생하게 되는데..
: : : 님께서 Edit1의 Text를 읽어온것은 해당 메세지가 Edit1의 WindowProc에서 처리하기 전에 가져온것입니다.
: : :
: : :
: : : [해결방안]
: : : 다음과 같이
: : : Edit1의 Text를 읽기전 Edit1에서 처리해야할 메세지를 처리하고  Text를 읽으시면 됩니다.
: : : VCL함수중에 Application->ProcessMessages(); 메소드가
: : : 현재 어플리케이션  GUI 쓰레드의 메세지큐에 있는 메세지를 가져와서 처리해주는 함수 입니다.
: : :
: : :
: : : void __fastcall TForm8::Timer1Timer(TObject *Sender)
: : : {
: : : 	Edit2->SetFocus();
: : : 	Application->ProcessMessages(); //Edit1의 TEXT를 읽지전 Edit1에 발생되는 메세지를 처리 
: : : 	String str=Edit1->Text;
: : : 	Edit2->Text=str;
: : : }
: : : 

: : :
: : :
: : : 다른 방법
: : : 원리는 같은데요
: : : Application->ProcessMessages();  메소드는
: : : Edit1뿐만 아니라 모든 어플에서 발생하는 메세지가 처리됩니다.
: : : Edit1에 해상되는 메세지만 처리하고 싶다면 다음과 같이 해보세요
: : :
: : :
: : : void __fastcall MessageProcess(TWinControl *pCtrl)
: : : {
: : : 	TMsg Msg;
: : : 	bool MsgExists = PeekMessageW(&Msg, pCtrl->Handle, 0, 0, PM_REMOVE);
: : : 	while(MsgExists)
: : : 	{
: : : 		TranslateMessage(&Msg);
: : : 		DispatchMessageW(&Msg);
: : : 		MsgExists = PeekMessageW(&Msg, pCtrl->Handle, 0, 0, PM_REMOVE);
: : : 	}
: : : }
: : : //--------------------------------------------------------------------------
: : : void __fastcall TForm8::Timer1Timer(TObject *Sender)
: : : {
: : : 	Timer1->Enabled=false;
: : : 	Edit2->SetFocus();
: : : 	MessageProcess(Edit1); //Edit1에 발생하는 WM_CHAR메세지 처리 
: : : 	String str=Edit1->Text;
: : : 	Edit2->Text=str;
: : : }
: : : 

: : :
: : : 두번째 방법은 직접 메세지큐에서 메세지를 가져와서 처리하므로
: : : Application객체에서 발생하는 OnMessage등의 이벤트들이  발생하지 않습니다.
: : : 관련사항을 유의하시고 사용하셔야 합니다.
: : :
: : :
: : : 이상입니다.
: : :
: : : 그럼..
: : :
: : : 서치포림 님이 쓰신 글 :
: : : : 안녕하세요.
: : : :
: : : : 현재 C++Builder 2010 버전을 사용하고 있습니다.
: : : : 그런데 TEdit 에 텍스트를 넣고 마우스로 다른 컨트롤을 클릭하여 포커스를 이동하면 TEdit에 입력한 문자 중 마지막 글자가 사라집니다.
: : : : Edit 박스에는 마지막 글짜까지 표시되어 있는데 코딩으로 읽어보면 마지막 글자는 나타나지 않습니다.
: : : :
: : : : 예를들면, Edit1 에 "학용품" 라고 입력한 후에 마우스로 다른 컨트롤을 클릭하여 포커스를 이동한 후 코딩으로
: : : :
: : : : AnsiString sText = Edit1->Text;
: : : :
: : : : 위와 같이 하면,  sText 에는 "학용" 이라고 나옵니다.
: : : :
: : : : 즉 마지막 글자 입력 중에 포커스를 다른 데로 옮기면 조합중인 글자가 사라지는 문제가 발생합니다.
: : : :
: : : : 그런데 Edit1에는 원래 입력한 대로 "학용품"이라고 표시되어 있고, 포커스를 다시 Edit1으로 옮겼다가 다른 컨트롤로 옮기면 이번에는 정상으로 나옵니다.
: : : :
: : : : 그리고 포커스를 옮길 때 <Tab> 키를 쳐서 이동하면 괜찮은데, 마우스로 다른 컨트롤을 클릭하여 이동하면 이런 문제가 발생합니다.
: : : :
: : : : 이런 경우에 어떻게 해결해야 하나요?
: : : :
: : : : 코딩으로 Edit 박스를 빠져나갈 때 End 키나 Right 키를 강제로 입력하여 마지막 글자가 사라지는 문제를 해결할 수 있을까요?
: : : : 기초가 많이 부족하여 해결하기가 어렵네요.
: : : : 가능하면 방법 좀 부탁드립니다.

+ -

관련 글 리스트
69627 TEdit 에 한글 텍스트를 넣고 포커스를 다른 컨트롤로 이동시 텍스트가 잘리는 문제? 서치포림 2937 2013/06/11
69628     Re:TEdit 에 한글 텍스트를 넣고 포커스를 다른 컨트롤로 이동시 텍스트가 잘리는 문제? 장성호 2630 2013/06/11
69629         Re:Re:TEdit 에 한글 텍스트를 넣고 포커스를 다른 컨트롤로 이동시 텍스트가 잘리는 문제? 서치포림 2278 2013/06/11
69630             Re:Re:Re: 이 또한 VCL 라이브러리를 멍청하게 만들어서 생긴 오류임 지나다가 2845 2013/06/11
69632                 Re:Re:Re:Re: 지나가다님 답변이 정확한거 같네요 진호 2369 2013/06/11
69631                 Re:Re:Re:Re: 오호 지나다가님. 신기하게 잘됩니다 aa 2465 2013/06/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.