rtfcontentcontrol.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 605 行 · 第 1/2 页
CPP
605 行
// RTFContentControl.cpp : implementation file
//
#include "stdafx.h"
#include "RTFContentCtrl.h"
#include "RTFContentControl.h"
#include "..\shared\itasklist.h"
#include "..\shared\enfiledialog.h"
#include "..\shared\autoflag.h"
#include "..\todolist\tdcmsg.h"
#include "..\shared\richedithelper.h"
#include "..\todolist\tdlschemadef.h"
#include "..\shared\misc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRTFContentControl
CRTFContentControl::CRTFContentControl() : m_bAllowNotify(TRUE), m_reSpellCheck(m_rtf)
{
// add custom protocol to comments field for linking to task IDs
GetRichEditCtrl().AddProtocol(TDL_PROTOCOL, TRUE);
}
CRTFContentControl::~CRTFContentControl()
{
}
BEGIN_MESSAGE_MAP(CRTFContentControl, CRulerRichEditCtrl)
//{{AFX_MSG_MAP(CRTFContentControl)
ON_WM_CONTEXTMENU()
ON_WM_CREATE()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
ON_EN_CHANGE(RTF_CONTROL, OnChangeText)
ON_MESSAGE(WM_SETFONT, OnSetFont)
ON_WM_STYLECHANGING()
ON_REGISTERED_MESSAGE(WM_UREN_CUSTOMURL, OnCustomUrl)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRTFContentControl message handlers
void CRTFContentControl::OnChangeText()
{
if (m_bAllowNotify && !GetRichEditCtrl().IsIMEComposing())
GetParent()->SendMessage(WM_TDCN_COMMENTSCHANGE);
}
LRESULT CRTFContentControl::OnSetFont(WPARAM wp, LPARAM lp)
{
// richedit2.0 sends a EN_CHANGE notification if it contains
// text when it receives a font change.
// to us though this is a bogus change so we prevent a notification
// being sent
CAutoFlag af(m_bAllowNotify, FALSE);
return CRulerRichEditCtrl::OnSetFont(wp, lp);
}
// ICustomControl implementation
int CRTFContentControl::GetContent(unsigned char* pContent) const
{
return GetContent(this, pContent);
}
// hack to get round GetRTF not being const
int CRTFContentControl::GetContent(const CRTFContentControl* pCtrl, unsigned char* pContent)
{
int nLen = 0;
if (pContent)
{
CString sContent;
// cast away constness
sContent = ((CRTFContentControl*)pCtrl)->GetRTF();
nLen = sContent.GetLength();
if (pContent)
CopyMemory(pContent, (LPCTSTR)sContent, nLen);
}
else
nLen = ((CRTFContentControl*)pCtrl)->GetRTFLength();
return nLen;
}
bool CRTFContentControl::SetContent(unsigned char* pContent, int nLength)
{
LPCTSTR RTFTAG = "{\\rtf";
const int LENTAG = strlen(RTFTAG);
// content must begin with rtf tag or be empty
if (nLength && (nLength < LENTAG || strncmp((const char*)pContent, RTFTAG, LENTAG)))
return false;
CAutoFlag af(m_bAllowNotify, FALSE);
CString sContent((LPCSTR)pContent, nLength);
SetRTF(sContent);
CRichEditHelper::ClearUndo(GetRichEditCtrl());
GetRichEditCtrl().ParseAndFormatText(TRUE);
return true;
}
int CRTFContentControl::GetTextContent(char* szContent, int nLength) const
{
if (!szContent)
return GetWindowTextLength();
// else
if (nLength == -1)
nLength = lstrlen(szContent);
GetWindowText(szContent, nLength);
return nLength;
}
bool CRTFContentControl::SetTextContent(const char* szContent)
{
CAutoFlag af(m_bAllowNotify, TRUE);
SendMessage(WM_SETTEXT, 0, (LPARAM)szContent);
return true;
}
HWND CRTFContentControl::GetHwnd() const
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return GetSafeHwnd();
}
const char* CRTFContentControl::GetTypeID() const
{
static CString sID;
Misc::GuidToString(RTF_TYPEID, sID);
return sID;
}
void CRTFContentControl::SetReadOnly(bool bReadOnly)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CRulerRichEditCtrl::SetReadOnly((BOOL)bReadOnly);
}
void CRTFContentControl::Release()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
DestroyWindow();
delete this;
}
void CRTFContentControl::EnableMenuItem(CMenu* pMenu, UINT nCmdID, BOOL bEnable)
{
pMenu->EnableMenuItem(nCmdID, MF_BYCOMMAND | (bEnable ? MF_ENABLED : MF_GRAYED));
}
void CRTFContentControl::CheckMenuItem(CMenu* pMenu, UINT nCmdID, BOOL bCheck)
{
pMenu->CheckMenuItem(nCmdID, MF_BYCOMMAND | (bCheck ? MF_CHECKED : MF_UNCHECKED));
}
void CRTFContentControl::OnContextMenu(CWnd* pWnd, CPoint point)
{
if (pWnd == &GetRichEditCtrl())
{
// prepare a simple edit menu
CMenu menu;
if (menu.LoadMenu(IDR_POPUP))
{
CMenu* pPopup = menu.GetSubMenu(0);
if (pPopup)
{
CRulerRichEdit& re = GetRichEditCtrl();
BOOL bCanEdit = re.IsWindowEnabled() && !(re.GetStyle() & ES_READONLY);
BOOL bHasText = re.GetTextLength();
EnableMenuItem(pPopup, ID_EDIT_UNDO, bCanEdit && re.CanUndo());
EnableMenuItem(pPopup, ID_EDIT_REDO, bCanEdit && re.SendMessage(EM_CANREDO));
CHARRANGE cr;
re.GetSel(cr);
BOOL bHasSel = (cr.cpMax - cr.cpMin);
CharFormat cf;
cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_COLOR;
re.GetSelectionCharFormat(cf);
CheckMenuItem(pPopup, BUTTON_BOLD, (cf.dwEffects & CFE_BOLD));
CheckMenuItem(pPopup, BUTTON_ITALIC, (cf.dwEffects & CFE_ITALIC));
CheckMenuItem(pPopup, BUTTON_UNDERLINE, (cf.dwEffects & CFE_UNDERLINE));
CheckMenuItem(pPopup, BUTTON_STRIKETHRU, (cf.dwEffects & CFE_STRIKEOUT));
CheckMenuItem(pPopup, ID_EDIT_SUPERSCRIPT, (cf.dwEffects & CFE_SUPERSCRIPT));
CheckMenuItem(pPopup, ID_EDIT_SUBSCRIPT, (cf.dwEffects & CFE_SUBSCRIPT));
EnableMenuItem(pPopup, BUTTON_BOLD, bCanEdit);
EnableMenuItem(pPopup, BUTTON_ITALIC, bCanEdit);
EnableMenuItem(pPopup, BUTTON_UNDERLINE, bCanEdit);
EnableMenuItem(pPopup, BUTTON_STRIKETHRU, bCanEdit);
EnableMenuItem(pPopup, ID_EDIT_SUPERSCRIPT, bCanEdit);
EnableMenuItem(pPopup, ID_EDIT_SUBSCRIPT, bCanEdit);
EnableMenuItem(pPopup, ID_EDIT_CUT, bCanEdit && bHasSel);
EnableMenuItem(pPopup, ID_EDIT_COPY, bHasSel);
EnableMenuItem(pPopup, ID_EDIT_PASTE, bCanEdit && CanPaste());
EnableMenuItem(pPopup, ID_EDIT_PASTESIMPLE, bCanEdit && CanPaste());
EnableMenuItem(pPopup, ID_EDIT_DELETE, bCanEdit && bHasSel);
EnableMenuItem(pPopup, ID_EDIT_SELECT_ALL, bHasText);
EnableMenuItem(pPopup, ID_EDIT_PASTEASREF, bCanEdit && !IsClipboardEmpty());
int nUrl = re.GetContextUrl();
EnableMenuItem(pPopup, ID_EDIT_OPENURL, nUrl != -1);
if (nUrl != -1)
{
CString sText, sMenu;
pPopup->GetMenuString(ID_EDIT_OPENURL, sMenu, MF_BYCOMMAND);
sText.Format("%s: %s", sMenu, re.GetUrl(nUrl, TRUE));
pPopup->ModifyMenu(ID_EDIT_OPENURL, MF_BYCOMMAND, ID_EDIT_OPENURL, sText);
}
EnableMenuItem(pPopup, ID_EDIT_FILEBROWSE, bCanEdit);
EnableMenuItem(pPopup, ID_EDIT_INSERTDATESTAMP, bCanEdit);
EnableMenuItem(pPopup, ID_EDIT_SPELLCHECK, bCanEdit && bHasText);
EnableMenuItem(pPopup, ID_EDIT_FIND, bHasText);
EnableMenuItem(pPopup, ID_EDIT_FINDREPLACE, bCanEdit && bHasText);
CheckMenuItem(pPopup, ID_EDIT_SHOWTOOLBAR, IsToolbarVisible());
CheckMenuItem(pPopup, ID_EDIT_SHOWRULER, IsRulerVisible());
CheckMenuItem(pPopup, ID_EDIT_WORDWRAP, HasWordWrap());
// check pos
if (point.x == -1 && point.y == -1)
{
point = GetCaretPos();
::ClientToScreen(m_rtf, &point);
}
UINT nCmdID = ::TrackPopupMenu(*pPopup, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON,
point.x, point.y, 0, *this, NULL);
switch (nCmdID)
{
case BUTTON_BOLD:
case BUTTON_ITALIC:
case BUTTON_UNDERLINE:
case BUTTON_STRIKETHRU:
SendMessage(WM_COMMAND, nCmdID);
break;
case ID_EDIT_SUPERSCRIPT:
DoSuperscript();
break;
case ID_EDIT_SUBSCRIPT:
DoSubscript();
break;
case ID_EDIT_UNDO:
CTextDocument(re).Undo();
break;
case ID_EDIT_REDO:
re.SendMessage(EM_REDO);
break;
case ID_EDIT_COPY:
re.Copy();
break;
case ID_EDIT_CUT:
re.Cut();
break;
case ID_EDIT_FIND:
re.DoEditFind(IDS_FIND_TITLE);
break;
case ID_EDIT_FINDREPLACE:
re.DoEditReplace(IDS_REPLACE_TITLE);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?