⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 viewrich.cpp

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"

#ifdef AFX_CORE4_SEG
#pragma code_seg(AFX_CORE4_SEG)
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW

/////////////////////////////////////////////////////////////////////////////
// CReObject

class CReObject : public _reobject
{
public:
	CReObject();
	CReObject(CRichEditCntrItem* pItem);
	~CReObject();
};

CReObject::CReObject()
{
	cbStruct = sizeof(REOBJECT);
	memset(&cbStruct+1, 0, sizeof(*this)-sizeof(cbStruct));
}

CReObject::CReObject(CRichEditCntrItem* pItem)
{
	ASSERT(pItem != NULL);
	cbStruct = sizeof(REOBJECT);

	pItem->GetClassID(&clsid);
	poleobj = pItem->m_lpObject;
	pstg = pItem->m_lpStorage;
	polesite = pItem->m_lpClientSite;
	ASSERT(poleobj != NULL);
	ASSERT(pstg != NULL);
	ASSERT(polesite != NULL);
	poleobj->AddRef();
	pstg->AddRef();
	polesite->AddRef();

	sizel.cx = sizel.cy = 0; // let richedit determine initial size
	dvaspect = pItem->GetDrawAspect();
	dwFlags = REO_RESIZABLE;
	dwUser = 0;
}

CReObject::~CReObject()
{
	if (poleobj != NULL)
		poleobj->Release();
	if (pstg != NULL)
		pstg->Release();
	if (polesite != NULL)
		polesite->Release();
}

/////////////////////////////////////////////////////////////////////////////
// CRichEditView

AFX_STATIC const UINT _afxMsgFindReplace2 = ::RegisterWindowMessage(FINDMSGSTRING);

BEGIN_MESSAGE_MAP(CRichEditView, CCtrlView)
	//{{AFX_MSG_MAP(CRichEditView)
	ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateNeedSel)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateNeedClip)
	ON_UPDATE_COMMAND_UI(ID_EDIT_FIND, OnUpdateNeedText)
	ON_UPDATE_COMMAND_UI(ID_EDIT_REPEAT, OnUpdateNeedFind)
	ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_SPECIAL, OnUpdateEditPasteSpecial)
	ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_PROPERTIES, OnUpdateEditProperties)
	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateNeedSel)
	ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateNeedSel)
	ON_UPDATE_COMMAND_UI(ID_EDIT_SELECT_ALL, OnUpdateNeedText)
	ON_UPDATE_COMMAND_UI(ID_EDIT_REPLACE, OnUpdateNeedText)
	ON_COMMAND(ID_EDIT_CUT, OnEditCut)
	ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
	ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
	ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
	ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
	ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
	ON_COMMAND(ID_EDIT_FIND, OnEditFind)
	ON_COMMAND(ID_EDIT_REPLACE, OnEditReplace)
	ON_COMMAND(ID_EDIT_REPEAT, OnEditRepeat)
	ON_COMMAND(ID_EDIT_PASTE_SPECIAL, OnEditPasteSpecial)
	ON_COMMAND(ID_OLE_EDIT_PROPERTIES, OnEditProperties)
	ON_COMMAND(ID_OLE_INSERT_NEW, OnInsertObject)
	ON_COMMAND(ID_FORMAT_FONT, OnFormatFont)
	ON_WM_SIZE()
	ON_WM_CREATE()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
	ON_NOTIFY_REFLECT(EN_SELCHANGE, OnSelChange)
	ON_REGISTERED_MESSAGE(_afxMsgFindReplace2, OnFindReplaceCmd)
END_MESSAGE_MAP()

// richedit buffer limit -- let's set it at 16M
AFX_DATADEF ULONG CRichEditView::lMaxSize = 0xffffff;

/////////////////////////////////////////////////////////////////////////////
// CRichEditView construction/destruction

CRichEditView::CRichEditView() : CCtrlView(_T("RICHEDIT"), AFX_WS_DEFAULT_VIEW |
	WS_HSCROLL | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
	ES_MULTILINE | ES_NOHIDESEL | ES_SAVESEL | ES_SELECTIONBAR)
{
	m_bSyncCharFormat = m_bSyncParaFormat = TRUE;
	m_lpRichEditOle = NULL;
	m_nBulletIndent = 720; // 1/2 inch
	m_nWordWrap = WrapToWindow;
	m_nPasteType = 0;
	SetPaperSize(CSize(8*1440+720, 11*1440));
	SetMargins(CRect(0,0,0,0));
	m_charformat.cbSize = sizeof(CHARFORMAT);
	m_paraformat.cbSize = sizeof(PARAFORMAT);
}

