#pragma once
#include <afxhtml.h>
// CHtmlEditCtrlEx control
class CHtmlEditCtrlEx : public CHtmlEditCtrl
{
DECLARE_DYNCREATE(CHtmlEditCtrlEx)
protected:
public:
CHtmlEditCtrlEx() { m_fEnableContextMenu=true; };
virtual ~CHtmlEditCtrlEx() {};
BOOL CreateFromStatic( UINT nID, CWnd* pParent );
void EnableContextMenu( BOOL fEnab ) { m_fEnableContextMenu= fEnab; };
HRESULT GetDocumentHTML( CString& sHtml ); // override discards BOM
HRESULT SetDocumentHTML( CString& sHtml ); // override discards BOM
protected:
BOOL m_fEnableContextMenu;
DECLARE_MESSAGE_MAP()
public:
virtual BOOL PreTranslateMessage(MSG* pMsg); // context menu suppression
};
And here's the source code (HtmlEditCtrlEx.cpp):
#include "stdafx.h"
#include "HtmlEditCtrlEx.h"
// CHtmlEditCtrlEx
IMPLEMENT_DYNCREATE(CHtmlEditCtrlEx, CHtmlEditCtrl)
BEGIN_MESSAGE_MAP(CHtmlEditCtrlEx, CHtmlEditCtrl)
END_MESSAGE_MAP()
BOOL CHtmlEditCtrlEx::CreateFromStatic( UINT nID, CWnd* pParent ) {
CStatic wndStatic;
if ( !wndStatic.SubclassDlgItem(nID, pParent)) {
return( FALSE );
}
CRect rc;
wndStatic.GetWindowRect( &rc );
pParent->ScreenToClient( &rc );
return Create( 0, (WS_CHILD | WS_VISIBLE), rc, pParent, nID, 0 );
};
BOOL CHtmlEditCtrlEx::PreTranslateMessage(MSG* pMsg)
{
if ( !m_fEnableContextMenu ) {
switch (pMsg->message) {
case WM_CONTEXTMENU:
case WM_RBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
if (pMsg->message==WM_RBUTTONUP) {
// let parent handle context menu
GetParent()->SendMessage(WM_CONTEXTMENU, pMsg->wParam, pMsg->lParam);
}
return TRUE; // eat it
}
}
return CHtmlEditCtrl::PreTranslateMessage(pMsg);
}
// overide to discard BOM
HRESULT CHtmlEditCtrlEx::GetDocumentHTML( CString& sHtml )
{
HRESULT hr= CHtmlEditCtrl::GetDocumentHTML( sHtml );
if ( sHtml[0] != '<' ) {
sHtml= sHtml.Mid(3);
}
return hr;
}
HRESULT CHtmlEditCtrlEx::SetDocumentHTML( CString& sHtml )
{
HRESULT hr;
int nOffset=0;
if ( sHtml[0]==0xef && sHtml[1]==0xbb && sHtml[2]==0xbf ) { // BOM may be there
nOffset= 3;
}
hr= CHtmlEditCtrl::SetDocumentHTML( sHtml.Mid(nOffset) );
return hr;
}
m_ctlEditHtml.CreateFromStatic( IDST_HtmlBox, this );
// m_ctlEditHtml.EnableContextMenu( false ); // -- uncomment later
and add...
#include "HtmlEditCtrlEx.h"
...at the top of the dialog's header file.
void CEditHtmlDlg::OnBnClickedLoadfile() {
wchar_t szFilter[] = L"HTML files (*.htm)|*.htm;*.html|"
L"All Files (*.*)|*.*||";
CFileDialog dlg(TRUE,0,0,6,szFilter );
if ( dlg.DoModal()!=IDOK ) {
return;
}
//-------------------------- read the HTML file into memory
CString sFile= dlg.GetPathName();
CFile cf( sFile,CFile::modeRead );
int nLen= (int)cf.GetLength();
BYTE *p= new BYTE[nLen+2];
int n= cf.Read( p,nLen ); // read it all
p[nLen]=0; // Add null terminator for CString
m_sHtml= p; // save the HTML string as dialog member variable
delete p;
m_ctlEditHtml.SetDocumentHTML( m_sHtml ); // stuff it into the document
m_ctHtmlSrcText.SetWindowTextW( m_sHtml );// and the source view
}
void CEditHtmlDlg::OnBnClickedSavefile() {
m_ctlEditHtml.SaveAs(); // this one is easier :-)
}
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (2)
Commented:
Aside from the technical reasons, the following items made this a top article that got my vote among the EE Editors and my yes vote above.
(a) It's a good example for giving a clear purpose of the article.
(b) It's a good example of putting itself into a proper technical context: The Good; The Bad; The Ugly.
(c) It has very good flow. For example, a longer article like this needed a "Let's get started!" Also, having a separate how-to-use heading is (I think) essential in a longer article (the "To use this control" heading).
(d) It has a summary that gives the user another chance to understand if the article would be helpful.
(e) it gives references for those who want or need more information
Author
Commented: