Visual C and DHTML

Visual C++ 6.0 supports DHTML through both MFC and ATL. Both MFC and ATL give you complete access to the DHTML object model. Unfortunately, access to the object model from languages like C++ is done through OLE Automation (IDispatch) and in many cases isn't as cut-and-dried as some of the scripts we looked at earlier.

The DHTML object model is exposed to C++ developers through a set of COM objects with the prefix IHTML (IHTMLDocument, IHTMLWindow, IHTMLElement, IHTMLBodyElement, and so on). In C++, once you obtain the document interface, you can use any of the IHTMLDocument2 interface methods to obtain or to modify the document's properties.

You can access the all collection by calling the IHTMLDocument2::get_all method. This method returns an IHTMLElementCollection collection interface that contains all the elements in the document. You can then iterate through the collection using the IHTMLElementCollection::item method (similar to the parentheses in the script above). The IHTMLElementCollection::item method supplies you with an IDispatch pointer that you can call QueryInterface on, requesting the IID_IHTMLElement interface. This call to QueryInterface will give you an IHTMLElement interface pointer that you can use to get or set information for the HTML element.

Most elements also provide a specific interface for working with that particular element type. These element-specific interface names take the format of IHTMLXXXXElement, where XXXX is the name of the element (IHTMLBodyElement, for example). You must call QueryInterface on the IHTMLElement object to request the element-specific interface you need. This might sound confusing (because it can be!). But don't worry—the MFC and ATL sections in this chapter contain plenty of samples that demonstrate how it all ties together. You'll be writing DHTML code in no time.

MFC and DHTML

MFC's support for DHTML starts with a new CView derivative, CHtmlView. CHtmlView allows you to embed an HTML view inside frame windows or splitter windows, where with some DHTML work it can act as a dynamic form. Example EX37A demonstrates how to use the new CHtmlView class in a vanilla MDI application.

