HTML -- The MFC-Way...



Click here for a larger image.

Environment: VC6 SP5, NT4 SP6, dao350 (mdac_typ20), IE5.5

Introduction

When I develop an application, I always search for nice skins; it sells, you know. I found an article on MSDN from Paul DiLasca, here, in which he describes how to use CHtmlView as a part of the application (in this example, as an About-Box). The advantages are clear: easy professional design, nice effects (Marquee, Overscreen...), resizeable forms, display JPGs and GIFs, and so on.

The disadvantage is that you need Internet Explorer® on your system. To demonstrate this technology, I wrote a small program named "Personal Knowledge Base." In this program you can collect files, store them compressed in the database, and with some explaining, add text and keywords for searching. I have tested the program with all my downloads from CodeGuru...

NOTE: It's DAO350 !!! If the application can't open a database, please install mdac_typ20.exe.

Now let's go...

How to Realize an Interaction between the Shown HTML Content and the Logic in the Application

  1. Bring the HTML code inside your EXE: Modify your resource file like this:
  2. //in PKG.rc
    START.HTML        HTML    DISCARDABLE     "res\\start.html"
    BG.GIF            HTML    DISCARDABLE     "res\\bg.gif"
    TITLE.GIF         HTML    DISCARDABLE     "res\\title.gif"
    CONT.HTML         HTML    DISCARDABLE     "res\\cont.html"
    BIN.HTML          HTML    DISCARDABLE     "res\\bin.html"
    LSTHEADER.HTML    HTML    DISCARDABLE     "res\\lstheade.htm"
    LST.HTML          HTML    DISCARDABLE     "res\\lst.html"
    

    It's important to use real file names as resource names so the browser can find them. Note that all files I need for the HTML pages are imported in this way.

    Note: I don't know why, but my Visual Studio crashes sometimes while importing HTML files. It's better that you edit your Resource File manually.

  3. Load and show these resources in the HtmlView:
  4. void CYourHtmlView::OnInitialUpdate()
    {
        LoadFromResource(_T("start.html"));    //that's all
    }
    

    But you have to give your browser a little help to find the content by adding the following code at the top of your HTML file:

    <BASE url="res://PKB.exe/start.html">
    

    This tells the browser that the current "directory" is res://PKB.exe.

  5. Interaction between your application and the browser: To access the content of your browser directly, you have to import the IE Typelibrary like this in your stdafx.h:
  6. #pragma warning(disable:4192)
    #pragma warning(disable:4049)
    #import "C:\WINNT\system32\mshtml.tlb"
    
    1. The program changes the content of your HTML page dynamically (DHTML): All the elements you want to change must have an unique id. After the document is loaded completely, you can access each element like this:
    2. //in derived CHtmlView-Class
      MSHTML::IHTMLDocument2Ptr pDoc(GetHtmlDocument());
      MSHTML::IHTMLElementPtr e(pDoc->Getall()->item
                               (_T("someElement")));
      e->PutinnerText(_T("someText"));
      //or
      e->PutinnerHTML(_T("<b>someText</b>"));
      

      To get elements inside frames, look in the source for the function ProcessContentPage. (It's a little bit tricky to find exactly the point when all frames are completely loaded.)

    3. Catch an event in the HTML page to interact with your code: Here, Paul DiLasca is my "hero." I customized his idea a little bit, so that it's pretty easy to invent new commands to be "sent" from JavaSript code to your application. Let's see an example of the JavaScript code:
    4. function onSomeButtonClicked()
      {
          document.location.href="app:buttonPressed";
          //or my way
          document.location.href="app:1000";
          //the number corresponds with a #define in my
          //C++ code
      }
      

      Paul DiLasca invented a pseudo-protocol called "app:". Now you can catch this "event" when you override CHtmlView::OnBeforeNavigate2. The rest is simple. Here is my code:

      void CRightView::OnBeforeNavigate2(LPCTSTR lpszURL,
                       DWORD nFlags,
                       LPCTSTR lpszTargetFrameName,
                       CByteArray& baPostedData,
                       LPCTSTR lpszHeaders,
                       BOOL* pbCancel)
      {
          if(!_strnicmp(BROWSER_TO_APP, lpszURL, strlen
                       (BROWSER_TO_APP)))
          {
              *pbCancel=TRUE;    //important to cancel the
                                 //navigation !!!
              ProcessBrowerCmds(lpszURL + strlen
                               (BROWSER_TO_APP));
          }
          CHtmlView::OnBeforeNavigate2(lpszURL, nFlags,
                     lpszTargetFrameName, baPostedData,
                     lpszHeaders, pbCancel);
      }
      
      BOOL CRightView::ProcessBrowerCmds(const char* lpszCmd)
      {
          BOOL bRet=FALSE;
        int iCmd=atoi(lpszCmd);
        switch(iCmd)
        {
          default:
            ASSERT(FALSE);
            //some code here...
            break;
      
            case CMD_OPEN_DOC:
              //some code here...
              break;
      
            case CMD_ADD_DOC:
              //some code here...
              break;
      
            case CMD_SAVE_DOC:
              //some code here...
              break;
      
            case CMD_DEL_DOC:
              //some code here...
              break;
      
            case CMD_CONTEXTMENU:
              //some code here to exchange the standard
              //explorer context menu with your own menu
              //(look in cont.html for more details)
              break;
          }
          return bRet;
      }
      

It's like programming in Visual Basic®...........

PS: Have look on the macros in the CDaoUti Class. I think they can be useful for your work with DAO.

Acknowledgements:

Thanks, Paul DiLasca, for your ideas. I used a lot of code thar was downloaded from this site. Thanks, all, particularly to Tadeusz Dracz for his class CZipArchive!!!

Downloads

Download demo project - 184 Kb
By the way, the user for the demo is "system", no password...
Download source - 634 Kb