在Web应用开发中经常会用到带有图象、声音和动画的对话框,然而要在VC++(www.cppentry.com)中实现这样一个对话框需要做大量的工作。幸运的是,随着Internet Explorer 4.0的出现以及它所使用的新的技术,所有这些工作无须大量的代码就可实现。一种方法是使用web 浏览器控件, 但它并不是最好的方法,尤其是对处理模式对话框时;另外一种方法是使用IE4所引入的HTML模式对话框,它驻留在系统的mshtml.dll这个对HTML进行解释的引擎中。虽然有些功能诸如:单击一个链接,对历史记录的管理以及在同一窗口中装入一个链接在这个模式对话框中不能实现,但对于我们几乎所有的时候仅使用一个模式对话框来说已经足够了。
如何使用HTML中的模式对话框
mshtml.dll中的函数SHOWHTMLDIALOGFN是用来显示一个HTML对话框的,但它需要用于字符串和其它事务转换的COM要素,为了简化所有这些工作,笔者利用一个类来对COM要素进行封装如下:
class CMshtmlDialog { public: void SetDlgOptions(LPCTSTR lpszOptions); void SetSize(int x, int y); LPCVARIANT GetReturnVariant(); CString GetReturnString();
void SetParam(LPCTSTR lpszArgs); void SetParam(VARIANT* pvarArgs);
virtual int DoModal();
CMshtmlDialog(LPCTSTR lpszURL, BOOL bRes = FALSE, CWnd* pParent = NULL); CMshtmlDialog (UINT nResID, CWnd* pParent = NULL); CMshtmlDialog ( );
virtual ~ CMshtmlDialog( );
private: inline void ResourceToURL(LPCTSTR lpszURL); void CommonConstruct();
protected: HWND m_hWndParent; CString m_strOptions; COleVariant m_varArgs, m_varReturn; CString m_strURL; HINSTANCE m_hInstMSHTML; };
// CMshtmlDialog类的实现文件. CMshtmlDialog :: CMshtmlDialog () { TRACE0("Warning: Initialization may not be done: Non Functional contructor"); }
CMshtmlDialog::~ CMshtmlDialog() { //释放Mshtml.dll ::FreeLibrary(m_hInstMSHTML); }
CMshtmlDialog:: CMshtmlDialog(UINT nResID, CWnd* pParent/*= NULL*/) { m_hWndParent = pParent pParent-〉GetSafeHwnd() : NULL; CString strTemp; strTemp.Format("%d", nResID); ResourceToURL(strTemp); CommonConstruct(); }
CMshtmlDialog::CMshtmlDialog(LPCTSTR lpszURL, BOOL bRes, CWnd* pParent/*= NULL*/) { m_hWndParent = pParent pParent-〉GetSafeHwnd() : NULL; if (bRes) { ResourceToURL(lpszURL); } else m_strURL = lpszURL; CommonConstruct(); }
int CMshtmlDialog::DoModal() { //First get the proc ShowHTMLDialog SHOWHTMLDIALOGFN *pfnShowHTMLDialog; pfnShowHTMLDialog = (SHOWHTMLDIALOGFN*)GetProcAddress(m_hInstMSHTML, TEXT("ShowHTMLDialog"));
if (!pfnShowHTMLDialog) return -1; //Now create a URL Moniker IMoniker* pmk = NULL; BSTR bstrURL = m_strURL.AllocSysString(); CreateURLMoniker(NULL, bstrURL, &pmk); if (!pmk) return -1; TCHAR* pchOptions = m_strOptions.IsEmpty() NULL : m_strOptions.GetBuffer(0);
//Now show the HTML Dialog HRESULT hr = (*pfnShowHTMLDialog)(m_hWndParent, pmk, m_varArgs, pchOptions, m_varReturn);
if (FAILED(hr))0 return -1; return 0; }
void CMshtmlDialog::CommonConstruct() { m_hInstMSHTML = ::LoadLibrary(TEXT("MSHTML.DLL")); }
inline void CMshtmlDialog::ResourceToURL(LPCTSTR lpszURL) { HINSTANCE hInstance = AfxGetResourceHandle(); ASSERT(hInstance != NULL); LPTSTR lpszModule = new TCHAR[_MAX_PATH]; if (GetModuleFileName(hInstance, lpszModule, _MAX_PATH)) { m_strURL.Format(_T("res://%s/%s"), lpszModule, lpszURL); } delete []lpszModule; }
void CMshtmlDialog::SetParam(VARIANT *pvarArgs) { m_varArgs = pvarArgs; }
void CMshtmlDialog::SetParam(LPCTSTR lpszArgs) { m_varArgs = lpszArgs; }
CString CMshtmlDialog::GetReturnString() { ASSERT(m_varReturn.vt == VT_BSTR); CString str = m_varReturn.bstrVal; return str; } LPCVARIANT CMshtmlDialog::GetReturnVariant() { return (LPCVARIANT)m_varReturn; }
void CMshtmlDialog::SetSize(int x, int y) { m_strOptions.Format("dialogWidth: %d; dialogHeight: %d", x, y); }
void CMshtmlDialog::SetDlgOptions(LPCTSTR lpszOptions) { m_strOptions = lpszOptions; }
|
使用CMshtmlDialog的一个简单例子
比如我们要在一个关于对话框里使用这个类,我们所要做工作是写一个HTML文件并把它以IDR_ABOUT_HTM包含进资源文件里。这里列出OnAppAbout的函数如下:
void CHDDemoApp::OnAppAbout() { CMshtmlDialog dlg(IDR_ABOUT_HTM, AfxGetMainWnd()); dlg.DoModal(); } |
还可以利用构造函数传递字符串资源或要显示的URLs,通过使用HTML中的图形和声音资源就可以在关于对话框中显示一个复杂的效果。
|