Utilizing Pocket IE Functionality in Mobile Applications
Most PDAs come with prewired Internet Explorer. Its versions may be different, or a vendor may decide that its device doesn't need it al all. But, when it does exist, it's just natural to use its capabilities, isn't it? In this article, we will discuss how to do it on different types of PDA and WinCE flavors.
Using HtlmControl
Even on very old devices with OS Palm Size PC 2.11, you have htmlview.dll (and respectively, htmlview.lib). This stuff is continuing to appear on all Pocket PC devices, such as PPC 2000, PPC 2002, and so forth. Well, not all devices with 1/4 VGA screens are from the "Pocket PC" family, but we will discuss them later in this article. Coming back to HtmlControl, below are the steps you need to complete to obtain browser functionality:
- Include htmlctrl.h to your project
- Initialize the HTML control by calling the InitHTMLControl function
- Create a window for the HTML control by calling the CreateWindow function with DISPLAYNAME as a window class name parameter
- Handle WM_NOTIFY messages for NM_HOTSPOT and NM_INLINE_IMAGE codes
- Link your application with htmlview.lib
As you may guess, there is nothing too complicated here. The stuff that is not mentioned above is downloading data from Web sites according to links and displaying images on the screen. And besides, don't expect any support for JScript, frames, and analogous features. HTML Control provides just basic browser functionality. All the rest is up to you.
But, that's enough theory. Let's take a look at a simple code sample to illustrate HTML Control usage. Below are parts of a sample project. For simplicity, the HTML Control object is inherited from CStatic class.
// Initialize HTML Control BOOL CHtmlCtrlApp::InitInstance() { InitHTMLControl(AfxGetInstanceHandle()); CHtmlCtrlDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); return FALSE; } // Create Html Control Window and make some initialization void CHtmlView::CreateHtmlWindow(CRect& rect) { DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; CString sInfo; m_hwndHtml = ::CreateWindow (DISPLAYCLASS,//DISPLAYCLASS, NULL, dwStyle, rect.left, rect.top, rect.right, rect.bottom, m_hWnd, 0, AfxGetInstanceHandle(), NULL); ::SetWindowLong(m_hwndHtml,GWL_ID,12321); ::SetFocus (m_hwndHtml); ::SendMessage(m_hwndHtml,WM_SETTEXT,0,(LPARAM)(LPCTSTR)_T("")); } // Handle notification messages LRESULT CHtmlView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_NOTIFY: NM_HTMLVIEW * pnmHTML = (NM_HTMLVIEW *) lParam; LPNMHDR pnmh = (LPNMHDR) &(pnmHTML->hdr); switch(pnmh->code) { case NM_HOTSPOT: OnLink(pnmHTML->szTarget); break; case NM_INLINE_IMAGE: OnInlineImage(pnmHTML->szTarget,pnmHTML->dwCookie); } } return CStatic::WindowProc(message, wParam, lParam); } // Download html page from selected target site void CHtmlView::OnLink(const CString &strHref) { TCHAR *szHtml = NULL; // Here you actually put the code to download HTML page into // szHtml ... // And finally command HTML Control to show it ::SendMessage(m_hwndHtml, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)NULL); ::SendMessage(m_hwndHtml, DTM_ADDTEXTW, FALSE, (LPARAM)(LPCTSTR)szHtml); ::SendMessage(m_hwndHtml, DTM_ENDOFSOURCE, 0, 0); } // Loading images void CHtmlView::OnInlineImage(const CString &strHref, DWORD dwCookie) { // Here handle image loading ... // Set image if all is OK if ( bImageLoadedOK ) { INLINEIMAGEINFO imageInfo; imageInfo.dwCookie = dwCookieValue; imageInfo.bOwnBitmap = FALSE; imageInfo.hbm = (HBITMAP)(*pBitmap); CSize size = pBitmap->GetBitmapDimension(); imageInfo.iOrigWidth = size.cx; imageInfo.iOrigHeight = size.cy; ::SendMessage(m_hwndHtml, DTM_SETIMAGE, 0, (LPARAM) (INLINEIMAGEINFO*)&imageInfo); } // Otherwise, send failure message else ::SendMessage(m_hwndHtml, DTM_IMAGEFAIL, 0, (LPARAM) (LPINLINEIMAGEINFO)dwCookieValue); } ... // And finally ... BOOL CHtmlCtrlDlg::OnInitDialog() { ... // m_htmlView is pointer to CHtmlView class if (m_htmlView->SubclassDlgItem(IDC_HTMLVIEW,this)) { // do some initialization if needed } ... }
Well, the code above initiates and creates CHtmlView object, and creates HtmlView window. By calling the SubclassDlgItem function, it's connected to the Static control's window. Thus, that's a convenient way to use a placeholder in the Resource editor. After a HTML Control window is created, it is able to display HTML pages. Also, it receives notifications when the user taps on links or some image should be shown. All details regarding downloading pages or images are ommited in this sample, so you may implement it as is more comfortable for you. For images, you may think about some kind of cache, to avoid odd network traffic for the same data. The following picture presents the resulting output of this sample:
IWebBrowser2 interface
For PDA devices running Windows CE.NET (not from Pocket PC family), e.g. Fujitsu iPAD, there is an opportunity to use the IWebBrowser2 interface. That's good news because this interface takes care of a lot of things. If you have used it on a PC, you'll feel pretty comfortable here. A code snippet below shows how to create an instance of IWebBrowser2:
... #include <exdisp.h> // an instance of IWebBrowser2 IWebBrowser2 *m_pBrowserApp; ... void CBrowser::Init(CRect rect,CWnd *pWnd) { //Create the control window if(!CreateControl(CLSID_WebBrowser, NULL, WS_VISIBLE|WS_CHILD, rect,pWnd,AFX_IDW_PANE_FIRST)) { m_pBrowserApp=NULL; DestroyWindow(); } LPUNKNOWN lpUnk = GetControlUnknown(); HRESULT hr = lpUnk->QueryInterface(IID_IWebBrowser2, (void**) &m_pBrowserApp); if(!SUCCEEDED(hr)) { m_pBrowserApp = NULL; DestroyWindow(); } }
With this interface, you get most of a desktop browser's functionality. "Most"—because of regular WinCE restrictions. If you need to capture events from a browser, you may implement the DWebBrowserEvents2 interface. There are a lot of articles on the Web about IWebBrowser-related stuff, so I will not enter into these issues. In any case, you life is easy enough in such an environment.
Conclusions
Using either HTML Control or IWebBrowser2, you may make your applications much more powerful and attracive. Have fun!
About the Author
Alex Gusev started to play with mainframes at the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers' lives in the mobile jungles a little bit simpler.

Comments
htmlview.dll
Posted by pwraustin on 06/01/2006 04:15pmHi I'm using .net Compact Framework and I wonder if you maybe can help me. I'm doing something like the example below, but on the OnLink method I tried to do nothing, to see if the navigation to the href doesn't get place. But still navigating and loading the page under href URL. Do you know how prevent to navigate or meybe stop it. Thanks
ReplyCan I refere to html elements from the control ?
Posted by piyushc on 07/08/2005 05:33amHi, Can I refere to the html controls from the HTML Control that you have mentioned ? I want to get the values entered by the user in these cotntrols. Thanks and Regards, Piyush
-
ReplyRe: Can I refere to html elements from the control ?
Posted by alex_gusev on 07/10/2005 06:18amHi, Html Control described in this article has no options to access to document controls. You can try to get it via interfaces defined in webvw.h header file in SDK
Replywheres the line to create the htmlviewer ?
Posted by risnandar on 01/25/2005 01:04amwheres the line to create the htmlviewer ? i cannot find that which cause an ASSERT when attach window
-
ReplyRE: wheres the line to create the htmlviewer ?
Posted by alex_gusev on 01/25/2005 01:29amCreateHtmlWindow function has CreateWindow call with DISPLAYCLASS as window class name. Besides, InitHtmlControl is called from InitInstance method
Reply