显示HTML对话框
用VC做GUI是一件相当闹心的事,自绘、各种细节调整真的需要程序员很要有耐心,而且当碰到朝令夕改的情况时,那就会让人抓狂了.现在发现很多软件的显示都是基于网页控件了,这办法好啊,改界面的事完全可以推给美工了,大善!。MFC提供了类CDHtmlDialog用来显示HTML对话框.要在非MFC框架下(如WTL)下显示HTML对话框就要自己动手了.
mshtml.dll中有个ShowHTMLDialog可以显示HTML对话框,MSDN定义如下:
HRESULT ShowHTMLDialog( HWND hwndParent,
IMoniker *pMk,
VARIANT *pvarArgIn,
WCHAR *pchOptions,
VARIANT *pvarArgOut
);
在此,我结合网上的一些资源,简单地封装了它的用法,网页事件的获取还没实现,以后会慢慢补上:
IMoniker *pMk,
VARIANT *pvarArgIn,
WCHAR *pchOptions,
VARIANT *pvarArgOut
);
#include <urlmon.h>
#pragma comment(lib, "urlmon.lib")
/*
* 获取uIDHtml指定的HTML资源的源码
*/
inline CString LoadHtmlResource(_U_STRINGorID uIDHtml)
{
HRSRC hrsrc = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), uIDHtml.m_lpstr, RT_HTML);
if( hrsrc != NULL )
{
DWORD dwSize = ::SizeofResource(ATL::_AtlBaseModule.GetResourceInstance(), hrsrc);
HGLOBAL hGlobal = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hrsrc);
if( hGlobal != NULL )
{
LPSTR pszData = (LPSTR) ::LockResource( hGlobal );
if( pszData != NULL )
{
pszData[dwSize] = 0;
CString strHtml = pszData;
UnlockResource( hGlobal );
::FreeResource( hGlobal );
return strHtml;
}
}
}
return CString();
}
class CHtmlDialog
{
private:
HINSTANCE m_hInstMSHTML;
SHOWHTMLDIALOGFN* m_pfnShowHTMLDialog;
public:
CHtmlDialog()
{
m_hInstMSHTML = ::LoadLibrary( _T("MSHTML.DLL") );
ATLASSERT( m_hInstMSHTML != NULL );
m_pfnShowHTMLDialog = (SHOWHTMLDIALOGFN*)::GetProcAddress( m_hInstMSHTML, "ShowHTMLDialog" );
ATLASSERT( m_pfnShowHTMLDialog != NULL );
}
/*
* 根据HTML资源显示对话框
* hWnd: 指定父窗口
* bstrHtml: HTML源代码
*/
BOOL ShowHtmlDialog( HWND hWnd, BSTR bstrHtml, VARIANT *pvIn = NULL, BSTR bstrOptions = NULL, VARIANT *pvOut = NULL )
{
ATLASSERT( m_pfnShowHTMLDialog != NULL );
if( m_pfnShowHTMLDialog == NULL )return FALSE;
if( hWnd==NULL ) hWnd = ::GetForegroundWindow();
ATLASSERT( ::IsWindow( hWnd ) );
//CAtlTemporaryFileEx源于我对ATL类CAtlTemporaryFile,详情请见我的另一篇博文<无语的CAtlTemporaryFile类>
CAtlTemporaryFileEx fileTmp;
fileTmp.Create();
//将HTML源码写入临时文件
fileTmp.Write( COLE2CT( bstrHtml ), wcslen( bstrHtml ) * sizeof( wchar_t ) );
fileTmp.Close();
CComBSTR bstrText(L"file:///");
bstrText += fileTmp.TempFileName();
CComPtr<IMoniker> spMoniker;
HRESULT hr;
hr = ::CreateURLMoniker( NULL, bstrText, &spMoniker );
if( SUCCEEDED(hr) )
{
//显示HTML对话框
hr = (*m_pfnShowHTMLDialog)( hWnd, spMoniker.p, pvIn, CT2W( COLE2CT( bstrOptions ) ), pvOut );
ATLASSERT( SUCCEEDED(hr) );
spMoniker.Release();
}
return ( hr==S_OK );
}
/*
* 重载ShowHtmlDialog方法,用HTML资源ID作为输入参数
*/
BOOL ShowHtmlDialog( HWND hWnd, _U_STRINGorID uIDHtml, VARIANT *pvIn = NULL, BSTR bstrOptions = NULL, VARIANT *pvOut = NULL )
{
CString strHtml;
strHtml = LoadHtmlResource( uIDHtml );
return ShowHtmlDialog( hWnd, CT2OLE( strHtml ), pvIn, bstrOptions, pvOut );
}
~CHtmlDialog()
{
if( m_hInstMSHTML != NULL )
{
::FreeLibrary( m_hInstMSHTML );
}
}
};
使用示例:
#pragma comment(lib, "urlmon.lib")
/*
* 获取uIDHtml指定的HTML资源的源码
*/
inline CString LoadHtmlResource(_U_STRINGorID uIDHtml)
{
HRSRC hrsrc = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), uIDHtml.m_lpstr, RT_HTML);
if( hrsrc != NULL )
{
DWORD dwSize = ::SizeofResource(ATL::_AtlBaseModule.GetResourceInstance(), hrsrc);
HGLOBAL hGlobal = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hrsrc);
if( hGlobal != NULL )
{
LPSTR pszData = (LPSTR) ::LockResource( hGlobal );
if( pszData != NULL )
{
pszData[dwSize] = 0;
CString strHtml = pszData;
UnlockResource( hGlobal );
::FreeResource( hGlobal );
return strHtml;
}
}
}
return CString();
}
class CHtmlDialog
{
private:
HINSTANCE m_hInstMSHTML;
SHOWHTMLDIALOGFN* m_pfnShowHTMLDialog;
public:
CHtmlDialog()
{
m_hInstMSHTML = ::LoadLibrary( _T("MSHTML.DLL") );
ATLASSERT( m_hInstMSHTML != NULL );
m_pfnShowHTMLDialog = (SHOWHTMLDIALOGFN*)::GetProcAddress( m_hInstMSHTML, "ShowHTMLDialog" );
ATLASSERT( m_pfnShowHTMLDialog != NULL );
}
/*
* 根据HTML资源显示对话框
* hWnd: 指定父窗口
* bstrHtml: HTML源代码
*/
BOOL ShowHtmlDialog( HWND hWnd, BSTR bstrHtml, VARIANT *pvIn = NULL, BSTR bstrOptions = NULL, VARIANT *pvOut = NULL )
{
ATLASSERT( m_pfnShowHTMLDialog != NULL );
if( m_pfnShowHTMLDialog == NULL )return FALSE;
if( hWnd==NULL ) hWnd = ::GetForegroundWindow();
ATLASSERT( ::IsWindow( hWnd ) );
//CAtlTemporaryFileEx源于我对ATL类CAtlTemporaryFile,详情请见我的另一篇博文<无语的CAtlTemporaryFile类>
CAtlTemporaryFileEx fileTmp;
fileTmp.Create();
//将HTML源码写入临时文件
fileTmp.Write( COLE2CT( bstrHtml ), wcslen( bstrHtml ) * sizeof( wchar_t ) );
fileTmp.Close();
CComBSTR bstrText(L"file:///");
bstrText += fileTmp.TempFileName();
CComPtr<IMoniker> spMoniker;
HRESULT hr;
hr = ::CreateURLMoniker( NULL, bstrText, &spMoniker );
if( SUCCEEDED(hr) )
{
//显示HTML对话框
hr = (*m_pfnShowHTMLDialog)( hWnd, spMoniker.p, pvIn, CT2W( COLE2CT( bstrOptions ) ), pvOut );
ATLASSERT( SUCCEEDED(hr) );
spMoniker.Release();
}
return ( hr==S_OK );
}
/*
* 重载ShowHtmlDialog方法,用HTML资源ID作为输入参数
*/
BOOL ShowHtmlDialog( HWND hWnd, _U_STRINGorID uIDHtml, VARIANT *pvIn = NULL, BSTR bstrOptions = NULL, VARIANT *pvOut = NULL )
{
CString strHtml;
strHtml = LoadHtmlResource( uIDHtml );
return ShowHtmlDialog( hWnd, CT2OLE( strHtml ), pvIn, bstrOptions, pvOut );
}
~CHtmlDialog()
{
if( m_hInstMSHTML != NULL )
{
::FreeLibrary( m_hInstMSHTML );
}
}
};
TCHAR szHtml[] = _T("<html> \
<head> \
<title>MyHtmlDialog</title> \
</head> \
<body bgcolor=\"#66cc55\"> \
<BUTTON id=BUTTON1 style=\"Z-INDEX: 100; LEFT: 155px; POSITION: absolute; TOP: 73px\">Button</BUTTON> \
</body> \
</html>");
CHtmlDialog dlgHtml;
dlgHtml.ShowHtmlDialog( m_hWnd, CT2OLE( szHtml ) );
dlgHtml.ShowHtmlDialog( m_hWnd, IDR_HTML2 );
<head> \
<title>MyHtmlDialog</title> \
</head> \
<body bgcolor=\"#66cc55\"> \
<BUTTON id=BUTTON1 style=\"Z-INDEX: 100; LEFT: 155px; POSITION: absolute; TOP: 73px\">Button</BUTTON> \
</body> \
</html>");
CHtmlDialog dlgHtml;
dlgHtml.ShowHtmlDialog( m_hWnd, CT2OLE( szHtml ) );
dlgHtml.ShowHtmlDialog( m_hWnd, IDR_HTML2 );