BOOL CRichEditView::PreCreateWindow(CREATESTRUCT& cs)
{
	if (!AfxInitRichEdit())
		return FALSE;
	CCtrlView::PreCreateWindow(cs);
	cs.lpszName = _T("");

	cs.cx = cs.cy = 100; // necessary to avoid bug with ES_SELECTIONBAR and zero for cx and cy
	cs.style |= WS_CLIPSIBLINGS;

	return TRUE;
}

int CRichEditView::OnCreate(LPCREATESTRUCT lpcs)
{
	if (CCtrlView::OnCreate(lpcs) != 0)
		return -1;
	GetRichEditCtrl().LimitText(lMaxSize);
	GetRichEditCtrl().SetEventMask(ENM_SELCHANGE | ENM_CHANGE | ENM_SCROLL);
	VERIFY(GetRichEditCtrl().SetOLECallback(&m_xRichEditOleCallback));
	m_lpRichEditOle = GetRichEditCtrl().GetIRichEditOle();
	DragAcceptFiles();
	GetRichEditCtrl().SetOptions(ECOOP_OR, ECO_AUTOWORDSELECTION);
	WrapChanged();
	ASSERT(m_lpRichEditOle != NULL);
	return 0;
}

void CRichEditView::OnInitialUpdate()
{
	CCtrlView::OnInitialUpdate();
	m_bSyncCharFormat = m_bSyncParaFormat = TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CRichEditView document like functions

void CRichEditView::DeleteContents()
{
	ASSERT_VALID(this);
	ASSERT(m_hWnd != NULL);
	SetWindowText(_T(""));
	GetRichEditCtrl().EmptyUndoBuffer();
	m_bSyncCharFormat = m_bSyncParaFormat = TRUE;
	ASSERT_VALID(this);
}

void CRichEditView::WrapChanged()
{
	CWaitCursor wait;
	CRichEditCtrl& ctrl = GetRichEditCtrl();
	if (m_nWordWrap == WrapNone)
		ctrl.SetTargetDevice(NULL, 1);
	else if (m_nWordWrap == WrapToWindow)
		ctrl.SetTargetDevice(NULL, 0);
	else if (m_nWordWrap == WrapToTargetDevice) // wrap to ruler
	{
		AfxGetApp()->CreatePrinterDC(m_dcTarget);
		if (m_dcTarget.m_hDC == NULL)
			m_dcTarget.CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
		ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
	}
}

/////////////////////////////////////////////////////////////////////////////
// CRichEditView serialization support

class _afxRichEditCookie
{
public:
	CArchive& m_ar;
	DWORD m_dwError;
	_afxRichEditCookie(CArchive& ar) : m_ar(ar) {m_dwError=0;}
};

void CRichEditView::Serialize(CArchive& ar)
	// Read and write CRichEditView object to archive, with length prefix.
{
	ASSERT_VALID(this);
	ASSERT(m_hWnd != NULL);
	Stream(ar, FALSE);
	ASSERT_VALID(this);
}

void CRichEditView::Stream(CArchive& ar, BOOL bSelection)
{
	EDITSTREAM es = {0, 0, EditStreamCallBack};
	_afxRichEditCookie cookie(ar);
	es.dwCookie = (DWORD)&cookie;
	int nFormat = GetDocument()->GetStreamFormat();
	if (bSelection)
		nFormat |= SFF_SELECTION;
	if (ar.IsStoring())
		GetRichEditCtrl().StreamOut(nFormat, es);
	else
	{
		GetRichEditCtrl().StreamIn(nFormat, es);
		Invalidate();
	}
	if (cookie.m_dwError != 0)
		AfxThrowFileException(cookie.m_dwError);
}

// return 0 for no error, otherwise return error code
DWORD CALLBACK CRichEditView::EditStreamCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
	_afxRichEditCookie* pCookie = (_afxRichEditCookie*)dwCookie;
	CArchive& ar = pCookie->m_ar;
	ar.Flush();
	DWORD dw = 0;
	*pcb = cb;
	TRY
	{
		if (ar.IsStoring())
			ar.GetFile()->WriteHuge(pbBuff, cb);
		else
			*pcb = ar.GetFile()->ReadHuge(pbBuff, cb);
	}
	CATCH(CFileException, e)
	{
		*pcb = 0;
		pCookie->m_dwError = (DWORD)e->m_cause;
		dw = 1;
		DELETE_EXCEPTION(e);
	}
	AND_CATCH_ALL(e)
	{
		*pcb = 0;
		pCookie->m_dwError = (DWORD)CFileException::generic;
		dw = 1;
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL
	return dw;
}

/////////////////////////////////////////////////////////////////////////////
// CRichEditView Printing support

void CRichEditView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo*)
{
	ASSERT_VALID(this);
//  ASSERT_VALID(pDC);
	// initialize page start vector
	ASSERT(m_aPageStart.GetSize() == 0);
	m_aPageStart.Add(0);
	ASSERT(m_aPageStart.GetSize() > 0);
	GetRichEditCtrl().FormatRange(NULL, FALSE); // required by RichEdit to clear out cache

	ASSERT_VALID(this);
}

