📄 viewrich.cpp
字号:
ft.chrg.cpMin++;
}
#endif
ft.chrg.cpMin++;
}
if (m_lInitialSearchPos >= 0)
ft.chrg.cpMax = GetTextLength();
else
ft.chrg.cpMax = GetTextLength()+m_lInitialSearchPos;
DWORD dwFlags = bCase ? FR_MATCHCASE : 0;
dwFlags |= bWord ? FR_WHOLEWORD : 0;
// if we find the text return TRUE
if (FindAndSelect(dwFlags, ft) != -1)
return TRUE;
// if the original starting point was not the beginning of the buffer
// and we haven't already been here
else if (m_lInitialSearchPos > 0)
{
ft.chrg.cpMin = 0;
ft.chrg.cpMax = m_lInitialSearchPos;
m_lInitialSearchPos = m_lInitialSearchPos - GetTextLength();
return FindAndSelect(dwFlags, ft) != -1;
}
// not found
else
return FALSE;
}
long CRichEditView::FindAndSelect(DWORD dwFlags, FINDTEXTEX& ft)
{
long index = GetRichEditCtrl().FindText(dwFlags, &ft);
if (index != -1) // i.e. we found something
GetRichEditCtrl().SetSel(ft.chrgText);
return index;
}
void CRichEditView::TextNotFound(LPCTSTR lpszFind)
{
ASSERT_VALID(this);
m_bFirstSearch = TRUE;
OnTextNotFound(lpszFind);
}
void CRichEditView::OnTextNotFound(LPCTSTR)
{
MessageBeep(MB_ICONHAND);
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditView diagnostics
#ifdef _DEBUG
void CRichEditView::AssertValid() const
{
CCtrlView::AssertValid();
ASSERT_VALID(&m_aPageStart);
_AFX_RICHEDIT_STATE* pEditState = _afxRichEditState;
if (pEditState->pFindReplaceDlg != NULL)
ASSERT_VALID(pEditState->pFindReplaceDlg);
}
void CRichEditView::Dump(CDumpContext& dc) const
{
CCtrlView::Dump(dc);
AFX_DUMP1(dc, "\nm_aPageStart ", &m_aPageStart);
AFX_DUMP0(dc, "\n Static Member Data:");
_AFX_RICHEDIT_STATE* pEditState = _afxRichEditState;
if (pEditState->pFindReplaceDlg != NULL)
{
AFX_DUMP1(dc, "\npFindReplaceDlg = ",
(void*)pEditState->pFindReplaceDlg);
AFX_DUMP1(dc, "\nbFindOnly = ", pEditState->bFindOnly);
}
AFX_DUMP1(dc, "\nstrFind = ", pEditState->strFind);
AFX_DUMP1(dc, "\nstrReplace = ", pEditState->strReplace);
AFX_DUMP1(dc, "\nbCase = ", pEditState->bCase);
AFX_DUMP1(dc, "\nbWord = ", pEditState->bWord);
AFX_DUMP1(dc, "\nbNext = ", pEditState->bNext);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// OLE Client support and commands
BOOL CRichEditView::IsSelected(const CObject* pDocItem) const
{
return (pDocItem == GetSelectedItem());
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditDoc
CRichEditDoc::CRichEditDoc()
{
m_bRTF = TRUE;
m_bUpdateObjectCache = FALSE;
ASSERT_VALID(this);
}
CRichEditView* CRichEditDoc::GetView() const
{
// find the first view - if there are no views
// we must return NULL
POSITION pos = GetFirstViewPosition();
if (pos == NULL)
return NULL;
// find the first view that is a CRichEditView
CView* pView;
while (pos != NULL)
{
pView = GetNextView(pos);
if (pView->IsKindOf(RUNTIME_CLASS(CRichEditView)))
return (CRichEditView*) pView;
}
// can't find one--return NULL
return NULL;
}
BOOL CRichEditDoc::IsModified()
{
return GetView()->GetRichEditCtrl().GetModify();
}
void CRichEditDoc::SetModifiedFlag(BOOL bModified)
{
GetView()->GetRichEditCtrl().SetModify(bModified);
ASSERT(!!GetView()->GetRichEditCtrl().GetModify() == !!bModified);
}
COleClientItem* CRichEditDoc::GetInPlaceActiveItem(CWnd* pWnd)
{
ASSERT_KINDOF(CRichEditView, pWnd);
CRichEditView* pView = (CRichEditView*)pWnd;
return pView->GetInPlaceActiveItem();
}
void CRichEditDoc::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU)
{
// we call CDocument and not COleServerDoc because we don't want to do the
// SetHostNames stuff here. The richedit will do it. And we tell the richedit
// in SetTitle
CDocument::SetPathName(lpszPathName, bAddToMRU);
}
void CRichEditDoc::SetTitle(LPCTSTR lpszTitle)
{
USES_CONVERSION;
COleServerDoc::SetTitle(lpszTitle);
CRichEditView *pView = GetView();
ASSERT(pView != NULL);
ASSERT(pView->m_lpRichEditOle != NULL);
pView->m_lpRichEditOle->SetHostNames(T2CA(AfxGetAppName()),
T2CA(lpszTitle));
}
CRichEditCntrItem* CRichEditDoc::LookupItem(LPOLEOBJECT lpobj) const
{
POSITION pos = COleServerDoc::GetStartPosition();
CRichEditCntrItem* pItem;
while (pos != NULL)
{
pItem = (CRichEditCntrItem*) COleServerDoc::GetNextItem(pos);
// delete item is right type and not under construction
if (pItem->IsKindOf(RUNTIME_CLASS(CRichEditCntrItem)) &&
pItem->m_lpObject == lpobj)
{
return pItem;
}
}
return NULL;
}
CRichEditCntrItem* CRichEditDoc::CreateClientItem(REOBJECT* preo) const
{
// cast away constness of this
return new CRichEditCntrItem(preo, (CRichEditDoc*)this);
// a derived class typically needs to return its own item of a class
// derived from CRichEditCntrItem
}
void CRichEditDoc::MarkItemsClear() const
{
POSITION pos = COleServerDoc::GetStartPosition();
CRichEditCntrItem* pItem;
while (pos != NULL)
{
pItem = (CRichEditCntrItem*) COleServerDoc::GetNextItem(pos);
// Mark item as not in use unless under construction (i.e. m_lpObject == NULL)
if (pItem->IsKindOf(RUNTIME_CLASS(CRichEditCntrItem)))
pItem->Mark(pItem->m_lpObject == NULL);
}
}
void CRichEditDoc::DeleteUnmarkedItems() const
{
POSITION pos = COleServerDoc::GetStartPosition();
CRichEditCntrItem* pItem;
while (pos != NULL)
{
pItem = (CRichEditCntrItem*) COleServerDoc::GetNextItem(pos);
// Mark item as not in use unless under construction (i.e. m_lpObject == NULL)
if (pItem->IsKindOf(RUNTIME_CLASS(CRichEditCntrItem)) && !pItem->IsMarked())
delete pItem;
}
}
POSITION CRichEditDoc::GetStartPosition() const
{
if (m_bUpdateObjectCache)
((CRichEditDoc*)this)->UpdateObjectCache(); //cast away const
return COleServerDoc::GetStartPosition();
}
void CRichEditDoc::UpdateObjectCache()
{
CRichEditView* pView = GetView();
CRichEditCntrItem* pItem;
if (pView != NULL)
{
ASSERT(pView->m_lpRichEditOle != NULL);
MarkItemsClear();
long i,nCount = pView->m_lpRichEditOle->GetObjectCount();
for (i=0;i<nCount;i++)
{
CReObject reo; // needs to be in here so destructor called to release interfaces
HRESULT hr = pView->m_lpRichEditOle->GetObject(i, &reo, REO_GETOBJ_ALL_INTERFACES);
//reo interfaces are UNICODE
ASSERT(SUCCEEDED(hr));
if (GetScode(hr) == S_OK)
{
pItem = LookupItem(reo.poleobj);
if (pItem == NULL)
{
pItem = ((CRichEditDoc*)this)->CreateClientItem(&reo);
pItem->UpdateItemType();
}
ASSERT(pItem != NULL);
pItem->Mark(TRUE);
}
}
DeleteUnmarkedItems();
}
m_bUpdateObjectCache = FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditDoc Attributes
COleClientItem* CRichEditDoc::GetPrimarySelectedItem(CView* pView)
{
ASSERT(pView->IsKindOf(RUNTIME_CLASS(CRichEditView)));
return ((CRichEditView*)pView)->GetSelectedItem();
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditDoc Operations
void CRichEditDoc::DeleteContents()
{
COleServerDoc::DeleteContents();
CWaitCursor wait;
CRichEditView *pView = GetView();
if (pView != NULL)
{
pView->DeleteContents();
pView->GetRichEditCtrl().SetModify(FALSE);
ASSERT(!pView->GetRichEditCtrl().GetModify());
}
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditDoc serialization
void CRichEditDoc::Serialize(CArchive& ar)
{
CRichEditView *pView = GetView();
if (pView != NULL)
pView->Serialize(ar);
// we don't call the base class COleServerDoc::Serialize
// because we don't want the client items serialized
// the client items are handled directly by the RichEdit control
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditDoc diagnostics
#ifdef _DEBUG
void CRichEditDoc::AssertValid() const
{
COleServerDoc::AssertValid();
}
void CRichEditDoc::Dump(CDumpContext& dc) const
{
COleServerDoc::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CRichEditDoc commands
void CRichEditDoc::PreCloseFrame(CFrameWnd* pFrameArg)
{
ASSERT_VALID(this);
ASSERT_VALID(pFrameArg);
// turn off redraw so the user doesn't see the deactivation happening
BOOL bSetRedraw = FALSE;
if (pFrameArg->GetStyle() & WS_VISIBLE)
{
pFrameArg->SendMessage(WM_SETREDRAW, (WPARAM)FALSE);
bSetRedraw = TRUE;
}
// deactivate any inplace active items on this frame
GetView()->m_lpRichEditOle->InPlaceDeactivate();
POSITION pos = GetStartPosition();
CRichEditCntrItem* pItem;
while (pos != NULL)
{
pItem = (CRichEditCntrItem*) GetNextClientItem(pos);
if (pItem == NULL)
break;
ASSERT(pItem->IsKindOf(RUNTIME_CLASS(CRichEditCntrItem)));
pItem->Close();
}
// turn redraw back on
if (bSetRedraw)
pFrameArg->SendMessage(WM_SETREDRAW, (WPARAM)TRUE);
}
void CRichEditDoc::UpdateModifiedFlag()
{
// don't do anything here
// let the richedit handle all of this
}
COleServerItem* CRichEditDoc::OnGetEmbeddedItem()
{
ASSERT(FALSE);
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditCntrItem implementation
CRichEditCntrItem::CRichEditCntrItem(REOBJECT *preo, CRichEditDoc* pContainer)
: COleClientItem(pContainer)
{
m_bMark = FALSE;
m_bLock = FALSE;
if (preo != NULL)
{
ASSERT(preo->poleobj != NULL);
ASSERT(preo->pstg != NULL);
ASSERT(preo->polesite != NULL);
m_lpObject = preo->poleobj;
m_lpStorage = preo->pstg;
m_lpClientSite = preo->polesite;
m_lpObject->AddRef();
m_lpStorage->AddRef();
m_lpClientSite->AddRef();
}
else
{
m_lpObject = NULL;
m_lpStorage = NULL;
m_lpClientSite = NULL;
}
}
CRichEditCntrItem::~CRichEditCntrItem()
{
if (m_lpClientSite != NULL)
m_lpClientSite->Release();
}
void CRichEditCntrItem::OnDeactivateUI(BOOL bUndoable)
{
CView* pView = GetActiveView();
if (pView != NULL)
{
ASSERT(pView->GetParentFrame() != NULL);
pView->GetParentFrame()->SendMessage(WM_SETMESSAGESTRING,
(WPARAM)AFX_IDS_IDLEMESSAGE);
}
COleClientItem::OnDeactivateUI(bUndoable);
}
HRESULT CRichEditCntrItem::ShowContainerUI(BOOL b)
{
if (!CanActivate())
return E_NOTIMPL;
if (b)
{
OnDeactivateUI(FALSE);
OnDeactivate();
}
else
{
OnActivate();
OnActivateUI();
}
return S_OK;
}
BOOL CRichEditCntrItem::OnChangeItemPosition(const CRect& /*rectPos*/)
{
ASSERT_VALID(this);
// richedit handles this
return FALSE;
}
BOOL CRichEditCntrItem::CanActivate()
{
// Editing in-place while the server itself is being edited in-place
// does not work and is not supported. So, disable in-place
// activation in this case.
COleServerDoc* pDoc = DYNAMIC_DOWNCAST(COleServerDoc, GetDocument());
if (pDoc != NULL && pDoc->IsInPlaceActive())
return FALSE;
// otherwise, rely on default behavior
return COleClientItem::CanActivate();
}
HRESULT CRichEditCntrItem::GetWindowContext(LPOLEINPLACEFRAME* lplpFrame,
LPOLEINPLACEUIWINDOW* lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
CRect rc1,rc2;
if (!CanActivate())
return E_NOTIMPL;
return m_xOleIPSite.GetWindowContext(lplpFrame, lplpDoc, &rc1, &rc2, lpFrameInfo);
}
BOOL CRichEditCntrItem::ConvertTo(REFCLSID clsidNew)
{
USES_CONVERSION;
LPRICHEDITOLE preole = GetDocument()->GetView()->m_lpRichEditOle;
LPOLESTR lpOleStr;
OleRegGetUserType(clsidNew, USERCLASSTYPE_FULL, &lpOleStr);
LPCTSTR lpsz = OLE2CT(lpOleStr);
HRESULT hRes = preole->ConvertObject(REO_IOB_SELECTION, clsidNew, T2CA(lpsz));
CoTaskMemFree(lpOleStr);
return (SUCCEEDED(hRes));
}
BOOL CRichEditCntrItem::ActivateAs(LPCTSTR, REFCLSID clsidOld,
REFCLSID clsidNew)
{
LPRICHEDITOLE preole = GetDocument()->GetView()->m_lpRichEditOle;
HRESULT hRes = preole->ActivateAs(clsidOld, clsidNew);
return (SUCCEEDED(hRes));
}
void CRichEditCntrItem::SetDrawAspect(DVASPECT nDrawAspect)
{
LPRICHEDITOLE preole = GetDocument()->GetView()->m_lpRichEditOle;
preole->SetDvaspect(REO_IOB_SELECTION, nDrawAspect);
COleClientItem::SetDrawAspect(nDrawAspect);
}
void CRichEditCntrItem::SyncToRichEditObject(REOBJECT& reo)
{
COleClientItem::SetDrawAspect((DVASPECT)reo.dvaspect);
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditCntrItem diagnostics
#ifdef _DEBUG
void CRichEditCntrItem::AssertValid() const
{
COleClientItem::AssertValid();
}
void CRichEditCntrItem::Dump(CDumpContext& dc) const
{
COleClientItem::Dump(dc);
}
#endif
/////////////////////////////////////////////////////////////////////////////
LPOLECLIENTSITE CRichEditCntrItem::GetClientSite()
{
if (m_lpClientSite == NULL)
{
CRichEditDoc* pDoc = DYNAMIC_DOWNCAST(CRichEditDoc, GetDocument());
CRichEditView* pView = DYNAMIC_DOWNCAST(CRichEditView, pDoc->GetView());
ASSERT(pView->m_lpRichEditOle != NULL);
HRESULT hr = pView->m_lpRichEditOle->GetClientSite(&m_lpClientSite);
if (hr != S_OK)
AfxThrowOleException(hr);
}
ASSERT(m_lpClientSite != NULL);
return m_lpClientSite;
}
/////////////////////////////////////////////////////////////////////////////
#ifndef _AFX_ENABLE_INLINES
static const char _szAfxWinInl[] = "afxrich.inl";
#undef THIS_FILE
#define THIS_FILE _szAfxWinInl
#define _AFXRICH_INLINE
#include "afxrich.inl"
#endif //_AFX_ENABLE_INLINES
/////////////////////////////////////////////////////////////////////////////
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_SERIAL(CRichEditCntrItem, COleClientItem, 0)
IMPLEMENT_DYNAMIC(CRichEditDoc, COleServerDoc)
IMPLEMENT_DYNCREATE(CRichEditView, CCtrlView)
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -