Q&A

  • 델로 ActiveX 를 사용중 Tab 키가 작동되지 않음
멀티프로그램 - 서버와 연결은 TSocket 으로 연결
서버프로그램:ADOConnect, ADODataSet, Provider 컴포넌트 사용
클라이언트 : TClientDataSet, AciveX, TDBGride, TDBEdit 사용

빈 폼에 TWebBrowser 컴포넌트를 올려놓고
  Form1.WebBrowser1.Navigate('http://' + _home +'/Test_ActiveX.htm');
로 코딩후 프로그램을 실행함

문제는 ActiveX 폼의 KeyPreview 를 True로 하였는데, Tab로 이동시 포커스가 다음으로 이동하지 않고 사라져 버립니다. TDBEdit (TabStop 은 True로 하였음) TabOrder 순서대로 포커스가 이동을 해야 하는데 왜 다음으로 이동을 하지 않는지??????

제발 답변부탁합니다.
델파이에서 ActiveX 를 작성하여 TWebBrowser 컴포넌트의 Navigate 로 연결을 하면 Tab 가 작동되지 않는게 정상인지,  아니면 다른 방법이 있는지...
아휴 왜 되질 않지??.  
==> DBEdit1 의 onExit 이벤트에 DBEdit2.setFocus 를 하여도 Focus가 잡히질 않음

아무도 참고가 될만한 답변이 없어서 다시 질문을 합니다.
1  COMMENTS
  • Profile
    강성만 2003.06.10 01:10


    휴 겨우 원하는 자료를 검색해서 찾았어요.  아래는 민성기님의 팁입니다. 참고하세요. 원인은 ActiveX 가 아니라 TWebBrowser 에서 지원을 하지 않더군요.


    민성기 입니다.
    델코의 팁란에 관련 게시물이 있습니다.
    http://www.delphikorea.com/board/zboard/view.php?id=lecture&page=1&sn1=&divpage=1&sn=on&ss=on&sc=on&select_arrange=headnum&desc=asc&no=348
    이 소스는 어플 실행하고 처음 입력하는 엔터키나 탭키가 동작하지 않는다는
    문제가 있습니다. 수정해서 어딘가에 써먹었는데... 워낙 오래전이라 찾을
    수가 없구먼요... 초기 동작시 FOleInPlaceActiveObject의 값이 nil이기
    때문에 생기는 문제라는 것만 기억이 납니다용... 적당히 고쳐 쓰세요~~ ^^;
    그럼...



    <소스는>==> 민성기님이 작성한 내용 입니다.

    ----------------------------------------------------------------------
    이 글의 모든 권한은 저자에게 있으며 저자와 협의 없이 인용
    또는 다른 게시판에 등록 하실 수 없습니다.
    ----------------------------------------------------------------------

    OCX로 제공되는 MS의 IE컨트롤을 델파이의 폼에 낑궈넣으면, 브라우징하는
        웹페이지에서 엔터키와 탭키가 동작하지 않는 경우가 있습니다.
        델파이 어플리케이션의 다이얼로그 메시지 처리가 표준적인 윈도우의 그것과 차이가 나기 때문에 생기는 현상이라고 하는군요...
    완벽하진 않지만, 비슷한 해결방법을 찾아서 적어봅니다.

    Uses구문에 ActiveX를 포함시키고 폼의 Private영역에 다음과 같이 선언하세요...

    private
    FOleInPlaceActiveObject: IOleInPlaceActiveObject;
    procedure MessageLoop(var Msg: TMsg; var Handled: Boolean);



    MessageLoop 프로시저는 다음과 같이 만들어주세요.
    procedure TForm1.MessageLoop(var Msg: TMsg; var Handled: Boolean);
    const
       DialogKeys: set of Byte
         = [VK_TAB, VK_RETURN, VK_DELETE, VK_EXECUTE,    VK_ESCAPE,     VK_CANCEL,
    VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_F10];
    MSJVMClassName = 'MSAWT_Comp_Class'; // for Java Applets
    var
      iOIPAO : IOleInPlaceActiveObject;
      Dispatch: IDispatch;
      Str : String;
    begin
      if (WebBrowser1 <> nil) and
         ((Msg.Message = WM_KEYDOWN) or (Msg.Message = WM_KEYUP)) and
         (Msg.wParam in DialogKeys) then
      begin
        Handled := IsDialogMessage(WebBrowser1.Handle, msg) = True;
        SetLength(Str, MAX_PATH);
        GetClassName(Msg.hwnd, PChar(Str), MAX_PATH);
        SetLength (Str, StrLen (PChar(Str)));
        
        if (Msg.wParam = VK_DELETE) and (Str = MSJVMClassName) then
        else
         if Handled then
            if FOleInPlaceActiveObject <> nil then
               FOleInPlaceActiveObject.TranslateAccelerator(Msg)
            else
            begin
               Dispatch := WebBrowser1.Application;
               if Dispatch <> nil then
               begin
                  Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
                  if iOIPAO <> nil then
                  FOleInPlaceActiveObject := iOIPAO;
               end;
            end;
       end
       else
          Handled := False;
    end;

    이제, Form의 OnCreate 이벤트에서 이 메시지루프를 어플리케이션의 메시지루프에 할당합니다.

    procedure TForm1.FormCreate(Sender: TObject);
    begin
       Application.OnMessage := MessageLoop;
    end;

    위의 기법은, 델파이로 만든 엑티브X컨트롤에서 탭키나 엔터키가 동작하지 않는 경우에도 적용됩니다.
    그럼...