웹, HTML

MSHTML 설명 및 컴포넌트 관계 - 틀린 설명도 있다.

디버그정 2008. 9. 10. 21:17

틀린 설명도 있으니 대충 본다...;;;

1. MSHTML이란?

MSHTML은 우리가 사용하는 브라우져에서 사용되는 언어인 HTML을 구조적으로 설계한 COM인터페이스 모음입니다.

마이크로소프트 제품인 인터넷익스플로러에서 파싱과 렌더링(DirectDraw와 연결되는 부분만)을 담당하는 것이죠.

우리가 보고있는 브라우져의 하부에는 MSHTML이 자리하고 있습니다.


MSHTML을 잘 다루면 CreateWindow를 통해 생성했던 윈32컨트롤들을 HTML엘리먼트로 대체하여 더 원활한 UI를 더 쉽게 만들수 있습니다.

물론 ActiveX등의 컨트롤도 쉽게 넣을 수 있겠지요. 더 이쁜 이미지도 간단히 넣을 수 있게 될겁니다.


그 동안 델파이나 C빌더 등의 RAD툴에서 보여주었던 것보다 더 간단하게 생성할 수도 있을 겁니다.


2. 기반지식.

MSHTML을 원활하게 다루려면 COM에 대한 지식이 필요합니다. C/C++은 당연하고 객체지향 처리와 덧붙여 ATL을 다룰 수있는 지식이 필요합니다.

물론 MSHTML을 다루면서 COM에 대한 지식을 습득할 수도 있습니다.

MSHTML은 COM의 기능을 최대한으로 이끌어내어 설계되었으며 내용도 많으므로 적잖히 도움이 될겁니다.


-- 여기서부터는 짧게 적겠습니다. --

3. 서론.

HTML을 흔히 "간단한" 마크업 언어라고 한다.

그러나 이 것을 해석하여 보여주는 프로그램에서는 수 많은 처리가 필요한데 이 처리를 위해서는 적절한 설계가 관건이다.

HTML테그가 100가지라면 100가지의 테그가 보여지는 방식이 다르고, 각 테그가 조합되어 보여지는 화면도 전부 다르기 때문에 적절한 설계는 중요할 것이다.


이를 위해서 마이크로소프트는 HTML에 대한 모든 처리를 개체지향화 설계했으며, COM을 사용했다.

COM을 사용함으로서 개체지향적인 설계와 이벤트처리, 다른 프로그램과의 통합된 인터페이스(오토메이션)등이 가능해 지게 되었다.

이를 통해 스크립트언어에서부터 C++과 같은 언어에서도 이벤트처리및 속성변화처리도 가능하다.



4. 시작하기


HTML기본적인 구조.

HTML문서는 테그의 조합으로 표현하며, 각 테그는 계층적인 특징을 담고 있다.


다음을 보자.


ex)

<HTML>

   <HEAD>

   </HEAD>

   <BODY>

   </BODY>

</HTML>


HTML문서에는 헤더부분과 바디부분으로 나누어져 있다. 헤더는 바디내에 표현할 수 없는 문서의 특징이나 기타 처리정보가 들어가게 되며, 바디에는 실제 사용자에게 보여지는 화면에 대한 정보가 들어가게 된다.

테그는 약 130여가지정도 되며, 각 테그가 어떻게 위치하는지에 따라 보여지는 모양이 달라진다.


ex)

<BODY>

   <B><I>Data</I></B>

</BODY>


B(bold)와 I(Italic)이 조합되어 Data라는 텍스트의 모양이 달리 표현된다. 이 와 같은 경우는 Data라는 텍스트가 Bold이면서 Italic인 상태가 될 것이다.

이 것을 보면 BODY -> B -> I -> (Data)의 형태로 트리형으로 표현할 수 있을 것이다. 즉, Data라는 텍스트가 들어간 노드는 ROOT에서부터 전부 찾아가 그 상에 있는 모든 테그의 특징이 적용된 텍스트라고 할 수 있다.


기본적으로 MSHTML은 트리형의 자료구조로 테그의 조합을 표현한다. 뿐만아니라 트리로는 표현하기 어려운 상황도 적절히 처리하였는데 예를 들자면,


ex)

<BODY>

   <B><I>Data</B></I>

</BODY>


이와같은 경우가 될 것이다.

즉, BODY -> B -> I인지 I -> B인지 모호한 상황에도 적절한 처리가 들어가 있다.


HTML + SCRIPT => DHTML


Dynamic HTML은 MSHTML이 COM을 통해 만들어진 후 Internet Explorer가 메인 웹브라우져의 자리를 차지하는 데 결정적인 역할을 한 개념이다.

적절하게 설계된 프로그램이 버젼업이나 기능확장에 좋은 영향을 끼친 셈이다.

HTML은 그 자체로는 문서적역할에 충실한 언어이다. 그러나 SCRIPT언어와 융합되어 프로그램적 요소가 대폭 증가되게 되었다.

예를 들자면 HTML만으로는 사용자가 어떤 이벤트를 발생했을 때 변화가 된다던지 하는 처리는 불가능하다.

그러나 스크립트와 연결되어 이같은 처리가 가능하게 되었다.


다음을 보자.


ex)

<DIV onmouseover="this.style.backgroundColor='#ff0000'" onmouseout="this.style.backgroundColor=''">Data</DIV>


위의 코드는 이벤트를 받아서 HTML문서에 어떤 변화를 주는 처리가 포함된 것이다. 즉, 마우스가 오버된 상태에서 배경색이 붉은색으로 변화되었다가,

마우스가 아웃되었을 때는 다시 원상태로 되돌리는 처리가 포함된것이다.


이 상의 모든처리를 MSHTML에서는 COM을 통해서 구현되어있다.

이벤트처리는 커넥션포인트라는 인터페이스를 통해 구조적으로 설계되어 있다.


그러면 MSHTML의 개체를 차근 차근 살펴보며 MSHTML의 깊은 곳을 탐구해보자.


1. document (IHTMLDocument2)

다큐먼트 객체는 MSHTML의 모든 객체의 가장 상위에 있는 객체이다. MSHTML이 제공하는 모든 객체(인터페이스)는 이 다큐먼트를 통해 접근가능(일부 서비스 프로바이더를 통해 얻어오는 인터페이스는 제외)하다.


예를 들어 다음과같은 HTML소스가 MSHTML에 의해 파싱된 후라면, 다큐먼트를 통해 BODY에 접근할 수 있다.


ex)

<HTML>

   <HEAD>

   </HEAD>

   <BODY>

   </BODY>

</HTML>

----


IHTMLDocument2* pDoc;   // 브라우져를 통해 얻어낼 수 있다.

IHTMLElement* pBODY = NULL;

pDoc->get_body( &pBODY );

pBODY->Release();


이와 같이 바디는 다큐먼트를 통해 얻을 수 있다.

바디와 같은 테그가 MSHTML을 통해 파싱된 후 객체로 불릴 때는 엘리먼트라고 부른다.

모든 테그는 엘리먼트가 되는데, 바디도 또한 엘리먼트중의하나가 되는 것이다.

이 엘리먼트인터페이스는 COM의 특징인 QueryInterface를 통해 실제 바디로 전환될 수 있다.


ex)


IHTMLBodyElement* peBODY = NULL;

pBODY->QueryInterface( IID_IHTMLBodyElement, reinterpret_cast< void** >( &peBODY ) );


BSTR bstrBackground;

peBODY->get_background( &bstrBackground );

::SysFreeString( bstrBackground );

peBODY->Release();

pBODY->Release();


위의 코드를 보면 바디를 가리키는 엘리먼트에서 실제 바디엘리먼트로 전환 후 바디테그가 가지고 있는 속성에 접근한 것을 볼 수 있다.


잠시 스크립트언어에 대한 이야기를 해보겠다.

스크립트에서는 단 몇번에 바디에 접근할 수 있는데 같은 처리를 스크립트에서 했을 경우 다음과 같이 된다.


document.body.background


단 한번에 접근할 수 있다.

COM의 특징에 의해 스크립트에서 접근할 수 있는 것은 Automation을 지원하기 때문이다.

즉 IDispatch를 지원하므로 이와 같이 스크립트에서 접근할 수 있는 것이다.

이에 대한 자세한 내용은 COM을 통해 알아보길 바란다.


그렇다면 C++에도 조금 더 간단하게 인터페이스에 접근할 수 있는 방법이 있지 않을까?

그렇다. 조금은 간단한 방법이 있다.

위 처럼 일일이 Release를 할 필요도 없게 해주는 템플릿 클래스가 존재한다. ATL라이브러리에 포함된 클래스인데 위의 처리를 똑같이 해보면.


CComPtr< IHTMLElement > pBODY;  // Release를 호출해줄 필요가 없다.

pDoc->get_body( &pBODY );

CComQIPtr< IHTMLBodyElement > peBODY( pBODY );  // 자동으로 쿼리 인터페이스.

CComBSTR bstrBackground;    // SysFreeString을 호출할 필요가 없다.

peBODY->get_background( &bstrBackground );


이와같이 처리할 수 있다. 즉, 자동으로 Release해주기 때문에 COM 스마트포인터 클래스인 것이다..


MSHTML프로그래밍을 하다보면 COM처리가 워낙 빈번하여 Release를 빠뜨리는 경우가 종종있다. 이를 막기위해서라도 사용할 필요가 있다.