Figure 1 CHtmlCtrl
HtmlCtrl.h
// Microsoft Systems Journal -- January 2000
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
class CHtmlCtrl : public CHtmlView {
public:
CHtmlCtrl() { }
~CHtmlCtrl() { }
BOOL CreateFromStatic(UINT nID, CWnd* pParent);
// Normally, CHtmlView destroys itself in PostNcDestroy,
// but we don't want to do that for a control since a control
// is usually implemented as a stack object in a dialog.
//
virtual void PostNcDestroy() { }
// overrides to bypass MFC doc/view frame dependencies
afx_msg void OnDestroy();
afx_msg int OnMouseActivate(CWnd* pDesktopWnd,UINT nHitTest,UINT message);
// override to trap "app:" pseudo protocol
virtual void OnBeforeNavigate2( LPCTSTR lpszURL,
DWORD nFlags,
LPCTSTR lpszTargetFrameName,
CByteArray& baPostedData,
LPCTSTR lpszHeaders,
BOOL* pbCancel );
// override to handle links to "app:mumble...". lpszWhere will be "mumble"
virtual void OnAppCmd(LPCTSTR lpszWhere);
DECLARE_MESSAGE_MAP();
DECLARE_DYNAMIC(CHtmlCtrl)
};
HtmlCtrl.cpp
// Microsoft Systems Journal -- January 2000
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
#include "StdAfx.h"
#include "HtmlCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(CHtmlCtrl, CHtmlView)
BEGIN_MESSAGE_MAP(CHtmlCtrl, CHtmlView)
ON_WM_DESTROY()
ON_WM_MOUSEACTIVATE()
END_MESSAGE_MAP()
//////////////////
// Create control in same position as an existing static control with
// the same ID (could be any kind of control, really)
//
BOOL CHtmlCtrl::CreateFromStatic(UINT nID, CWnd* pParent)
{
CStatic wndStatic;
if (!wndStatic.SubclassDlgItem(nID, pParent))
return FALSE;
// Get static control rect, convert to parent's client coords.
CRect rc;
wndStatic.GetWindowRect(&rc);
pParent->ScreenToClient(&rc);
wndStatic.DestroyWindow();
// create HTML control (CHtmlView)
return Create(NULL, // class name
NULL, // title
(WS_CHILD | WS_VISIBLE ), // style
rc, // rectangle
pParent, // parent
nID, // control ID
NULL); // frame/doc context not used
}
////////////////
// Override to avoid CView stuff that assumes a frame.
//
void CHtmlCtrl::OnDestroy()
{
// This is probably unecessary since ~CHtmlView does it, but
// safer to mimic CHtmlView::OnDestroy.
if (m_pBrowserApp) {
m_pBrowserApp->Release();
m_pBrowserApp = NULL;
}
CWnd::OnDestroy(); // bypass CView doc/frame stuff
}
////////////////
// Override to avoid CView stuff that assumes a frame.
//
int CHtmlCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT msg)
{
// bypass CView doc/frame stuff
return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, msg);
}
//////////////////
// Override navigation handler to pass to "app:" links to virtual handler.
// Cancels the navigation in the browser, since app: is a pseudo-protocol.
//
void CHtmlCtrl::OnBeforeNavigate2( LPCTSTR lpszURL,
DWORD nFlags,
LPCTSTR lpszTargetFrameName,
CByteArray& baPostedData,
LPCTSTR lpszHeaders,
BOOL* pbCancel )
{
const char APP_PROTOCOL[] = "app:";
int len = _tcslen(APP_PROTOCOL);
if (_tcsnicmp(lpszURL, APP_PROTOCOL, len)==0) {
OnAppCmd(lpszURL + len);
*pbCancel = TRUE;
}
}
void CHtmlCtrl::OnAppCmd(LPCTSTR lpszWhere)
{
// default: do nothing
}
Figure 2 AboutHtml
<HTML>
<HEAD>
<BASE url="res://AboutHtml.exe/about.htm">
<TITLE>CHtmlCtrl About Page</TITLE>
<META http-equiv="Page-Enter" content="blendTrans(Duration=1.0)">
<BGSOUND loop="1" src="mozart.wav">
</HEAD>
<STYLE>A:hover { color:#FF00C0 }</STYLE>
<SCRIPT LANGUAGE="JavaScript">
var okImages = new Array(2);
okImages[0] = new Image();
okImages[1] = new Image();
okImages[0].src = "okup.gif";
okImages[1].src = "okdn.gif";
function OnClickOK(bDown) {
okImage.src = okImages[bDown].src;
}
</SCRIPT>
<BODY scroll=no link="#02B7B7" vlink="#02B7B7">
<TABLE border="0" width="100%" cellspacing="0" cellpadding="0">
<TR><TD width="15%" valign="top">
<a target="newwin" href="http://pobox.com/~askpd">
<img src="pd.jpg" border="0" alt="Yours Truly" width="83" height="90">
</a></TD>
<TD width="85%" valign="top">
<p align=right><FONT size=1><B>HTMLCTRL</b>Copyright 1999<br>
<a target="newwin" href="http://microsoft.com/msj">Microsoft
Systems Journal</a><br>
Written by <a target="newwin" href="http://pobox.com/~askpd">Paul DiLascia</a>
</FONT></TD>
</TR>
<TR>
<TD width="100%" colspan="2"><br>
<FONT size=1>This program shows how to implement a new class,
<b>CHtmlCtrl</b>, derived from <b>CHtmlView</b> with minor modifications, to
implement web pages you can embed in dialogs such as this About box. It also
shows how to embed HTML files as resources within your EXE or DLL. You can
read all about it in my C++ Q&A column in the January 2000 issue of
<a href="http://microsoft.com/msj" target="newwin">MSJ</a>.
<P>
You might think this is frivolous, but actually it's way cool! You can even
write some <b>JavaScript</b> or <b>DHTML</b> to do animations--HTML is just
the ticket for implementing late-nite EXE easter eggs.
</FONT>
</TD>
</TR>
<TR>
<TD width="100%" colspan="2"><br>
<b><SMALL><a target="newwin" href="http://www.webpagesthatsuck.com"><marquee
border="2" style="color: rgb(2,183,183); text-decoration: none; font-family:
Tahoma" bgcolor="#E2FCFC" scrollamount="3" scrolldelay="60" width="100%"
height="13">
Marquees
like this are really grody....
Click to find out why...
</marquee></a></SMALL></b>
</TD>
</TR>
<TR>
<TD width="28%"></TD>
<TD width="72%"> <p>
<a onMouseDown="OnClickOK(1);"
onMouseUp="OnClickOK(0);"
onMouseOut="OnClickOK(0);" href="app:ok">
<img name="okImage" src="okup.gif" align="right" border="0" width="80"
height="20"></a>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>