📄 viewrich.cpp
字号:
if (FAILED(pThis->m_lpRichEditOle->GetClipboardData(lpchrg, reco,
&lpOrigDataObject)))
{
return E_NOTIMPL;
}
// allow changes
HRESULT hRes = pThis->GetClipboardData(lpchrg, reco, lpOrigDataObject,
lplpdataobj);
// if changed then free original object
if (SUCCEEDED(hRes))
{
if (lpOrigDataObject!=NULL)
lpOrigDataObject->Release();
return hRes;
}
else
{
// use richedit's data object
*lplpdataobj = lpOrigDataObject;
return S_OK;
}
}
STDMETHODIMP CRichEditView::XRichEditOleCallback::GetDragDropEffect(
BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect)
{
if (!fDrag) // allowable dest effects
{
DWORD dwEffect;
// check for force link
if ((grfKeyState & (MK_CONTROL|MK_SHIFT)) == (MK_CONTROL|MK_SHIFT))
dwEffect = DROPEFFECT_LINK;
// check for force copy
else if ((grfKeyState & MK_CONTROL) == MK_CONTROL)
dwEffect = DROPEFFECT_COPY;
// check for force move
else if ((grfKeyState & MK_ALT) == MK_ALT)
dwEffect = DROPEFFECT_MOVE;
// default -- recommended action is move
else
dwEffect = DROPEFFECT_MOVE;
if (dwEffect & *pdwEffect) // make sure allowed type
*pdwEffect = dwEffect;
}
return S_OK;
}
STDMETHODIMP CRichEditView::XRichEditOleCallback::GetContextMenu(
WORD seltype, LPOLEOBJECT lpoleobj, CHARRANGE* lpchrg,
HMENU* lphmenu)
{
METHOD_PROLOGUE_EX(CRichEditView, RichEditOleCallback)
HMENU hMenu = pThis->GetContextMenu(seltype, lpoleobj, lpchrg);
if (hMenu == NULL)
return E_NOTIMPL;
*lphmenu = hMenu;
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditView command helpers
void CRichEditView::OnCharEffect(DWORD dwMask, DWORD dwEffect)
{
GetCharFormatSelection();
if (m_charformat.dwMask & dwMask) // selection is all the same
m_charformat.dwEffects ^= dwEffect;
else
m_charformat.dwEffects |= dwEffect;
m_charformat.dwMask = dwMask;
SetCharFormat(m_charformat);
}
void CRichEditView::OnUpdateCharEffect(CCmdUI* pCmdUI, DWORD dwMask, DWORD dwEffect)
{
GetCharFormatSelection();
pCmdUI->SetCheck((m_charformat.dwMask & dwMask) ?
((m_charformat.dwEffects & dwEffect) ? 1 : 0) : 2);
}
void CRichEditView::OnParaAlign(WORD wAlign)
{
GetParaFormatSelection();
m_paraformat.dwMask = PFM_ALIGNMENT;
m_paraformat.wAlignment = wAlign;
SetParaFormat(m_paraformat);
}
void CRichEditView::OnUpdateParaAlign(CCmdUI* pCmdUI, WORD wAlign)
{
GetParaFormatSelection();
// disable if no word wrap since alignment is meaningless
pCmdUI->Enable( (m_nWordWrap == WrapNone) ?
FALSE : TRUE);
pCmdUI->SetCheck( (m_paraformat.dwMask & PFM_ALIGNMENT) ?
((m_paraformat.wAlignment == wAlign) ? 1 : 0) : 2);
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditView commands
void CRichEditView::OnUpdateNeedSel(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
long nStartChar, nEndChar;
GetRichEditCtrl().GetSel(nStartChar, nEndChar);
pCmdUI->Enable(nStartChar != nEndChar);
ASSERT_VALID(this);
}
void CRichEditView::OnUpdateNeedClip(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
pCmdUI->Enable(CanPaste());
}
void CRichEditView::OnUpdateNeedText(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
pCmdUI->Enable(GetTextLength() != 0);
}
void CRichEditView::OnUpdateNeedFind(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
_AFX_RICHEDIT_STATE* pEditState = _afxRichEditState;
pCmdUI->Enable(GetTextLength() != 0 &&
!pEditState->strFind.IsEmpty());
}
void CRichEditView::OnUpdateEditUndo(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
pCmdUI->Enable(GetRichEditCtrl().CanUndo());
}
void CRichEditView::OnEditCut()
{
ASSERT_VALID(this);
GetRichEditCtrl().Cut();
}
void CRichEditView::OnEditCopy()
{
ASSERT_VALID(this);
GetRichEditCtrl().Copy();
}
void CRichEditView::OnEditPaste()
{
ASSERT_VALID(this);
m_nPasteType = 0;
GetRichEditCtrl().Paste();
}
void CRichEditView::OnEditClear()
{
ASSERT_VALID(this);
GetRichEditCtrl().Clear();
}
void CRichEditView::OnEditUndo()
{
ASSERT_VALID(this);
GetRichEditCtrl().Undo();
m_bSyncCharFormat = m_bSyncParaFormat = TRUE;
}
void CRichEditView::OnEditSelectAll()
{
ASSERT_VALID(this);
GetRichEditCtrl().SetSel(0, -1);
}
void CRichEditView::OnEditFind()
{
ASSERT_VALID(this);
OnEditFindReplace(TRUE);
}
void CRichEditView::OnEditReplace()
{
ASSERT_VALID(this);
OnEditFindReplace(FALSE);
}
void CRichEditView::OnEditRepeat()
{
ASSERT_VALID(this);
_AFX_RICHEDIT_STATE* pEditState = _afxRichEditState;
if (!FindText(pEditState))
TextNotFound(pEditState->strFind);
}
void CRichEditView::OnCancelEditCntr()
{
m_lpRichEditOle->InPlaceDeactivate();
}
void CRichEditView::OnInsertObject()
{
// Invoke the standard Insert Object dialog box to obtain information
COleInsertDialog dlg;
if (dlg.DoModal() != IDOK)
return;
CWaitCursor wait;
CRichEditCntrItem* pItem = NULL;
TRY
{
// create item from dialog results
pItem = GetDocument()->CreateClientItem();
pItem->m_bLock = TRUE;
if (!dlg.CreateItem(pItem))
{
pItem->m_bLock = FALSE;
AfxThrowMemoryException(); // any exception will do
}
HRESULT hr = InsertItem(pItem);
pItem->UpdateItemType();
pItem->m_bLock = FALSE;
if (hr != NOERROR)
AfxThrowOleException(hr);
// if insert new object -- initially show the object
if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
pItem->DoVerb(OLEIVERB_SHOW, this);
}
CATCH(CException, e)
{
if (pItem != NULL)
{
ASSERT_VALID(pItem);
pItem->Delete();
}
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE);
}
END_CATCH
}
void CRichEditView::OnSelChange(NMHDR* pNMHDR, LRESULT* pResult)
{
ASSERT(pNMHDR->code == EN_SELCHANGE);
UNUSED(pNMHDR); // not used in release builds
m_bSyncCharFormat = m_bSyncParaFormat = TRUE;
*pResult = 0;
}
void CRichEditView::OnDestroy()
{
if (m_lpRichEditOle != NULL)
m_lpRichEditOle->Release();
CCtrlView::OnDestroy();
}
void CRichEditView::OnEditProperties()
{
ASSERT(m_lpRichEditOle != NULL);
CRichEditCntrItem* pSelection = GetSelectedItem();
// make sure item is in sync with richedit's item
CReObject reo;
m_lpRichEditOle->GetObject(REO_IOB_SELECTION, &reo,
REO_GETOBJ_NO_INTERFACES);
pSelection->SyncToRichEditObject(reo);
COlePropertiesDialog dlg(pSelection);
dlg.DoModal();
}
void CRichEditView::OnUpdateEditProperties(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetSelectedItem() != NULL);
}
void CRichEditView::OnCharBold()
{
OnCharEffect(CFM_BOLD, CFE_BOLD);
}
void CRichEditView::OnUpdateCharBold(CCmdUI* pCmdUI)
{
OnUpdateCharEffect(pCmdUI, CFM_BOLD, CFE_BOLD);
}
void CRichEditView::OnCharItalic()
{
OnCharEffect(CFM_ITALIC, CFE_ITALIC);
}
void CRichEditView::OnUpdateCharItalic(CCmdUI* pCmdUI)
{
OnUpdateCharEffect(pCmdUI, CFM_ITALIC, CFE_ITALIC);
}
void CRichEditView::OnCharUnderline()
{
OnCharEffect(CFM_UNDERLINE, CFE_UNDERLINE);
}
void CRichEditView::OnUpdateCharUnderline(CCmdUI* pCmdUI)
{
OnUpdateCharEffect(pCmdUI, CFM_UNDERLINE, CFE_UNDERLINE);
}
void CRichEditView::OnParaCenter()
{
OnParaAlign(PFA_CENTER);
}
void CRichEditView::OnUpdateParaCenter(CCmdUI* pCmdUI)
{
OnUpdateParaAlign(pCmdUI, PFA_CENTER);
}
void CRichEditView::OnParaLeft()
{
OnParaAlign(PFA_LEFT);
}
void CRichEditView::OnUpdateParaLeft(CCmdUI* pCmdUI)
{
OnUpdateParaAlign(pCmdUI, PFA_LEFT);
}
void CRichEditView::OnParaRight()
{
OnParaAlign(PFA_RIGHT);
}
void CRichEditView::OnUpdateParaRight(CCmdUI* pCmdUI)
{
OnUpdateParaAlign(pCmdUI, PFA_RIGHT);
}
void CRichEditView::OnBullet()
{
GetParaFormatSelection();
if (m_paraformat.dwMask & PFM_NUMBERING && m_paraformat.wNumbering == PFN_BULLET)
{
m_paraformat.wNumbering = 0;
m_paraformat.dxOffset = 0;
m_paraformat.dxStartIndent = 0;
m_paraformat.dwMask = PFM_NUMBERING | PFM_STARTINDENT | PFM_OFFSET;
}
else
{
m_paraformat.wNumbering = PFN_BULLET;
m_paraformat.dwMask = PFM_NUMBERING;
if (m_paraformat.dxOffset == 0)
{
m_paraformat.dxOffset = m_nBulletIndent;
m_paraformat.dwMask = PFM_NUMBERING | PFM_STARTINDENT | PFM_OFFSET;
}
}
SetParaFormat(m_paraformat);
}
void CRichEditView::OnUpdateBullet(CCmdUI* pCmdUI)
{
GetParaFormatSelection();
pCmdUI->SetCheck( (m_paraformat.dwMask & PFM_NUMBERING) ? ((m_paraformat.wNumbering & PFN_BULLET) ? 1 : 0) : 2);
}
void CRichEditView::OnFormatFont()
{
GetCharFormatSelection();
CFontDialog dlg(m_charformat, CF_BOTH|CF_NOOEMFONTS);
if (dlg.DoModal() == IDOK)
{
dlg.GetCharFormat(m_charformat);
SetCharFormat(m_charformat);
}
}
void CRichEditView::OnColorPick(COLORREF cr)
{
GetCharFormatSelection();
m_charformat.dwMask = CFM_COLOR;
m_charformat.dwEffects = NULL;
m_charformat.crTextColor = cr;
SetCharFormat(m_charformat);
}
void CRichEditView::OnColorDefault()
{
GetCharFormatSelection();
m_charformat.dwMask = CFM_COLOR;
m_charformat.dwEffects = CFE_AUTOCOLOR;
SetCharFormat(m_charformat);
}
void CRichEditView::OnEditPasteSpecial()
{
COlePasteSpecialDialog dlg;
dlg.AddStandardFormats();
dlg.AddFormat(_oleData.cfRichTextFormat, TYMED_HGLOBAL, AFX_IDS_RTF_FORMAT, FALSE, FALSE);
dlg.AddFormat(CF_TEXT, TYMED_HGLOBAL, AFX_IDS_TEXT_FORMAT, FALSE, FALSE);
if (dlg.DoModal() != IDOK)
return;
DVASPECT dv = dlg.GetDrawAspect();
HMETAFILE hMF = (HMETAFILE)dlg.GetIconicMetafile();
CLIPFORMAT cf =
dlg.m_ps.arrPasteEntries[dlg.m_ps.nSelectedIndex].fmtetc.cfFormat;
CWaitCursor wait;
SetCapture();
// we set the target type so that QueryAcceptData know what to paste
m_nPasteType = dlg.GetSelectionType();
GetRichEditCtrl().PasteSpecial(cf, dv, hMF);
m_nPasteType = 0;
ReleaseCapture();
}
void CRichEditView::OnUpdateEditPasteSpecial(CCmdUI* pCmdUI)
{
pCmdUI->Enable(CanPaste());
}
void CRichEditView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_F10 && GetKeyState(VK_SHIFT) < 0)
{
CRect rect;
GetClientRect(rect);
CPoint pt = rect.CenterPoint();
SendMessage(WM_CONTEXTMENU, (WPARAM)m_hWnd, MAKELPARAM(pt.x, pt.y));
}
else
CCtrlView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CRichEditView::OnDropFiles(HDROP hDropInfo)
{
TCHAR szFileName[_MAX_PATH];
UINT nFileCount = ::DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
ASSERT(nFileCount != 0);
CHARRANGE cr;
GetRichEditCtrl().GetSel(cr);
int nMin = cr.cpMin;
for (UINT i=0;i<nFileCount;i++)
{
::DragQueryFile(hDropInfo, i, szFileName, _MAX_PATH);
InsertFileAsObject(szFileName);
GetRichEditCtrl().GetSel(cr);
cr.cpMin = cr.cpMax;
GetRichEditCtrl().SetSel(cr);
UpdateWindow();
}
cr.cpMin = nMin;
GetRichEditCtrl().SetSel(cr);
::DragFinish(hDropInfo);
}
void CRichEditView::OnDevModeChange(LPTSTR /*lpDeviceName*/)
{
// WM_DEVMODECHANGE forwarded by the main window of the app
CDC dc;
AfxGetApp()->CreatePrinterDC(dc);
OnPrinterChanged(dc);
}
/////////////////////////////////////////////////////////////////////////////
// CRichEditView attributes
BOOL AFX_CDECL CRichEditView::IsRichEditFormat(CLIPFORMAT cf)
{
return ((cf == _oleData.cfRichTextFormat) ||
(cf == _oleData.cfRichTextAndObjects) || (cf == CF_TEXT));
}
BOOL CRichEditView::CanPaste() const
{
return (CountClipboardFormats() != 0) &&
(IsClipboardFormatAvailable(CF_TEXT) ||
IsClipboardFormatAvailable(_oleData.cfRichTextFormat) ||
IsClipboardFormatAvailable(_oleData.cfEmbedSource) ||
IsClipboardFormatAvailable(_oleData.cfEmbeddedObject) ||
IsClipboardFormatAvailable(_oleData.cfFileName) ||
IsClipboardFormatAvailable(_oleData.cfFileNameW) ||
IsClipboardFormatAvailable(CF_METAFILEPICT) ||
IsClipboardFormatAvailable(CF_DIB) ||
IsClipboardFormatAvailable(CF_BITMAP) ||
GetRichEditCtrl().CanPaste());
}
CHARFORMAT& CRichEditView::GetCharFormatSelection()
{
if (m_bSyncCharFormat)
{
GetRichEditCtrl().GetSelectionCharFormat(m_charformat);
m_bSyncCharFormat = FALSE;
}
return m_charformat;
}
PARAFORMAT& CRichEditView::GetParaFormatSelection()
{
if (m_bSyncParaFormat)
{
GetRichEditCtrl().GetParaFormat(m_paraformat);
m_bSyncParaFormat = FALSE;
}
return m_paraformat;
}
void CRichEditView::SetCharFormat(CHARFORMAT cf)
{
CWaitCursor wait;
GetRichEditCtrl().SetSelectionCharFormat(cf);
m_bSyncCharFormat = TRUE;
}
BOOL CRichEditView::SetParaFormat(PARAFORMAT& pf)
{
BOOL bRetVal;
CWaitCursor wait;
bRetVal = GetRichEditCtrl().SetParaFormat(pf);
m_bSyncParaFormat = TRUE;
return bRetVal;
}
CRichEditCntrItem* CRichEditView::GetSelectedItem() const
{
ASSERT(m_lpRichEditOle != NULL);
CRichEditDoc* pDoc = GetDocument();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -