.NET Framework에서 Internet Explorer와 연동하는 방법에 대한 모든 것

1. System.Windows.Forms.WebBrowser 컨트롤이 제공하는 것만으로는 턱없이 부족하다!


.NET Framework 2.0이 제공하는 새로운 컨트롤 (이라기보다는 우리가 기존에 사용해왔던 “Microsoft Web Browser” ActiveX 컨트롤에 대한 Wrapper 스타일의 컨트롤)인 System.Windows.Forms.WebBrowser는 여러모로 요긴하게 사용하는 곳이 많다. 하지만 이 컨트롤의 진짜 능력을 전혀 모르는 사람들이 의외로 많은것 같다.


이 컨트롤이 제공하는 멤버들 중 Document 프로퍼티와 Window 프로퍼티에 대해 관심있게 관찰할 필요가 있다. 물론 이것들 만으로도 원하는 일을 “어느 정도 수준”까지는 처리할 수 있겠다만 이것으로도 안되는 것은 너무 많다. (ExecCommand가 노출하는 API의 종류를 숙지하고 있는 사람들은 ExecCommand로는 택도 없다는 걸 안다. 그래서 IOleCommandTarget 형식을 얻어올 필요가 있다. 그리고 꼭 이런 이유 뿐만이 아니라 원래의 DOM 객체는 진정한 의미에서의 호환성 구현에 있어서 필요한 부분이다.)


웹 브라우저 컨트롤이 제공하는 멤버들 중 Dom- 이라는 접두어가 붙는 프로퍼티들은 모두 Microsoft.mshtml.dll 어셈블리와 관련이 있다. Microsoft.mshtml.dll 역시 Visual Studio 2005와 함께 제공되는 Primary Interop Assembly이다. 여기서 노출하는 인터페이스 또는 클래스로 형변환을 시도한 다음 이 객체를 활용하면 매우 풍부한 기능들을 맛볼 수 있다. (만약 Microsoft Windows를 기반으로 솔루션을 작성 중이라면 별도의 HTML 해석기를 찾아나설 이유가 없다.)


2. Microsoft.mshtml.dll을 배포할 때 필요한 것


이것을 모르면 상당히 많이 당황하게 되는 내용이다. 분명히 개발자 PC에서는 잘 돌아갔던 코드인데 왜 리테일에만 나가면 뻑뻑 나가떨어지는걸까… 이유는 간단하다. Microsoft.mshtml.dll은 regasm.exe 유틸리티로 등록을 해줄 필요가 있는 어셈블리이다. 만약 그래도 해결될 기미가 안보인다면 실행하는 PC의 소프트웨어 구성이 Internet Explorer 6.0보다 낮지는 않은지 확인해볼 필요가 있다. Visual Studio 2005 안에 포함된 MSHTML PIA의 경우 Internet Explorer 6.0 – 또는 – 7.0에 맞추어져있다. (특별히 최신 API를 사용하는 경우가 아니라면 5.0까지는 생각해 볼 수 있을 것이다.)


3. -Class 접미어가 붙는 형식이야말로 진짜배기


PIA를 쓰면서 제일 당황스럽다거나 어렵다고 하는 것은 PIA가 노출하는 타입의 수가 (물론 모두 그렇다고는 할 수 없겠으나 일반적으로 우리가 자주 고려하는 유명한 솔루션의 경우) 천문학적으로 많다. 나열 상수만 해도 Auto Naming으로 인하여 리스팅을 때려보면 눈앞이 어지러울 정도로 많다. 하지만 이런 방대한 라이브러리에 기죽을 필요는 전혀 없다. 오히려 진짜 모습을 알게되면 BCL보다 더 체계적이라는 사실에 새삼 감탄하게 된다.


우선 우리가 제일 먼저 찾고 싶어하는 Document.DomDocument에 대해서 먼저 생각해보면 결론은 이렇다. IHTMLDocument, IHTMLDocument2, IHTMLDocument3 등등 HTMLDocument를 설명하는 Interface나 Dispatch Interface의 수는 많다. 하지만 이것들을 모두 엮는 하나의 주체는 바로 HTMLDocumentClass 이다. HTMLDocumentClass 형식으로 Document.DomDocument가 반환하는 object 형식을 형변환시도해서 써보자. 놀랍게도 (사실 당연한것이지만) 올바르게 형변환이 일어나면서 우리가 원하는 “이상적인” 작업을 가능케 한다. 그 “이상적인” 작업 중의 하나를 살펴보자.


이렇게 가져온 DOM 객체의 실제를 이용하여 브라우저가 가지고 있는 이미지 목록을 한번에 얻어와 볼 수 있다. HTMLDocumentClass의 멤버들 중에 images 멤버를 찾아보자. IHTMLElementCollection 인터페이스 형식을 반환하고 있다. 하지만 이것의 멤버를 보면 그리 익숙하지도 않고 item 메서드는 어찌 사용해야 할 지 감이 금방 오지도 않는다. 파라미터 시그니처가 string, int 라는 점이 그리 좋아 보이지 않는 것이다. 하지만, 고민할 필요가 없다. 실제 구현을 살펴보면 ICollection을 구현하고 있는 게 보인다. 그렇다면 여기에 대한 답은? 당연히 foreach 구문이다! 그리고 foreach 구문에 제시할 형식으로 우리는 HTMLImgClass를 택하기만 하면 된다. 그리고 당연한 것이지만 HTMLImgClass를 통하여 각 이미지에 대한 정보는 물론 브라우저가 출력하는 컨텐트의 속성을 편집할 수도 있음은 물론이다.


그리고 DOM 객체가 노출하는 on 시리즈의 이벤트들은 Callback Function Pointer의 형태로 사용할 수도 있지만 더 직관적인 방법도 제공한다. 즉, 이벤트를 지원한다. HTMLDocumentEvent_ 라는 접두어가 붙는 멤버를 검색하면 나온다. HTMLDocumentEvents_2라는 인터페이스를 구현하고 있기 때문이다. 이런 이벤트 전용 인터페이스들에도 비슷한 이름 짓기 규칙이 적용된다는 것을 알 수 있다.

댓글 남기기