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
[69630] Re:Re:Re: 이 또한 VCL 라이브러리를 멍청하게 만들어서 생긴 오류임
지나다가 [] 2845 읽음    2013-06-11 16:50
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 에 한글 텍스트를 넣고 포커스를 다른 컨트롤로 이동시 텍스트가 잘리는 문제? 장성호 2631 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: 지나가다님 답변이 정확한거 같네요 진호 2370 2013/06/11
69631                 Re:Re:Re:Re: 오호 지나다가님. 신기하게 잘됩니다 aa 2466 2013/06/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.