트위터위젯


iframe 과 activeX를 동시에 써서 발생한 문제점 Programmer Life

activex 를 만들다보니 여러가지 상황에 놓이게 되는 경우가 많네요. 일단 iframe 과 activex 를 같은 화면에 올려놓고 사용하는 경우가 발생했습니다.

iframe 은 사이즈가 변경되거나 iframe의 내부 코드가 변경되었을 때 상위 부모에 자신의 사이즈가 변경되었으니 전체적으로 화면을 변경해달라는 이벤트를 발생시키나봅니다. 근데 이 사이즈 조절 이벤트가 발생되면 같이 있던 activex 에도 그 이벤트가 전달이 되겠죠. 그럼 activex 은 화면을 다시 그리기 위해 invalidate 할테고 그러면 그려져있는 이미지들을 다시 그리게 되니 화면이 번쩍이게 됩니다.

또 한가지, iframe 에서 marqee 같은거 써주면 계속 이벤트가 발생돼서 activex 아 화면을 그리는데만 쓰는 자원 소모가 심각하게 많아지게 됩니다. 그래서 여기 저기 찾아서 검색해본 결과 다음과 같은 답이 있었답니다.

일단 activex control class 에 다음 메소드를 상속받아 추가합니다.

virtual BOOL OnSetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect);

그리고 소스코드에 다음을 복사해서 붙여넣으면 해결됩니다.

void AFXAPI MyGetClippingCoordinates(LPCRECT pPosRect, LPCRECT pClipRect,
                                     LPRECT pIntersectRect, LPPOINT pOffsetPoint)
{
    int clipLeft = 0;
    int clipTop = 0;

    if ((pClipRect == NULL) || IsRectEmpty(pClipRect))
    {
        CopyRect(pIntersectRect, pPosRect);
    }
    else
    {
        IntersectRect(pIntersectRect, pPosRect, pClipRect);
        clipLeft = pClipRect->left;
        clipTop = pClipRect->top;
    }

    pOffsetPoint->x = min(0, pPosRect->left - clipLeft);
    pOffsetPoint->y = min(0, pPosRect->top - clipTop);
}

BOOL CTmtMDICtlCtrl::OnSetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
    ASSERT(lprcPosRect != NULL);

    // Remember the position rectangle for later
    m_rcPos = *lprcPosRect;

    // Calculate complete rectangle including the tracker (if present)
    CRect rectPos = m_rcPos;
    if (m_bUIActive && m_pRectTracker != NULL)
    {
        // Save new clipping rectangle (for DestroyTracker)
        if (lprcClipRect != NULL)
            m_pRectTracker->m_rectClip = *lprcClipRect;

        // Adjust tracker rectangle to new dimensions
        CRect rectTmp = rectPos;
        rectTmp.OffsetRect(-rectTmp.left, -rectTmp.top);
        m_pRectTracker->m_rect = rectTmp;

        // Adjust the "true" rectangle to include handles/hatching
        UINT nHandleSize = m_pRectTracker->m_nHandleSize - 1;
        rectPos.InflateRect(nHandleSize, nHandleSize);
    }

    // Now clip that rectangle as appropriate
    CRect rectClip;

    // CHANGE - call your own copy of _GetClippingCoordinates
    MyGetClippingCoordinates(rectPos, lprcClipRect, rectClip, &m_ptOffset);

    // Move outer window first. then inner window

    if (!m_bInPlaceSiteWndless)
    {
        CWnd* pWndOuter = GetOuterWindow();

        //BEGIN CHANGE
        if (pWndOuter != NULL)
        {

            //        ::MoveWindow(pWndOuter->m_hWnd, rectClip.left, rectClip.top,
            //            rectClip.Width(), rectClip.Height(), TRUE);
            ::MoveWindow(pWndOuter->m_hWnd, rectPos.left, rectPos.top,
                rectPos.Width(), rectPos.Height(), TRUE);
        }
        //END CHANGE                               
        if (pWndOuter != this)
            MoveWindow(m_ptOffset.x, m_ptOffset.y, rectPos.Width(), rectPos.Height());
    }

    return TRUE;
}

이 동작은 activeX 에 리사이즈 하라는 이벤트가 전달 됐을 때 실제 호출자가 IE 인지 아니면 다른 녀석인지를 분간해서 IE 일 경우에만 화면을 resize 하는 코드입니다. 구굴신님 감사해요.

트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://junpp.egloos.com/tb/2264928 [도움말]

덧글

댓글 입력 영역