BOOL CRichEditView::PaginateTo(CDC* pDC, CPrintInfo* pInfo)
	// attempts pagination to pInfo->m_nCurPage, TRUE == success
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDC);

	CRect rectSave = pInfo->m_rectDraw;
	UINT nPageSave = pInfo->m_nCurPage;
	ASSERT(nPageSave > 1);
	ASSERT(nPageSave >= (UINT)m_aPageStart.GetSize());
	VERIFY(pDC->SaveDC() != 0);
	pDC->IntersectClipRect(0, 0, 0, 0);
	pInfo->m_nCurPage = m_aPageStart.GetSize();
	while (pInfo->m_nCurPage < nPageSave)
	{
		ASSERT(pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize());
		OnPrepareDC(pDC, pInfo);
		ASSERT(pInfo->m_bContinuePrinting);
		pInfo->m_rectDraw.SetRect(0, 0,
			pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
		pDC->DPtoLP(&pInfo->m_rectDraw);
		OnPrint(pDC, pInfo);
		if (pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize())
			break;
		++pInfo->m_nCurPage;
	}
	BOOL bResult = pInfo->m_nCurPage == nPageSave;
	pDC->RestoreDC(-1);
	pInfo->m_nCurPage = nPageSave;
	pInfo->m_rectDraw = rectSave;
	ASSERT_VALID(this);
	return bResult;
}

void CRichEditView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDC);
	ASSERT(pInfo != NULL);  // overriding OnPaint -- never get this.

	pDC->SetMapMode(MM_TEXT);

	if (pInfo->m_nCurPage > (UINT)m_aPageStart.GetSize() &&
		!PaginateTo(pDC, pInfo))
	{
		// can't paginate to that page, thus cannot print it.
		pInfo->m_bContinuePrinting = FALSE;
	}
	ASSERT_VALID(this);
}

long CRichEditView::PrintPage(CDC* pDC, long nIndexStart, long nIndexStop)
	// worker function for laying out text in a rectangle.
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDC);
	FORMATRANGE fr;

	// offset by printing offset
	pDC->SetViewportOrg(-pDC->GetDeviceCaps(PHYSICALOFFSETX),
		-pDC->GetDeviceCaps(PHYSICALOFFSETY));
	// adjust DC because richedit doesn't do things like MFC
	if (::GetDeviceCaps(pDC->m_hDC, TECHNOLOGY) != DT_METAFILE && pDC->m_hAttribDC != NULL)
	{
		::ScaleWindowExtEx(pDC->m_hDC,
			::GetDeviceCaps(pDC->m_hDC, LOGPIXELSX),
			::GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSX),
			::GetDeviceCaps(pDC->m_hDC, LOGPIXELSY),
			::GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSY), NULL);
	}

	fr.hdcTarget = pDC->m_hAttribDC;
	fr.hdc = pDC->m_hDC;
	fr.rcPage = GetPageRect();
	fr.rc = GetPrintRect();

	fr.chrg.cpMin = nIndexStart;
	fr.chrg.cpMax = nIndexStop;
	long lRes = GetRichEditCtrl().FormatRange(&fr,TRUE);
	return lRes;
}

long CRichEditView::PrintInsideRect(CDC* pDC, RECT& rectLayout,
	long nIndexStart, long nIndexStop, BOOL bOutput)
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDC);
	FORMATRANGE fr;

	// adjust DC because richedit doesn't do things like MFC
	if (::GetDeviceCaps(pDC->m_hDC, TECHNOLOGY) != DT_METAFILE && pDC->m_hAttribDC != NULL)
	{
		::ScaleWindowExtEx(pDC->m_hDC,
			::GetDeviceCaps(pDC->m_hDC, LOGPIXELSX),
			::GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSX),
			::GetDeviceCaps(pDC->m_hDC, LOGPIXELSY),
			::GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSY), NULL);
	}

	fr.hdcTarget = pDC->m_hAttribDC;
	fr.hdc = pDC->m_hDC;
	// convert rect to twips
	fr.rcPage = rectLayout;
	fr.rc = rectLayout;

	fr.chrg.cpMin = nIndexStart;
	fr.chrg.cpMax = nIndexStop;
	GetRichEditCtrl().FormatRange(NULL, FALSE); // required by RichEdit to clear out cache
	// if bOutput is FALSE, we only measure
	long lres = GetRichEditCtrl().FormatRange(&fr, bOutput);
	GetRichEditCtrl().FormatRange(NULL, FALSE); // required by RichEdit to clear out cache

	rectLayout = fr.rc;
	return lres;
}

