在某些特殊的应用场合,我们很想要一个类似IE功能的模块,定制自己的功能。

HTML控件现在向我们张开了怀抱。稍稍奇怪的是,它并不完全支持WAP协议。看来,IE还是做了自己的解析。

首先,我们要注册一下控件。把Htmlctrl.h包含进来,调用InitHTMLControl()函数,里面的参数为应用程序句柄。以下代码在MFC中使用:

VERIFY(InitHTMLControl(AfxGetInstanceHandle()));
 
 DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
 RECT rect;
 GetClientRect(&rect);
 m_hHtmlWnd = ::CreateWindow (DISPLAYCLASS,
                                 NULL,
                                 dwStyle,
                                 rect.left,
                                 rect.top,
                                 rect.right,
                                 rect.bottom,
                                 m_hWnd,
                                 0,
                                 ::AfxGetInstanceHandle(),
                                 NULL);

 ::SetWindowLong(m_hHtmlWnd, GWL_ID, 12321);
 ::SetFocus(m_hHtmlWnd);
 ::SendMessage(m_hHtmlWnd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)_T(""));

在这里,m_hHtmlWnd是某个Dialog的HWND型成员变量。

然后,在Dialog的WindowProc函数中,使用如下方法:

switch(message)
 {
  case WM_NOTIFY:
        {
            WCHAR wszURL[1000] = {0};
            NM_HTMLVIEW* pnmHTMLView = (NM_HTMLVIEW*)lParam;
   
            switch (pnmHTMLView->hdr.code)
            {
              case NM_HOTSPOT:
             {
              OutputDebugString(pnmHTMLView->szTarget);
             break;
            }

             case NM_INLINE_IMAGE:
            {
             OutputDebugString(TEXT("NM_INLINE_IMAGE\r\n"));
             break;
            }

            case NM_INLINE_SOUND:
           {
          OutputDebugString(TEXT("NM_INLINE_SOUND\r\n"));
           break;
           }

          case NM_TITLE:
          {
          OutputDebugString(TEXT("NM_TITLE\r\n"));
          break;
         }

         case NM_META:
        {
        OutputDebugString(TEXT("NM_META\r\n"));
         break;
        }

        case NM_BASE:
        {
        OutputDebugString(TEXT("NM_BASE\r\n"));
        break;
        }

      case NM_CONTEXTMENU:
       {
        OutputDebugString(TEXT("NM_CONTEXTMENU\r\n"));
        break;
      }

      case NM_INLINE_XML:
      {
       OutputDebugString(TEXT("NM_INLINE_XML\r\n"));
       break;
      }

     case NM_BEFORENAVIGATE:
      {
       OutputDebugString(TEXT("NM_BEFORENAVIGATE\r\n"));
       break;
      }

     case NM_DOCUMENTCOMPLETE:
      {
       OutputDebugString(TEXT("NM_DOCUMENTCOMPLETE\r\n"));
       break;
      }

     case NM_NAVIGATECOMPLETE:
      {
       OutputDebugString(TEXT("NM_NAVIGATECOMPLETE\r\n"));
       break;
      }

     case NM_TITLECHANGE:
      {
       OutputDebugString(TEXT("NM_TITLECHANGE\r\n"));
       break;
      }

     default:
      {
       ASSERT(FALSE);
       break;
      }

}

}
  }

  在上面的几个关键点,NM_HOTSPOT是用户点击了网页链接,通过访问pnmHTMLView->szTarget可以得到网页内容。SendMessage可以将得到的内容赋给控件,控件会自己解析网页元素。如果有图片链接,将会触发NM_INLINE_IMAGE动作。此时亦需要通过访问pnmHTMLView->szTarget来得到图片。如果得到了图片的内容,可以使用下面的代码来显示:

INLINEIMAGEINFO imageInfo;
imageInfo.dwCookie = pnmHTMLView->dwCookie;
imageInfo.bOwnBitmap = FALSE;
imageInfo.hbm = hBitmap;

BITMAP mInfo; 
GetObject(hBitmap, sizeof(BITMAP), (LPBYTE)&mInfo);

imageInfo.iOrigWidth  = mInfo.bmWidth;
imageInfo.iOrigHeight = mInfo.bmHeight;
        
::SendMessage(pnmHTMLView->hdr.hwndFrom, DTM_SETIMAGE, 0, (LPARAM)(INLINEIMAGEINFO*)&imageInfo);

上面代码中hBitmap为图片位图句柄。

  我在处理图片的时候,遇到的问题是。使用SHLoadImageFile函数后,需使用DeleteObject函数释放句柄内存。否则将有内存泄露。MSDN没有提及这一现象。

如果未得到图片内容,想在网页相应的位置显示一个叉,DTM_SETIMAGE参数应改为DTM_IMAGEFAIL。

  值得注意的是,如果我们处理了NM_HOTSPOT或NM_INLINE_IMAGE消息,需要返回TURE或FALSE,不然控件本身会再处理一遍。

关于 NM_HTMLVIEW 结构体

typedef struct tagNM_HTMLVIEW {
NMHDR hdr;
LPSTR szTarget;
LPSTR szData;
DWORD dwCookie;
} NM_HTMLVIEW;

函数中的第一个参数是一个NMHDR类型的结构体

NMHDR Structure

Contains information about a notification message.

Syntax

typedef struct tagNMHDR {
            HWND hwndFrom;
            UINT_PTR idFrom;
            UINT code;
            } NMHDR;

Members

hwndFrom
A window handle to the control sending the message.
idFrom
An identifier of the control sending the message.
code
A notification code. This member can be one of the common notification codes (see Notifications under General Control Reference), or it can be a control-specific notification code.

 

 

 

 

posted on 2008-09-16 18:18  NANLEE  阅读(1354)  评论(2编辑  收藏  举报