본문 바로가기

old drawer/C, C++, MFC

[MFC]웹브라우저 컨트롤 호스팅시 스크립트 실행 안되게 하기

웹브라우저 컨트롤을 이용한 어플리케이션을 제작하거나

MSHTML을 이용하여 HTML을 파싱하는 등의 경우에

필요에 따라 웹 페이지의 스크립트를 꺼야 하는 경우가 있습니다.

 

제 생각에, 이걸 편하기 하기 위해 제공되는게

IDocHostUIHandler::GetHostInfo 메소드인 것 같더군요.

VC++ 7 이상에는 MFC CHtmlView에 IDocHostUIHandler 처리 기능이 추가됐기 때문에

그냥 메소드 하나 오버라이드하여 손쉽게 처리할 수 있습니다.

이 내용은 자료실에서 제 ID로 검색해 보시면 찾으실 수 있습니다.

 

그런데 제 기억으로는 IE 6.0일 때 이 방법을 테스트 해본 것 같고.. 그때 정말 스크립트가 실행 안됐던 것 같은데

지금 다시 해보니 전혀 안 먹더군요.

아무리 해도 스크립트 실행을 막을 수 없었습니다.

IE 6 SP1이 나오면서 바뀐건지.. 그때 실수한 것인지.. 잘 모르겠더군요.

 

아무튼 그래서 다시 해결책을 찾다가 좋은 방법을 알게 되었습니다.

http://support.microsoft.com/?id=266343

 

이 글을 보시면 되는데요,

그러니까 웹브라우저 컨트롤이 컨트롤 컨테이너에게 ambient 프로퍼티를 물어볼 때

스크립트 실행 안되게 지정할 수 있다는 얘깁니다.

 

그리고 CWnd 클래스에 보면 OnAmbientProperty 라는 메소드가 virtual로 제공되기 때문에

(VC 7 이상 기준)

아주 편하게도 처리할 수 있죠.

 

아래 헤더 추가 후...

#include < AFXOCC.H >
#include < MSHTMDID.H >

 

아래와 같은 메소드 하나만 정의해주면 스크립트 끄기가 가능합니다.

BOOL CXBView::OnAmbientProperty(COleControlSite* pSite, DISPID dispid, VARIANT* pvar)

{

    if (pvar && dispid == DISPID_AMBIENT_DLCONTROL) {

        V_VT(pvar) = VT_I4;

        V_I4(pvar) =

            DLCTL_DOWNLOADONLY |

            DLCTL_NO_JAVA |

            DLCTL_NO_SCRIPTS |

            DLCTL_NO_DLACTIVEXCTLS |

            DLCTL_NO_RUNACTIVEXCTLS |

            0;

    }

    return TRUE;

}

 

(* 스크립트 자체만 끌 수도 있을 것 같은데 그냥 예제 코드를 그대로 베꼈습니다.)

 

데모 프로그램 소스 프로젝트(VC 7.1)와

빌드된 exe를 첨부했습니다.

 

수정:

OnAmbientProperty 메소드 구현에서 부모 클래스 메소드를 호출해줘야 되는데 잘못했네요.

죄송합니다. 대충하다 보니...

BOOL CXBView::OnAmbientProperty(COleControlSite* pSite, DISPID dispid, VARIANT* pvar)

{

    if (pvar && dispid == DISPID_AMBIENT_DLCONTROL) {

        V_VT(pvar) = VT_I4;

        V_I4(pvar) =

            DLCTL_DOWNLOADONLY |

            DLCTL_NO_JAVA |

            DLCTL_NO_SCRIPTS |

            DLCTL_NO_DLACTIVEXCTLS |

            DLCTL_NO_RUNACTIVEXCTLS |

            0;

        return TRUE;

    } else {

        return CHtmlView::OnAmbientProperty(pSite, dispid, pvar);

    }

}

 

이런 식으로 해야 겠죠.

 

 

수정2:

... 그림, 이미지 등도 보이게.. 그러니까 스크립트 빼고 나머지는 거의 제대로 나오게 하려면

BOOL CXBView::OnAmbientProperty(COleControlSite* pSite, DISPID dispid, VARIANT* pvar)

{

    if (pvar && dispid == DISPID_AMBIENT_DLCONTROL) {

        V_VT(pvar) = VT_I4;

        V_I4(pvar) =

            DLCTL_DLIMAGES|

            DLCTL_VIDEOS|

            DLCTL_BGSOUNDS|

            DLCTL_NO_SCRIPTS|

            0;

        return TRUE;

    } else {

        return CHtmlView::OnAmbientProperty(pSite, dispid, pvar);

    }

}

이런식으로 하면 되죠.

자세한 내용은 mshtmdid.h를 참고하세요.