|
2009년 02월 22일
예전에 ActiveX Control을 이용해서 차트 컨트롤을 개발한 적이 있었습니다. ActiveX control에 올라간 Edit control에 키보드 입력을 통해 좌표를 입력하면 차트가 입력한 좌표에 따라 변화 하는 기능을 추가할때였는데 도통 키보드 메시지가 받아지지 않았습니다. 당근, 문제를 해결하기는 했으나 그 문제에 대해 문서화를 시켜 놓지 않았더니 같은 문제가 최근에 발생했을때 다시 삽질을 해댔지 뭡니까!! 문서화의 중요성 다시 한 번 마음에 새기게 됩니다. ㅡㅡ;; ![]() 아래는 이 문제에 대한 Microsoft 고객지원 사이트의 기술문서 링크입니다. MFC ActiveX Control in IE Doesn't Detect Keystrokes 그럼, 위 기술문서를 통해 이 문제를 해결하는 방법에 대해서 하나씩 알아보도록 하겠습니다. SYMPTOMS Accelerator keys, such as ARROW keys, are first received by the message pump of the ActiveX control's container. Even if the control has the focus, it does not receive messages for keystrokes that have special meaning to control containers, such as ARROW and TAB keys. MFC ActiveX controls have a chance to intercept these messages by overriding their PreTranslateMessage function. However, PreTranslateMessage is not always called for an MFC ActiveX control. 증상 화살표키와 같은 엑셀레이터 키들은 ActiveX control's container의 메시지 펌프로 처음 전달 됩니다. 비록 control이 포커스를 받고 있다고 하더라도 키보드 메시지는 control로 전달되어지지 않습니다. MFC ActiveX control들은 이러한 키보드 메시지를PreTranslateMessage 함수를 오버라이딩 하므로써 키보드 메시지를 가로챌 수 있습니다. 그러나, PreTranslateMessage는 MFC ActiveX control에서는 항상 호출 되지 않습니다. CAUSE PreTranslateMessage in an MFC ActiveX control is called by the TranslateAccelerator method of the IOleInPlaceActiveObject interface of the control. Internet Explorer only calls this method for the control that is currently UI-Active. Only one control can be UI-Active at a time. Internet Explorer does not automatically UI-Activate any controls when a page is first loaded. Internet Explorer waits until the user tabs to an ActiveX control on the page to UI-Activate it. Also, MFC ActiveX controls UI-Activate themselves when they are clicked with the mouse. In an MFC ActiveX control, this is done in COleControl::OnLButtonUp. If you have a child control inside your COleControl, mouse-click messages on the child control are not sent to the COleControl and MFC does not UI- Activate the ActiveX control, even though the child control has just been given the keyboard focus. Internet Explorer intercepts the keystrokes and does not give the control a chance to filter them in PreTranslateMessage. 원인 MFC ActiveX control의 PreTranslateMessage 함수는 control의 IOleInPlaceActiveObject interface의 TranslateAccelerator method에 의해서 호출 됩니다. Internet Explorer는 오직 현재 활성화 된 control을 위해 이 method를 호출합니다. 한 번에 오직 하나의 control만이 활성화 될 수 있습니다. Internet Explorer는 웹 페이지가 처음으로 로드되었을 때 어떠한 control들도 자동으로 활성화 시키지 않습니다. Internet Explorer는 사용자가 user tabs(이게 사용자가 탭키를 누르는것을 이야기하는건지 아니면 다른 의미가 있는건지 모르겠네요 ㅡㅡ??) 웹 페이지의 ActiveX control을 활성화 시킬때 까지 대기합니다. 또한, MFC ActiveX controls 마우스 클릭을 통해서도 활성화가 됩니다. MFC ActiveX control은 COleControl::OnLButtonUp 메시지가 완료되었을때 활성화 됩니다. 만약 당신의 COleControl이 내부에 child control (제가 소개한 클래스 다이어그램에서 CMyActiveXView에 해당합니다.)을 가지고 있고 마우스 이벤트가 child control에서 발생한다면 이 메시지는 COleControl에게 보내지지 않으며 MFC는 child control이 키보드 포커스를 가지고 있다고 하더라도 ActiveX control을 활성화 시키지 않습니다. Internet Explorer가 키보드 메시지를 가로채서 control이 PreTranslateMessage함수가 메시지를 가져올 기회를 주지 않기 때문입니다. RESOLUTION Here is a typical PreTranslateMessage. This code forwards ARROW, HOME, and END keys back to the control so that they can be received using a MESSAGE_MAP entry: // trap keys and forward on to the control BOOL CMyActiveXCtrl::PreTranslateMessage(MSG* pMsg) { switch (pMsg->message) { case WM_KEYDOWN: case WM_KEYUP: switch (pMsg->wParam) { case VK_UP: case VK_DOWN: case VK_LEFT: case VK_RIGHT: case VK_HOME: case VK_END: SendMessage (pMsg->message, pMsg->wParam, pMsg->lParam); // Windowless controls won't be able to call SendMessage. // Instead, just respond to the message here. return TRUE; } break; } return COleControl::PreTranslateMessage(pMsg); } 해결 아래 코드는 일반적인 PreTranslateMessage함수 입니다. 이 코드는 화살표, HOME, 및 END 키들을 control의 MESSAGE_MAP 항목을 사용하여 받아 사용할 수 있도록 전달합니다. 저 같은 경우는 Enter키와 Tab키에서 CEdit control의 값을 얻어와야 하므로 위 MS 기술문서의 코드를 아래와 같이 고쳐서 사용하였습니다. // trap keys and forward on to the control BOOL CMyActiveXCtrl::PreTranslateMessage(MSG* pMsg) { switch (pMsg->message) { case WM_KEYDOWN: case WM_KEYUP: switch (pMsg->wParam) { case VK_TAB: case VK_RETURN: pView->GetPoint(); return TRUE; } break; } return COleControl::PreTranslateMessage(pMsg); } If you have a child control within your ActiveX control, you need to UI-Activate the whole control whenever that child control is activated. For example, if you have an edit control inside your ActiveX control, add a handler as follows to your ActiveX control class: int CMyActiveXCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { if (!m_bUIActive) OnActivateInPlace (TRUE, NULL); // == UI-Activate the control return COleControl::OnMouseActivate(pDesktopWnd, nHitTest, message); } 만약 당신의 ActiveX control이 child control을 가지고 있다면, 모든 control이 활성화 될 때는 언제나 child control도 활성화 될 필요가 있습니다. 예를 들어 만약 당신의 ActiveX control 내부에 edit control이 있다면, 아래 핸들러를 당신의 ActiveX control 클래스에 추가합니다. Because Internet Explorer may not immediately UI-Activate a control, even if that is the only control on the page, it may be desirable to automatically request a UI-Activation when the control is created. This can be done during the COleControl::OnCreate (WM_CREATE) handler. Windowless controls do not get WM_CREATE or any windows messages; therefore, this code won't work in a windowless control. Also note that this does not guarantee that a control will remain UI-Activated. If there are other controls on a page that request UI-Activation in a similar manner, only one will eventually be UI-Activated and receive keystroke messages as described. And if the user TABs away from an ActiveX Control, Internet Explorer will automatically UI-deactivate the control. int CMyActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; OnActivateInPlace (TRUE, NULL); // == UI-Activate the control return 0; } Internet Explorer는 웹 페이지에 오직 control 뿐이라고 해도 즉시 control을 활성화 시키지 않기 때문에 control이 생성되자 마자 활성화 시키는 것이 바람직하다고 할 수 있겠습니다. 이 방법은 COleControl::OnCreate (WM_CREATE) handler를 통해서 구현 될 수 있습니다. 윈도우가 없는 control들은 WM_CREATE 또는 어떠한 윈도우 메시지도 받을 수 없기 때문에 윈도우가 없는 control의 경우 아래의 코드는 무의미합니다. 또한 이 코드가 control이 활성화를 유지하도록 보장하지는 않습니다. 만약 다른 control들이 웹 페이지 상에서 같은 방법으로 활성화 되었다면, 오직 하나만 마지막으로 활성화 될 것이고, 키보드 메시지를 받을 수 있을 것입니다. And if the user TABs away from an ActiveX Control, (해석이 안되네요 ㅡㅡ;;) Internet Explorer 자동으로 control을 활성화 시킬 것입니다. 위 방법대로 소스코드를 수정하고 테스트해 본 결과 아주 잘 동작을 합니다. 굳!! 이 글과 관련있는 글을 자동검색한 결과입니다 [?]
|
ABOUT
![]() 새로운 도전을 위해 약 1년간 자리를 비웁니다. 그 동안 블로그에 방문해 주신 분들께 진심으로 감사드립니다. 1년 뒤 .NET 관련 양질의 정보를 가지고 돌아오겠습니다. by greenfrog 메모장
카테고리
최근 등록된 덧글
잘 봤습니다. 그런데 저 상태에서 하얀..
by 비니 at 07/24 안녕하세요. 내용이 좋아서 참고합니다... by 김현수 at 07/09 1년뒤....너무 멀군요... 도전 성.. by rince at 06/26 좋은 내용이네요 많은 도움이 되었습니다.. by 이준배 at 06/04 좋은 정보 감사합니다^^ by 코즈 at 06/03 사랑합니다 by 최곱니다 at 05/12 좋은정보 감사합니다. by 이창열 at 05/11 좋은 정보 잘보고갑니다 그리고 제가 .. by Cherry at 04/27 답글이 늦어서 죄송합니다. 요즘 이래저.. by greenfrog at 04/20 좋은 정보 잘보고 갑니다^^ 도움이 많.. by 토끼 at 04/15 좋은 정보 감사합니다. 다음에 써먹어야.. by neptunex at 03/26 ㅎㅎ 잘 찾아보면 재미있는 플러그인 많.. by greenfrog at 03/22 예전에는 일부러 에러내고 그거찾아가는.. by 규학 at 03/13 아 ~ 그 일이었군요 ^^ 글 잘 봤어요 .. by greenfrog at 02/21 하나은행과 정말 생동감 넘쳤지요 ^^ by rince at 02/20 rince님의 생동감 넘치는 하루가 궁금.. by greenfrog at 02/20 어제, 그제 정말 생동감 넘치는 하루.. by rince at 02/19 저도 짬 비릴때 고참들이 웃기면 그것 .. by greenfrog at 02/19 전 자주 웃는 편이지요 ^^; 군대에선 .. by rince at 02/18 저도 이 만화 보고 어쩜 저런 생각 없는 .. by greenfrog at 02/17 최근 등록된 트랙백
자바로 작성된 프로그램 단 한번만 실..
by Start!!! 제 취향이 Oddly Enough와 안성맞.. by Oddly Enough 2009년 보기 시작하는 미드 by Pell's seer Blog [포토] 국민 여러분, 떡국 드시고 .. by Green Monkey Blog** MARVEL MOVIES : 아이언 맨 by 잠보니스틱스 ▶◀ 최진실씨, 삼가 고인의 명복을 .. by ** MY's kitchen ** 재미로 해보는 MBTI 검사 by A2공간 - 도움되는 글을 쓰자 러시아 극우조직 스킨헤드를 파헤친 기자 by Oddly Enough [Sleeping Through My Fingers].. by 바람나무, 생각가는대로 구글 크롬 안내서의 작지만 큰 실수 by Oddly Enough PETA, 돼지학대 농장 잠입취재 by Oddly Enough 병쭈니의 생각 by chrisjun82's me2DAY 준이아빠의 생각 by kkh1030's me2DAY 안철수가 말하는 "현대의 인재에.. by loading... 100% 이전블로그
이글루 파인더
|