void CRichEditView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDC);
	ASSERT(pInfo != NULL);
	ASSERT(pInfo->m_bContinuePrinting);

	UINT nPage = pInfo->m_nCurPage;
	ASSERT(nPage <= (UINT)m_aPageStart.GetSize());
	long nIndex = (long) m_aPageStart[nPage-1];

	// print as much as possible in the current page.
	nIndex = PrintPage(pDC, nIndex, 0xFFFFFFFF);

	if (nIndex >= GetTextLength())
	{
		TRACE0("End of Document\n");
		pInfo->SetMaxPage(nPage);
	}

	// update pagination information for page just printed
	if (nPage == (UINT)m_aPageStart.GetSize())
	{
		if (nIndex < GetTextLength())
			m_aPageStart.Add(nIndex);
	}
	else
	{
		ASSERT(nPage+1 <= (UINT)m_aPageStart.GetSize());
		ASSERT(nIndex == (long)m_aPageStart[nPage+1-1]);
	}
}


void CRichEditView::OnEndPrinting(CDC*, CPrintInfo*)
{
	ASSERT_VALID(this);
	GetRichEditCtrl().FormatRange(NULL, FALSE); // required by RichEdit to clear out cache
	m_aPageStart.RemoveAll();
}

/////////////////////////////////////////////////////////////////////////////
// CRichEditView::XRichEditOleCallback

BEGIN_INTERFACE_MAP(CRichEditView, CCtrlView)
	// we use IID_IUnknown because richedit doesn't define an IID
	INTERFACE_PART(CRichEditView, IID_IUnknown, RichEditOleCallback)
END_INTERFACE_MAP()

STDMETHODIMP_(ULONG) CRichEditView::XRichEditOleCallback::AddRef()
{
	METHOD_PROLOGUE_EX_(CRichEditView, RichEditOleCallback)
	return (ULONG)pThis->InternalAddRef();
}

STDMETHODIMP_(ULONG) CRichEditView::XRichEditOleCallback::Release()
{
	METHOD_PROLOGUE_EX_(CRichEditView, RichEditOleCallback)
	return (ULONG)pThis->InternalRelease();
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::QueryInterface(
	REFIID iid, LPVOID* ppvObj)
{
	METHOD_PROLOGUE_EX_(CRichEditView, RichEditOleCallback)
	return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::GetNewStorage(LPSTORAGE* ppstg)
{
	METHOD_PROLOGUE_EX_(CRichEditView, RichEditOleCallback)

	// Create a flat storage and steal it from the client item
	// the client item is only used for creating the storage
	COleClientItem item;
	item.GetItemStorageFlat();
	*ppstg = item.m_lpStorage;
	HRESULT hRes = E_OUTOFMEMORY;
	if (item.m_lpStorage != NULL)
	{
		item.m_lpStorage = NULL;
		hRes = S_OK;
	}
	pThis->GetDocument()->InvalidateObjectCache();
	return hRes;
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::GetInPlaceContext(
	LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc,
	LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
	METHOD_PROLOGUE_EX(CRichEditView, RichEditOleCallback)
	return pThis->GetWindowContext(lplpFrame, lplpDoc, lpFrameInfo);
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::ShowContainerUI(BOOL fShow)
{
	METHOD_PROLOGUE_EX(CRichEditView, RichEditOleCallback)
	return pThis->ShowContainerUI(fShow);
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::QueryInsertObject(
	LPCLSID /*lpclsid*/, LPSTORAGE /*pstg*/, LONG /*cp*/)
{
	METHOD_PROLOGUE_EX(CRichEditView, RichEditOleCallback)
	pThis->GetDocument()->InvalidateObjectCache();
	return S_OK;
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::DeleteObject(LPOLEOBJECT /*lpoleobj*/)
{
	METHOD_PROLOGUE_EX_(CRichEditView, RichEditOleCallback)
	pThis->GetDocument()->InvalidateObjectCache();
	return S_OK;
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::QueryAcceptData(
	LPDATAOBJECT lpdataobj, CLIPFORMAT* lpcfFormat, DWORD reco,
	BOOL fReally, HGLOBAL hMetaPict)
{
	METHOD_PROLOGUE_EX(CRichEditView, RichEditOleCallback)
	return pThis->QueryAcceptData(lpdataobj, lpcfFormat, reco,
		fReally, hMetaPict);
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::ContextSensitiveHelp(BOOL /*fEnterMode*/)
{
	return E_NOTIMPL;
}

STDMETHODIMP CRichEditView::XRichEditOleCallback::GetClipboardData(
	CHARRANGE* lpchrg, DWORD reco, LPDATAOBJECT* lplpdataobj)
{
	METHOD_PROLOGUE_EX(CRichEditView, RichEditOleCallback)
	LPDATAOBJECT lpOrigDataObject = NULL;

	// get richedit's data object

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -