DHTML User Interface Library
Implement an advanced DHTML user interface in your own MFC applications
Current Version: DHTMLUI v1.00 build 47
Index
Introduction
Have you ever wanted to make an application similar to Microsoft« Outlook Express« without resorting to ATL? The DHTMLUI library allows you to implement such an advanced DHTML user interface in your own MFC applications! This library is the latest version in a series of continuously updated classes which I have been using in one of my own projects. DHTMLUI started life as a part of my original application, but when my project crested more than 800K of raw source code, I decided to break my code into bite size chunks and so DHTMLUI was born.
Microsoft« Outlook Express«
My previous article, "Processing HTML
Forms From a CHtmlView", shows a very basic technique for retrieving form
data using a standard CHtmlView
. This technique is fine for basic
forms, but what if you want to notify your program when a selection is made from
a list of radio buttons? Well, this library makes this all possible!
NOTE: This library is by no means what I would consider to be complete! There are classes in which functions have been defined, but there is no actual code in them. This is a result of laziness on my part! If you need to use a particular function and it has no code, let me know and I will fill in the details for you, unless of course you want to do it! Please submit a copy of any changed files to me via e-mail - crowtc@gmail.com - and I will make the changes to the master copy.
About the DHTMLUI Library
The DHTMLUI Library simplifies the use of the myriad COM methods and properties used in conjunction with a browser window. The library also allows you to override the functionality associated with almost every event, feature request and property change. This library allows you to implement almost every feature present in Internet Explorer! This kind of power comes at a cost though, browsing through the library source code is like trying to read a popular novel that has been translated into Old English!
This library is based on information I have collected from various sources, including the Microsoft Internet Explorer 5.5 SDK, MSDN and the Platform SDK. There are bits and pieces from Microsoft samples, pieces gleaned from numerous websites and a lot of my own "This function isn't documented, but let's see what I can do with it" original code.
Enjoy!
Using the DHTMLUI Library
Getting Started
Before using this library, you should make sure you have the Platform SDK installed and the paths are set in your Options...Directories tab. If you want to use Internet Explorer 5.x features, you want to make sure the SDK is installed as well, but it is not 100% necessary for normal operation. To make everything work, you must also have the corresponding version of Internet Explorer installed!
Extract the Library
Extract the DHTMLUI Library where you want, but be sure to configure the path in your directories tab.
Open and Compile the Project
Open the DHTMLUI workspace and open the class labeled
__DHTMLUI_Config
, or DHTMLUIConfig.h
. This class is a
dummy class to help me open the configuration file (lazy huh?). Well, anyway -
go through the file and set the options for the library, it is pretty well
documented in the file and should be pretty easy to do.
Save the file and do a complete rebuild both Debug and Release configurations, just to make sure they compile correctly. If they don't compile, please check the library dependencies before flaming me or blasting my email with epithets that would make a "Hell's Angel" ask to leave the room.
When you get it to compile, you may continue on with the next step.
Setting up your Project
I made this library to be used as a drop-in replacement for CHtmlView, so setting it up in an existing project is pretty easy. If you don't have an existing project, use the MFC AppWizard to create a project which uses Automation and set up the application's primary view as a CHtmlView. If your existing project does not have automation enabled, you will only need to add it if you want your embedded DHTML pages to be able to access your application via COM.
Once you have a project with a CHtmlView you will need to add the following
lines (Bold) to the project's STDAFX.H
file if they aren't
already there:
// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX_STDAFX_H__1F9F46AD_DDF4_4D29_BC06_592204E7F660__INCLUDED_) #define AFX_STDAFX_H__1F9F46AD_DDF4_4D29_BC06_592204E7F660__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxadv.h> #include <afxdisp.h> // MFC Automation classes #ifndef _AFX_NO_DB_SUPPORT #include <afxdb.h> // MFC ODBC database classes #endif // _AFX_NO_DB_SUPPORT #ifndef _AFX_NO_DAO_SUPPORT #include <afxdao.h> // MFC DAO database classes #endif // _AFX_NO_DAO_SUPPORT #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common // Controls #ifndef _AFX_NO_AFXCMN_SUPPORT #include <afxcmn.h> // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT #include <afxhtml.h> // MFC HTML view support #include <dhtmlui.h> // Dynamic HTML User Interface Library //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately // before the previous line. #endif //!defined(AFX_STDAFX_H__1F9F46AD_DDF4_4D29_BC06_592204E7F660__INCLUDED_)
In your CHtmlView
derived class header file, add a define to
replace CHtmlView
with CHtmlViewEx
. This enables you
to keep using the name CHtmlView
when you refer to the class and
there is a lot less typing involved.
///////////////////////////////////////////////////////////////////////////// #define CHtmlView CHtmlViewEx ///////////////////////////////////////////////////////////////////////////// class CWorksheetView : public CHtmlView { protected: // create from serialization only CWorksheetView(); DECLARE_DYNCREATE(CWorksheetView) ...
In your CDocument
class, you should have an automation
interface, this is where you will add property and method extensions to DHTML.
The methods you add here will become available to JavaScript and VBScript
through the window.external
interface.
Basically, if you add a method called LoadFormData
defined
as:
afx_msg void LoadFormData( long PageNumber ); ------ void CWorksheetDoc::LoadFormData(long PageNumber) { GET_CURRENT_VIEW(pView); switch(PageNumber) { case 1: ... default: break; } }
You can call LoadFormData
from your embedded web pages as
such:
<script language="JavaScript">
<!--
function window_onload( page )
{
window.external.LoadFormData( page );
}
//-->
</script>
You do basically the same thing for properties, except that return values of non-integral types are usually passed by reference.
Special Features of this Library
The DHTMUI Library has a number of capabilities which set it apart from CHtmlView. The number of features is too great to go into much detail on each of them, so I will include some of the header files and you can read more about them in the source code documentation.
// HtmlViewEx.h : header file // ////////////////////////////////////////////////////////////////// #ifndef __HTMLVIEWEX_H__ #define __HTMLVIEWEX_H__ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #ifndef __mshtmhst_h__ #include <mshtmhst.h> #endif #include <mshtml.h> // IE/MSHTML Interface Definitions // Forward Declarations class CHtmlViewExOccManager; // The available commands #define HTMLID_FIND 1 #define HTMLID_VIEWSOURCE 2 #define HTMLID_OPTIONS 3 // Names for SetSecureLockIcon() values #define SECURELOCKICON_UNSECURE 0 #define SECURELOCKICON_MIXED 1 #define SECURELOCKICON_SECURE_UNKNOWNBITS 2 #define SECURELOCKICON_SECURE_40BIT 3 #define SECURELOCKICON_SECURE_56BIT 4 #define SECURELOCKICON_SECURE_FORTEZZA 5 #define SECURELOCKICON_SECURE_128BIT 6 // Kill some of the MFC garbage #undef AFX_DATA #define AFX_DATA /////////////////////////////////////////////////////////////////// // CHtmlViewEx class class _INS_EXT_CLASS CHtmlViewEx : public CFormView { DECLARE_DYNCREATE(CHtmlViewEx) /////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////// public: CHtmlViewEx(); /////////////////////////////////////////////////////////////////// // Attributes /////////////////////////////////////////////////////////////////// protected: CHtmlViewExOccManager* m_pHtmlViewExOccManager; int m_nFontSize; BOOL m_bNoStatusText; BOOL m_bOfflineIfNotConnected; BOOL m_bSilentMode; CString m_strUserAgent; public: void SetNoStatusText(BOOL bNoStatus = TRUE); int GetFontSize() const; void SetFontSize(int fontSize = 2); CString GetType() const; long GetLeft() const; void SetLeft(long nNewValue); long GetTop() const; void SetTop(long nNewValue); long GetHeight() const; void SetHeight(long nNewValue); void SetVisible(BOOL bNewValue); BOOL GetVisible() const; CString GetLocationName() const; READYSTATE GetReadyState() const; BOOL GetOffline() const; void SetOffline(BOOL bNewValue); BOOL GetSilent() const; void SetSilent(BOOL bNewValue); BOOL GetTopLevelContainer() const; CString GetLocationURL() const; BOOL GetBusy() const; LPDISPATCH GetApplication() const; LPDISPATCH GetParentBrowser() const; LPDISPATCH GetContainer() const; LPDISPATCH GetHtmlDocument() const; CString GetFullName() const; int GetToolBar() const; void SetToolBar(int nNewValue); BOOL GetMenuBar() const; void SetMenuBar(BOOL bNewValue); BOOL GetFullScreen() const; void SetFullScreen(BOOL bNewValue); OLECMDF QueryStatusWB(OLECMDID cmdID) const; BOOL GetRegisterAsBrowser() const; void SetRegisterAsBrowser(BOOL bNewValue); BOOL GetRegisterAsDropTarget() const; void SetRegisterAsDropTarget(BOOL bNewValue); BOOL GetTheaterMode() const; void SetTheaterMode(BOOL bNewValue); BOOL GetAddressBar() const; void SetAddressBar(BOOL bNewValue); BOOL GetStatusBar() const; void SetStatusBar(BOOL bNewValue); CString GetUserAgent() const; void SetUserAgent(LPCTSTR strNewValue); /////////////////////////////////////////////////////////////////// // Operations /////////////////////////////////////////////////////////////////// public: #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif /////////////////////////////////////////////////////////////////// // New CHtmlViewEx Operations // public: // Helper for OLE Commands to the WebBrowser void ExecCmdTarget(DWORD nCmdID); // Helper for parsing POST Data CString GetValueFromPostData(LPCTSTR strPostData, LPCTSTR strValName); /////////////////////////////////////////////////////////////////// // Setup Functions /////////////////////////////////////////////////////////////////// // These functions are primarily for doing the initial setup // of a form upon load. Most other actions should be performed // within the form page itself. /////////////////////////////////////////////////////////////////// public: IDispatch* GetInputElementByName(LPCTSTR lpszElementName); IDispatch* GetSelectElementByName(LPCTSTR lpszElementName); IDispatch* GetTextAreaElementByName(LPCTSTR lpszElementName); protected: IHTMLOptionElementFactory* GetOptionElementFactory(); public: /////////////////////////////////////////////////////////////////// // General Input Controls BOOL SetInputTextValue(LPCTSTR lpszFieldName, LPCTSTR lpszValue); CString GetInputTextValue(LPCTSTR lpszFieldName); /////////////////////////////////////////////////////////////////// // Drop-down list / list box BOOL RemoveAllOptionElements(LPCTSTR lpszFieldName); BOOL AddOptionElement(LPCTSTR lpszFieldName, LPCTSTR lpszOptionText, LPCTSTR lpszOptionValue = NULL, BOOL bSelected = FALSE, BOOL bDefault = FALSE, long nBefore = -1); BOOL ClearSelection(LPCTSTR lpszFieldName); BOOL SetOptionSelected(LPCTSTR lpszFieldName, LPCTSTR lpszOptionText); /////////////////////////////////////////////////////////////////// // Checkbox Specific BOOL SetCheck(LPCTSTR lpszFieldName); BOOL ClearCheck(LPCTSTR lpszFieldName); /////////////////////////////////////////////////////////////////// // Regular Button Specific BOOL SetButtonAction(LPCTSTR lpszFieldName, LPCTSTR lpszAction); /////////////////////////////////////////////////////////////////// // Radio Button Specific BOOL SetRadioSelected(LPCTSTR lpszFieldName, BOOL bSelected); BOOL SetRadioDisabled(LPCTSTR lpszFieldName, BOOL bDisabled); public: /////////////////////////////////////////////////////////////////// // NOTE: If you use these functions, you must navigate to a // page for them to take effect! // // Use "Navigate2(GetLocationURL(), 0, NULL, NULL);" to navigate // to the page currently displayed /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // DocHostUIHandler DoubleClick interface functions DWORD GetUI_DblClk() const; void SetUI_DblClk(DWORD dwSet); /////////////////////////////////////////////////////////////////// // DocHostUIHandler Flags interface functions DWORD GetUI_Flags() const; void SetUI_Flags(DWORD dwSet); BOOL GetUIFlag_Dialog() const; BOOL GetUIFlag_DisableHelpMenu() const; BOOL GetUIFlag_No3dBorder() const; BOOL GetUIFlag_NoScrollbar() const; BOOL GetUIFlag_DisableScriptInactive() const; BOOL GetUIFlag_OpenNewWin() const; BOOL GetUIFlag_DisableOffscreen() const; BOOL GetUIFlag_FlatScrollbar() const; BOOL GetUIFlag_DivBlockDefault() const; BOOL GetUIFlag_ActivateClientHitOnly() const; void SetUIFlag_Dialog(BOOL bSet); void SetUIFlag_DisableHelpMenu(BOOL bSet); void SetUIFlag_No3dBorder(BOOL bSet); void SetUIFlag_NoScrollbar(BOOL bSet); void SetUIFlag_DisableScriptInactive(BOOL bSet); void SetUIFlag_OpenNewWin(BOOL bSet); void SetUIFlag_DisableOffscreen(BOOL bSet); void SetUIFlag_FlatScrollbar(BOOL bSet); void SetUIFlag_DivBlockDefault(BOOL bSet); void SetUIFlag_ActivateClientHitOnly(BOOL bSet); /////////////////////////////////////////////////////////////////// // Basic CHtmlView Operations // public: void GoBack(); void GoForward(); void GoHome(); void GoSearch(); void Navigate(LPCTSTR URL, DWORD dwFlags = 0, LPCTSTR lpszTargetFrameName = NULL, LPCTSTR lpszHeaders = NULL, LPVOID lpvPostData = NULL, DWORD dwPostDataLen = 0); void Navigate2(LPITEMIDLIST pIDL, DWORD dwFlags = 0, LPCTSTR lpszTargetFrameName = NULL); void Navigate2(LPCTSTR lpszURL, DWORD dwFlags = 0, LPCTSTR lpszTargetFrameName = NULL, LPCTSTR lpszHeaders = NULL, LPVOID lpvPostData = NULL, DWORD dwPostDataLen = 0); void Navigate2(LPCTSTR lpszURL, DWORD dwFlags, CByteArray& baPostedData, LPCTSTR lpszTargetFrameName = NULL, LPCTSTR lpszHeader = NULL); void Refresh(); void Refresh2(int nLevel); void Stop(); void PutProperty(LPCTSTR lpszProperty, const VARIANT& vtValue); void PutProperty(LPCTSTR lpszPropertyName, double dValue); void PutProperty(LPCTSTR lpszPropertyName, LPCTSTR lpszValue); void PutProperty(LPCTSTR lpszPropertyName, long lValue); void PutProperty(LPCTSTR lpszPropertyName, short nValue); BOOL GetProperty(LPCTSTR lpszProperty, CString& strValue); COleVariant GetProperty(LPCTSTR lpszProperty); void ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt, VARIANT* pvaIn, VARIANT* pvaOut); BOOL LoadFromResource(LPCTSTR lpszResource); BOOL LoadFromResource(UINT nRes); /////////////////////////////////////////////////////////////////// // Overrides /////////////////////////////////////////////////////////////////// // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CHtmlViewEx) public: virtual void OnDraw(CDC* pDC); virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,CCreateContext* pContext = NULL); virtual BOOL OnAmbientProperty(COleControlSite* pSite, DISPID dispid, VARIANT* pvar); //}}AFX_VIRTUAL /////////////////////////////////////////////////////////////////// // Overridable Event Notifications // public: virtual void OnNavigateComplete2(LPCTSTR strURL); virtual void OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, LPCTSTR strPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel); virtual void OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, CByteArray& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel); virtual void OnStatusTextChange(LPCTSTR lpszText); virtual void OnProgressChange(long nProgress, long nProgressMax); virtual void OnCommandStateChange(long nCommand, BOOL bEnable); virtual void OnDownloadBegin(); virtual void OnDownloadComplete(); virtual void OnTitleChange(LPCTSTR lpszText); virtual void OnPropertyChange(LPCTSTR lpszProperty); virtual void OnNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel); virtual void OnDocumentComplete(LPCTSTR lpszURL); virtual void OnQuit(); virtual void OnVisible(BOOL bVisible); virtual void OnToolBar(BOOL bToolBar); virtual void OnMenuBar(BOOL bMenuBar); virtual void OnStatusBar(BOOL bStatusBar); virtual void OnFullScreen(BOOL bFullScreen); virtual void OnTheaterMode(BOOL bTheaterMode); virtual void OnFilePrint(); // Formerly unimplemented virtual void OnAddressBar(BOOL bAddressBar); virtual void OnAppCmd(LPCTSTR lpszAppCmd, LPCTSTR PostData); virtual void OnAdvancedContextMenu(DWORD dwID, CPoint ptPosition, IUnknown* pCommandTarget, IDispatch* pDispatchObjectHit); virtual void OnShowHelp(HWND hwnd, LPCTSTR pszHelpFile, UINT uCommand,DWORD dwData,POINT ptMouse, IDispatch __RPC_FAR *pDispatchObjectHit); virtual void OnShowMessage(HWND hwnd, LPCTSTR lpstrText, LPCTSTR lpstrCaption, DWORD dwType, LPCTSTR lpstrHelpFile, DWORD dwHelpContext, LRESULT __RPC_FAR *plResult); virtual void OnViewSource(); virtual void OnToolsInternetOptions(); virtual void OnEditCut(); virtual void OnEditCopy(); virtual void OnEditPaste(); virtual void OnEditSelectall(); virtual void OnEditFindOnThisPage(); virtual void OnWindowSetResizable(BOOL Resizable); virtual void OnWindowClosing(BOOL IsChildWindow, BOOL* Cancel); virtual void OnWindowSetLeft(long left); virtual void OnWindowSetTop(long Top); virtual void OnWindowSetWidth(long Width); virtual void OnWindowSetHeight(long Height); virtual void OnClientToHostWindow(long* CX, long* CY); virtual void OnSetSecureLockIcon(long SecureLockIcon); virtual void OnFileDownload(BOOL* Cancel); /////////////////////////////////////////////////////////////////// // Implementation /////////////////////////////////////////////////////////////////// protected: IWebBrowser2* m_pBrowserApp; public: virtual ~CHtmlViewEx(); CWnd m_wndBrowser; /////////////////////////////////////////////////////////////////// // Event reflectors (not normally overridden) protected: virtual void NavigateComplete2(LPDISPATCH pDisp, VARIANT* URL); virtual void BeforeNavigate2(LPDISPATCH pDisp, VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers, BOOL* Cancel); virtual void DocumentComplete(LPDISPATCH pDisp, VARIANT* URL); /////////////////////////////////////////////////////////////////// // Internal Helper Functions protected: char CharTokenToChar(const CString &val); CString ProcessCharCodes(LPCTSTR lpszInput); void RemoveAllOptionElements_(IHTMLSelectElement* pSelectElem); // Custom UI Toggles void UseCustomHelp(BOOL bSet); void UseCustomMessage(BOOL bSet); void UseCustomContextMenu(BOOL bSet); void UseAdvancedContextMenu(BOOL bSet); /////////////////////////////////////////////////////////////////// // Generated message map functions protected: //{{AFX_MSG(CHtmlViewEx) afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnPaint(); afx_msg void OnDestroy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() DECLARE_EVENTSINK_MAP() }; #undef AFX_DATA #define AFX_DATA ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately // before the previous line. /////////////////////////////////////////////////////////////////// // Inline Functions (They looked too messy in this file) #include "HtmlViewEx.inl" #endif // __HTMLVIEWEX_H_
In Conclusion
As I said up above, this library is far from complete. If you have any bug fixes, comments or contributions to help make this library more complete, feel free to contact me via e-mail. You can do a LOT with the library just as it is, but as most code goes, it can always be better.
You are free to use this library for anything, but if you are using it in an application that will be distributed commercially or for enterprise internal distribution, or want to include it in a larger library, you must contact me before you release it. I will not charge you for it, I just want to know where it's being used to consider providing full support for it.
Thank You,
Ted Crow
Infinity Networking Solutions