This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


MIND

Extreme C++
mindplus@microsoft.com        Download the code (26KB)
Steve Zimmerman
DHTML Meets C++
L
ast October, I attended the Microsoft® Professional Developers Conference in San Diego. I can't claim that I learned any earth-shattering secrets while I was there. However, I'm in awe of the sheer magnitude of the development effort being put forth to improve Windows®. There is certainly room for continued improvement. But, it's obvious that—as Bill Gates himself is often quoted saying—Windows just keeps getting better and better. Surprisingly, the subject matter at the conference that impressed me most was not Windows NT® 5.0 or the Zero Administration Windows Initiative, nor was it MTS, MSMQ, or even COM+. Instead, the most dazzling part of the show, at least as far as I'm concerned, was Dynamic HTML (DHTML).

Why DHTML?
      This is probably not the first time you've heard about DHTML, and believe me, it won't be the last time either. This new technology, first made available in Microsoft Internet Explorer 4.0, promises to change not just the way you develop Web sites, but also the way you write software. What makes DHTML so much better than plain vanilla HTML? With traditional HTML, you have to use sophisticated tricks or server-side scripts to alter the presentation of data in response to display-time conditions.
      Suppose you want to provide online access to information stored in a database. Using Active Server Pages (ASP), CGI scripts, or ISAPI DLLs, you can instruct a Web server to generate HTML on the fly that presents the data to your users. But what if your users want to sort or filter the data being presented on the Web page? With server-side HTML generation, the browser has to submit the display criteria to the Web server, which would in turn have to generate a completely new HTML page for the browser. Even with a fast Internet connection, server round-trips are time-consuming and inefficient. A much more palatable approach would be to simply instruct the browser to retrieve the information and then let it do the filtering. With plain vanilla HTML, that simply isn't possible; you cannot change the contents of a page once it's been downloaded.
      A popular way to get around the static nature of HTML is to use ActiveX® controls. For example, a combination of ASP and an ActiveX listbox control can be used to present the information stored in the database. Your listbox control can filter or sort the data without having to hit the server. With ActiveX, you get dynamic, active content (hence the name, I presume) in the context of HTML. You also get control over content presentation.
      However, while ActiveX is appropriate for some tasks, it's a big pain to have to whip out your compiler and create a COM object every time you want to add active content to a Web page. Furthermore, ActiveX controls suffer from two traits that make them somewhat unattractive even to expert developers. First, since they are binary objects, they are inherently platform-dependent. You must maintain a system-specific version of your ActiveX control for every operating system on which it will be hosted. Second, placing ActiveX controls on a Web page incurs a one-time download penalty that for all but the leanest controls makes them a bit frustrating for people connected to the Internet at 19.2Kbps.
      I don't see plain vanilla HTML or ActiveX ever going away completely because there will always be a demand for Web content at both ends of the total platform-independence versus complete control over presentation spectrum. However, DHTML is clearly a good trade-off between the two and it seems to satisfy the needs of the vast majority of the middle ground. Because it grants you dynamic control over page elements, styles, positioning, and content, DHTML provides a level of creative license that approaches ActiveX, but without the overhead and platform-dependence of a binary. At the Professional Developers Conference, I saw DHTML scripts running on preview versions of Internet Explorer written for the Windows 3.1, Unix, and Macintosh operating systems, so I don't think platform-independence is going to be a problem.

Hosting DHTML in Your Application (Not the Other Way Around)
      OK, so I've sung the praises of DHTML. But Extreme C++ is supposed to be about cutting-edge C++ development, right? As it turns out, there are a lot of interesting possibilities for hybrid applications that combine C++ and DHTML. Unfortunately, many organizations are having a difficult time separating Internet hype from reality. Many developers are being asked to convert fully functional desktop applications into applets or ActiveX controls for the sole purpose of being able to say that those applications are Internet-enabled. While traditional applications can benefit from hybridization with DHTML, a wholesale "host it in the browser" approach seems akin to forcing a square peg into a round hole. Instead of trying to figure out how to host your application within Internet Explorer, you might instead benefit from the reverse approach: hosting DHTML within your application.
      Consider this scenario: suppose you want to write an application to serve as a computer-based physician's aid. This software would help a doctor reach a more accurate diagnosis by asking the appropriate questions while examining a patient. One approach would be to build an expert system—a database of thousands of questions and corresponding decision logic—and let that system walk the doctor through a list of successive questions until a single diagnosis was reached. For an MFC-based application, you might implement the user interface with a wizard. Each question could represent a page in the wizard, and you'd enable the Finish button when the expert system had collected enough information to arrive at a diagnosis.
      Unfortunately, an application like this would be difficult to build using straight C++ because you'd have to generate the layout of each page in the wizard on-the-fly. You would not be able to simply hardcode all of the question screens using a dialog editor because the second, third, and fourth questions would be based, in part, on the answer to the first. To account for the fact that there would be thousands of different diagnosis paths, you'd have to develop some sort of layout manager that allows you to create radio buttons, text fields, checkboxes, listboxes, pushbuttons, and edit controls at runtime and position them appropriately on the screen. Even with the help of MFC, that would be a painful experience. Obviously, this is a task for DHTML.

The Visual C++ Technology Preview
      The hypothetical physician's assistant software is just one example of the way in which hosting DHTML might improve your software. You'll be happy to know that the Visual C++® development team is hard at work finding ways to make it easy for your applications to take advantage of DHTML. Visual C++ 98 will support DHTML hosting and several other technologies introduced in Internet Explorer 4.0. Fortunately, you don't need to wait for Visual C++ 98 to explore those benefits. The Visual C++ Internet Explorer 4.0 Technology Preview is available right now to all users of Visual C++ 5.0. While this preview should not be used to develop and distribute commercial-grade applications, it will help you get a head start so that your application will be ready when the next version of Visual C++ is released later this year. To find out about the Technology, check out the Visual C++ Web site at http://www.microsoft.com/visualc.

Figure 1: Hosting DHTML
Figure: Hosting DHTML

      The preview support for DHTML hosting comes in the form of a CView-derived MFC class named CHtmlView. I created a sample that illustrates an MFC splitter-window application with DHTML hosted in the right-hand pane (see Figure 1). I make no claims about the robustness of this sample, but you can download it from the link at the top of this column to see how easy it is to use the CHtmlView class. I simply created a CTestView class derived from CHtmlView and then called the splitter's CreateView function to place that view in the pane:

 VERIFY( m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CTestView),
                                  start_size, pContext) );
In the OnInitialUpdate handler for my CTestView class, I simply instructed the embedded browser window to navigate to a DHTML page in the same directory as the application:

 CString strPath;
 GetModuleFileName(AfxGetInstanceHandle(),
     strPath.GetBuffer(_MAX_PATH), _MAX_PATH);
 strPath.ReleaseBuffer();
 strPath = strPath.Left(strPath.ReverseFind(_T('\\')) + 1);
 strPath += _T("outline.html");
 Navigate2(strPath, NULL, NULL);

The CHtmlView Class
      While the CHtmlView class does little more than wrap an instance of a WebBrowser object inside an MFC view, there are a few aspects of the code worth mentioning. I'll assume you've already read the excellent article by Aaron Skonnard about WebBrowser objects that appeared in the October 1997 issue of MIND, "Boning up on the Internet Client SDK, Part 1: Web Browsing Objects." The implementation of CHtmlView is too lengthy to reprint in its entirety, but a partial listing of the code is shown in Figures 2 and 3.
      In the virtual Create function—called by the MFC framework when a CView-derived class is created—CHtmlView first calls CView::Create, and then creates an instance of the WebBrowser object using a powerful but little-known CWnd method called CreateControl (see Figure 3). The CreateControl function takes the GUID or OLE, short name, (ProgID) for an ActiveX control and creates an instance of that control, represented as a CWnd object. After the WebBrowser object is created, CHtmlView calls the object's QueryInterface to extract a pointer to the IWebBrowser2 interface.
      During operation, the WebBrowser object fires notification events into its container in response to various actions. For example, just before navigating to a new Web page, the WebBrowser object fires the BeforeNavigate2 event; after navigating to that page, it fires the NavigateComplete2 event. Because the CHtmlView class handles each of these events using a virtual Onxxx member function, you can selectively override only those functions that correspond to the events you want to handle.
      Because the WebBrowser object exposes a dual interface, its interface methods use only Dispatch interface-compatible data types. While that makes it possible for script-based languages to take advantage of the browser object, it means that C++ users must deal with VARIANTs and BSTRs. As a convenience, the CHtmlView class converts these data types into C++-friendly data types such as CStrings and LPCTSTRs. Thus, even though most of the CHtmlView methods simply call associated functions in the IWebBrowser2 interface, it's a lot easier to work with the WebBrowser object in the context of CHtmlView than it would be on its own.

Conclusion
      If the emphasis placed on DHTML at the Professional Developers Conference is any indication of its potential for success, any effort you put into learning how to use it will be time well spent. Fortunately, there are tools available today that will allow you to get a head start. Happy hosting!

From the March 1998 issue of Microsoft Interactive Developer.