Follow these steps to create the EX37A example:

  1. Run AppWizard and create \vcpp32\ex37a\ex37a. Choose New from Visual C++'s File menu. Then click the Projects tab, and select MFC AppWizard (exe). Accept all defaults, except in Step 6 choose CHtmlView as the Base Class, as shown here.

    click to view at full size.

  2. Edit the URL to be loaded. In the CEx37aView::OnInitialUpdate function, you will see this line:

    Navigate2(_T("http://www.microsoft.com/visualc/"),NULL,NULL);

    You can edit this line to have the application load a local page or a URL other than the Visual C++ page.

  3. Compile and run. Figure 37-3 shows the application running with the default Web page.

    click to view at full size.

    Figure 37-3. The EX37A example.

    Now let's create a sample that really shows how to use DHTML with MFC. EX37B creates a CHtmlView object and a CListView object separated by a splitter. The example then uses DHTML to enumerate the HTML elements in the CHtmlView object and displays the results in the CListView object. The end result will be a DHTML explorer that you can use to view the DHTML object model of any HTML file.

    Here are the steps to create EX37B:

  4. Run AppWizard and create \vcpp32\ex37b\ex37b. Choose New from Visual C++'s File menu. Then click the Projects tab, and select MFC AppWizard (exe). Accept all the defaults but three: select Single Document, select Windows Explorer in Step 5, and select CHtmlView as the Base Class in Step 6. The options that you should see after finishing the wizard are shown in the graphic below.

  5. Change the CLeftView to be a CListView derivative. By default, AppWizard makes the CLeftView of the splitter window a CTreeView derivative. Open the LeftView.h file, and do a global search for CTreeView and replace it with CListView. Open LeftView.cpp and do the same find and replace (Hint: Use Edit/Replace/Replace All.)

  6. Edit the URL to be loaded. In the CEx37bView::OnInitialUpdate function, change the URL to res://ie4tour.dll/welcome.htm.

  7. Add a DoDHTMLExplore function to CMainFrame. First add the fol-lowing declaration to the MainFrm.h file:

        virtual void DoDHTMLExplore(void);

    Now add the implementation for DoHTMLExplore to MainFrm.cpp.

    void CMainFrame::DoDHTMLExplore(void) {     CLeftView *pListView =          (CLeftView *)m_wndSplitter.GetPane(0,0);     CEx37bView * pDHTMLView =          (CEx37bView *)m_wndSplitter.GetPane(0,1);     //Clear the listview      pListView->GetListCtrl().DeleteAllItems();     IDispatch* pDisp = pDHTMLView->GetHtmlDocument();          if (pDisp != NULL )     {         IHTMLDocument2* pHTMLDocument2;         HRESULT hr;         hr = pDisp->QueryInterface( IID_IHTMLDocument2,                     (void**)&pHTMLDocument2 );         if (hr == S_OK)         {             IHTMLElementCollection* pColl = NULL;             hr = pHTMLDocument2->get_all( &pColl );             if (hr == S_OK && pColl != NULL)             {                 LONG celem;                 hr = pColl->get_length( &celem );                 if ( hr == S_OK )                 {                     for ( int i=0; i< celem; i++ )                     {                         VARIANT varIndex;                         varIndex.vt = VT_UINT;                         varIndex.lVal = i;                         VARIANT var2;                         VariantInit( &var2 );                         IDispatch* pDisp;                          hr = pColl->item( varIndex, var2, &pDisp );                         if ( hr == S_OK )                         {                             IHTMLElement* pElem;                             hr = pDisp->QueryInterface(                                 IID_IHTMLElement,                                 (void **)&pElem);                             if ( hr == S_OK )                             {                                 BSTR bstr;                                 hr = pElem->get_tagName(&bstr);                                 CString strTag = bstr;                                 IHTMLImgElement* pImgElem;                                 //Is it an image element?                                 hr = pDisp->QueryInterface(                                     IID_IHTMLImgElement,                                      (void **)&pImgElem );                                 if ( hr == S_OK )                                 {                                     pImgElem->get_href(&bstr);                                     strTag += " - ";                                     strTag += bstr;                                     pImgElem->Release();                                 }                                 else                                 {                                     IHTMLAnchorElement* pAnchElem;                                     //Is it an anchor?                                     hr = pDisp->QueryInterface(                                         IID_IHTMLAnchorElement,                                          (void **)&pAnchElem );                                     if ( hr == S_OK )                                     {                                         pAnchElem->get_href(&bstr);                                         strTag += " - ";                                         strTag += bstr;                                         pAnchElem->Release();                                     }                                 }//end of else                                 pListView->GetListCtrl().InsertItem(                                     pListView->GetListCtrl()                                     .GetItemCount(), strTag);                                 pElem->Release();                             }                             pDisp->Release();                         }                     }                 }                 pColl->Release();             }             pHTMLDocument2->Release();         }         pDisp->Release();     } }

    Here are the steps that this function takes to "explore" the HTML document using DHTMLs:

    • First DoHTMLExplore gets pointers to the CListView and CHtmlView views in the splitter window.

    • Then it makes a call to GetHtmlDocument to get an IDispatch pointer to the DHTML document object.

    • Next DoHTMLExplore gets the IHTMLDocument2 interface.

    • With the IHTMLDocument2 interface, DoHTMLExplore retrieves the all collection and iterates through it. In each iteration, DoHTMLExplore checks the element type.If the element is an image or an anchor, DoHTMLExplore retrieves additional information such as the link for the image. The all collection loop then places the textual description of the HTML element in the CListView object.

  8. Make sure that Mainfrm.cpp includes mshtml.h. Add the following line to the top of Mainfrm.cpp so that the DoHTMLExplore code will compile.

    #include <mshtml.h>

  9. Add a call to DoHTMLExplore. For this example, we will change the CEx37bApp::OnAppAbout function to call the DoDHTMLExplore function in the ex37b.cpp file. Replace the existing code with the following boldface code:

    void CEx37bApp::OnAppAbout() {     CMainFrame * pFrame = (CMainFrame*)AfxGetMainWnd();     pFrame->DoDHTMLExplore(); }

  10. Customize the list view. In the CLeftView::PreCreateWindow function (LeftView.cpp), add this line:

    cs.style |= LVS_LIST;

  11. Compile and run. Compile and run the sample. Press the "?" toolbar item, or choose Help/About to invoke the explore function.

    Figure 37-4 shows the EX37B example in action.

    click to view at full size.

    Figure 37-4. The EX37B example in action.

Now that you've seen how to use DHTML and MFC, let's look at how ATL implements DHMTL support.

ATL and DHTML

ATL's support for DHTML comes in the form of an HTML object that can be embedded in any ATL ActiveX control. EX37C creates an ATL control that illustrates DHTML support.

To create the example, follow these steps:

  1. Run the ATL COM AppWizard and create \vcpp32\ex37c\ex37c. Choose New from Visual C++'s File menu. Then click the Projects tab, and select ATL COM AppWizard. Choose Executable as the server type.

  2. Insert an HTML control. In ClassView, right-click on the ex37c classes item and select New ATL Object. Select Controls and HTML Control as shown in the graphic below.

  3. Click Next and fill in the C++ Short Name as shown here.

    If you look at the IDHTMLUI object, you will see this stock implementation of the OnClick handler:

        STDMETHOD(OnClick)(IDispatch* pdispBody, VARIANT varColor)     {         CComQIPtr<IHTMLBodyElement> spBody(pdispBody);         if (spBody != NULL)             spBody->put_bgColor(varColor);         return S_OK;     }

    The default OnClick handler uses QueryInterface on the IDispatch pointer to get the IHTMLBodyElement object. The handler then calls the put_bgColor method to change the background color.

  • Compile, load, and run the control to see the ATL DHTML code in action. After you build the project, select ActiveX Control Test Container from the Tools menu. In the test container, select Insert New Control from the Edit menu and choose CDHTML Class from the list box. Figure 37-5 shows the resulting ActiveX control that uses DHTML to change the background when the user clicks the button.

    Figure 37-5. EX37C ActiveX control.

    For More Information…

    We hope this introduction to DHTML has you thinking of some ways to use this exciting new technology in your Visual C++ applications. The possibilities are endless: completely dynamic applications, applications that update from the Internet, client/server ActiveX controls, and many more.

    If you would like to learn more about DHTML, we suggest the following resources:

    • Inside Dynamic HTML by Scott Isaacs (Microsoft Press, 1997)

    • Dynamic HTML in Action by William J. Pardi and Eric M. Schurman (Microsoft Press, 1998)

    • The Internet SDK (an excellent resource on DHTML and other Microsoft technologies)

    • www.microsoft.com (several areas discuss DHTML)



  • Programming Visual C++
    Advanced 3ds max 5 Modeling & Animating
    ISBN: 1572318570
    EAN: 2147483647
    Year: 1997
    Pages: 331
    Authors: Boris Kulagin

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net