rulerricheditctrl.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 2,215 行 · 第 1/4 页
CPP
2,215 行
/* ==========================================================================
File : RuleRichEditCtrl.cpp
Class : CRulerRichEditCtrl
Author : Johan Rosengren, Abstrakt Mekanik AB
Iain Clarke
Date : 2004-04-17
Purpose : "CRulerRichEditCtrl" is a "CWnd" derived class containing an
embedded RTF-control, a ruler-control with dragable tab-
positions and a formatting toolbar. The class can be used
to - for example - add a complete mini-editor to a modal
or modeless dialog box.
Description : The class mainly handles mouse messages. The mouse
messages are sent from the ruler control, and are
button down, where the a check is made for the cursor
located on one of the tab-markers, mouse move, where an
XORed line is drawn across the RTF-control and button up,
where a new tab position is set. The class also handles
the toolbar buttons, setting styles as
appropriate for the selected text.
Usage : Add a "CRulerRichEditCtrl"-member to the parent class.
Call Create to create the control. "GetRichEditCtrl" can
be used to access the embedded RTF-control. Remember to
call "AfxInitRichEdit(2)"!
The contents can be saved to disk by calling "Save", and
loaded from disk by calling "Load". The two functions
will automatically display a file dialog if the file
name parameter of the calls are left empty.
"GetRTF" and "SetRTF" can be used to get and set the
contents of the embedded RTF-control as RTF
respectively.
The ruler measures can be displayed as inches or
centimeters, by calling "SetMode". "GetMode" will get the
current mode.
========================================================================*/
#include "stdafx.h"
#include "RulerRichEditCtrl.h"
#include "resource.h"
#include "..\3rdparty\TextFile.h"
#include "..\shared\misc.h"
#include "..\shared\enstring.h"
#include "ids.h"
#include <afxpriv.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int SCMARGIN = 4;
const LPCTSTR FILEPREFIX = "file://";
/////////////////////////////////////////////////////////////////////////////
// Registered messages for ruler/CRulerRichEditCtrl communication
UINT urm_RULERACTION = ::RegisterWindowMessage(_T("_RULERRICHEDITCTRL_RULER_TRACK_"));
UINT urm_GETSCROLLPOS = ::RegisterWindowMessage(_T("_RULERRICHEDITCTRL_GET_SCROLL_POS_"));
UINT urm_SETCURRENTFONTNAME = ::RegisterWindowMessage(_T("_RULERRICHEDITCTRL_SET_CURRENT_FONT_NAME"));
UINT urm_SETCURRENTFONTSIZE = ::RegisterWindowMessage(_T("_RULERRICHEDITCTRL_SET_CURRENT_FONT_SIZE"));
UINT urm_SETCURRENTFONTCOLOR = ::RegisterWindowMessage(_T("_RULERRICHEDITCTRL_SET_CURRENT_FONT_COLOR"));
/////////////////////////////////////////////////////////////////////////////
// Stream callback functions
// Callbacks to the Save and Load functions.
static DWORD CALLBACK StreamOut(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CMemFile* pFile = (CMemFile*)dwCookie;
pFile->Write(pbBuff, cb);
*pcb = cb;
return 0;
}
static DWORD CALLBACK StreamOutLen(DWORD dwCookie, LPBYTE /*pbBuff*/, LONG cb, LONG *pcb)
{
int* pLen = (int*)dwCookie;
*pLen += cb;
*pcb = cb;
return 0;
}
struct STREAMINCOOKIE
{
STREAMINCOOKIE(const CString& sContent) : sRTF(sContent), nStreamPos(0) {}
int GetLength() const { return sRTF.GetLength(); }
LPCTSTR CopyFrom() const { return ((LPCTSTR)sRTF) + nStreamPos; }
const CString& sRTF;
int nStreamPos;
};
static DWORD CALLBACK StreamIn(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
STREAMINCOOKIE* pCookie = (STREAMINCOOKIE*)dwCookie;
int max = min(cb, pCookie->GetLength());
strncpy((LPSTR)pbBuff, pCookie->CopyFrom(), max);
*pcb = max;
pCookie->nStreamPos += max;
return 0;
}
/////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CRulerRichEditCtrl, CWnd)
//{{AFX_MSG_MAP(CRulerRichEditCtrl)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_COMMAND(BUTTON_FONT, OnButtonFont)
ON_COMMAND(BUTTON_COLOR, OnButtonColor)
ON_COMMAND(BUTTON_BOLD, OnButtonBold)
ON_COMMAND(BUTTON_STRIKETHRU, OnButtonStrikethrough)
ON_COMMAND(BUTTON_ITALIC, OnButtonItalic)
ON_COMMAND(BUTTON_UNDERLINE, OnButtonUnderline)
ON_COMMAND(BUTTON_LEFTALIGN, OnButtonLeftAlign)
ON_COMMAND(BUTTON_CENTERALIGN, OnButtonCenterAlign)
ON_COMMAND(BUTTON_RIGHTALIGN, OnButtonRightAlign)
ON_COMMAND(BUTTON_INDENT, OnButtonIndent)
ON_COMMAND(BUTTON_OUTDENT, OnButtonOutdent)
ON_COMMAND(BUTTON_BULLET, OnButtonBullet)
ON_WM_SETFOCUS()
ON_MESSAGE(WM_SETTEXT, OnSetText)
ON_MESSAGE(WM_GETTEXT, OnGetText )
ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLength)
ON_WM_ENABLE()
ON_REGISTERED_MESSAGE(urm_RULERACTION, OnTrackRuler)
ON_REGISTERED_MESSAGE(urm_GETSCROLLPOS, OnGetScrollPos)
ON_REGISTERED_MESSAGE(urm_SETCURRENTFONTNAME, OnSetCurrentFontName)
ON_REGISTERED_MESSAGE(urm_SETCURRENTFONTSIZE, OnSetCurrentFontSize)
ON_REGISTERED_MESSAGE(urm_SETCURRENTFONTCOLOR, OnSetCurrentFontColor)
//}}AFX_MSG_MAP
ON_COMMAND(BUTTON_TEXTCOLOR, OnButtonTextColor)
ON_COMMAND(BUTTON_BACKCOLOR, OnButtonBackColor)
ON_WM_CREATE()
ON_MESSAGE(WM_SETFONT, OnSetFont)
ON_EN_HSCROLL(RTF_CONTROL, OnEnHScroll)
ON_NOTIFY(EN_SELCHANGE, RTF_CONTROL, OnEnSelChange)
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnUpdateToolbar)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRulerRichEditCtrl
CRulerRichEditCtrl::CRulerRichEditCtrl() : m_pen(PS_DOT, 0, RGB(0, 0, 0))
/* ============================================================
Function : CRulerRichEditCtrl::CRulerRichEditCtrl
Description : constructor
Access : Public
Return : void
Parameters : none
Usage :
============================================================*/
{
m_rulerPosition = 0;
m_margin = 0;
m_movingtab = -1;
m_offset = 0;
m_readOnly = FALSE;
// m_richEditModule = LoadLibrary (_T("Riched20.dll"));
m_bWordWrap = FALSE;
ShowToolbar();
ShowRuler();
m_cfDefault.dwMask = CFM_SIZE | CFM_FACE | CFM_BOLD | CFM_ITALIC |
CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR;
m_cfDefault.yHeight = 200;
m_cfDefault.dwEffects = CFE_AUTOBACKCOLOR | CFE_AUTOCOLOR;
lstrcpy(m_cfDefault.szFaceName, _T("Times New Roman"));
CUrlRichEditCtrl::SetGotoErrorMsg(CEnString(IDS_COMMENTSGOTOERRMSG));
}
CRulerRichEditCtrl::~CRulerRichEditCtrl()
/* ============================================================
Function : CRulerRichEditCtrl::~CRulerRichEditCtrl
Description : destructor
Access : Public
Return : void
Parameters : none
Usage :
============================================================*/
{
// if (m_richEditModule)
// FreeLibrary (m_richEditModule);
m_pen.DeleteObject();
}
BOOL CRulerRichEditCtrl::Create(DWORD dwStyle, const RECT &rect, CWnd* pParentWnd, UINT nID, BOOL /*autohscroll*/)
/* ============================================================
Function : CRulerRichEditCtrl::Create
Description : Creates the control and sub controls.
Access : Public
Return : BOOL - "TRUE" if created OK.
Parameters : DWORD dwStyle - Style of the control,
normally "WS_CHILD"
and "WS_VISIBLE".
const RECT &rect - Placement rectangle.
CWnd* pParentWnd - Parent window.
UINT nID - Control ID
BOOL autohscroll - "TRUE" if the RTF-control
should have the
"ES_AUTOHSCROLL" style
set.
Usage : Call to create the control.
============================================================*/
{
BOOL result = CWnd::Create(NULL, _T(""), dwStyle, rect, pParentWnd, nID);
return result;
}
BOOL CRulerRichEditCtrl::CreateToolbar()
/* ============================================================
Function : CRulerRichEditCtrl::CreateToolbar
Description : Creates the toolbar control
Access : Private
Return : BOOL - "TRUE" if the toolbar was created ok.
Parameters : none
Usage : Called during control creation
============================================================*/
{
return m_toolbar.Create(this);
}
BOOL CRulerRichEditCtrl::CreateRuler()
/* ============================================================
Function : CRulerRichEditCtrl::CreateRuler
Description : Creates the ruler control
Access : Private
Return : BOOL - "TRUE" if created ok.
Parameters : none
Usage : Called during control creation
============================================================*/
{
CRect rect;
GetClientRect(rect);
CRect rulerRect(0, TOOLBAR_HEIGHT, rect.right, TOOLBAR_HEIGHT + RULER_HEIGHT);
return m_ruler.Create(rulerRect, this, RULER_CONTROL);
}
BOOL CRulerRichEditCtrl::CreateRTFControl(BOOL autohscroll)
/* ============================================================
Function : CRulerRichEditCtrl::CreateRTFControl
Description : Creates the embedded RTF-control.
Access : Private
Return : BOOL - "TRUE" if created ok.
Parameters : BOOL autohscroll - "TRUE" if the RTF-control
should have the
"ES_AUTOHSCROLL" style
set.
Usage : Called during control creation
============================================================*/
{
BOOL result = FALSE;
CRect rect;
GetClientRect(rect);
int top = TOOLBAR_HEIGHT + RULER_HEIGHT;
CRect rtfRect(0, top, rect.right, rect.bottom);
DWORD style = ES_NOHIDESEL | WS_CHILD | WS_VISIBLE | /*WS_BORDER |*/ WS_HSCROLL | WS_VSCROLL | ES_WANTRETURN | ES_MULTILINE;
if (autohscroll)
style |= ES_AUTOHSCROLL;
if (m_rtf.Create(style, rtfRect, this, RTF_CONTROL))
{
// Setting up default tab stops
ParaFormat para(PFM_TABSTOPS);
para.cTabCount = MAX_TAB_STOPS;
for(int t = 0; t < MAX_TAB_STOPS ; t++)
para.rgxTabs[ t ] = 640 * (t + 1);
m_rtf.SetParaFormat(para);
// Setting default character format
m_rtf.SetDefaultCharFormat(m_cfDefault);
// Set the internal tabs array
SetTabStops((LPLONG) (para.rgxTabs), MAX_TAB_STOPS);
m_rtf.SetEventMask(m_rtf.GetEventMask() | ENM_SELCHANGE | ENM_SCROLL | ENM_CHANGE);
m_rtf.ModifyStyleEx(0, WS_EX_CLIENTEDGE);
result = TRUE;
}
return result;
}
void CRulerRichEditCtrl::UpdateEditRect()
{
// Set up edit rect margins
CRect rc;
m_rtf.GetClientRect(rc);
rc.top = SCMARGIN;
rc.left = SCMARGIN * 2;
rc.right -= SCMARGIN * 2;
m_rtf.SetRect(rc);
}
void CRulerRichEditCtrl::CreateMargins()
/* ============================================================
Function : CRulerRichEditCtrl::CreateMargins
Description : Sets the margins for the subcontrols and
the RTF-control edit rect.
Access : Private
Return : void
Parameters : none
Usage : Called during control creation.
============================================================*/
{
UpdateEditRect();
// Get the diff between the window- and client
// rect of the RTF-control. This gives the actual
// size of the RTF-control border.
CRect r1;
CRect r2;
m_rtf.GetWindowRect(r1);
m_rtf.GetClientRect(r2);
m_rtf.ClientToScreen(r2);
// Create the margin for the toolbar
// controls and the ruler.
m_margin = SCMARGIN * 2 + r2.left - r1.left;
m_ruler.SetMargin(m_margin);
}
/////////////////////////////////////////////////////////////////////////////
// CRulerRichEditCtrl message handlers
int CRulerRichEditCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// Save screen resolution for later on.
CClientDC dc(this);
m_physicalInch = dc.GetDeviceCaps(LOGPIXELSX);
// Create sub-controls
BOOL autohscroll = TRUE;
if (CreateRTFControl(autohscroll) && CreateToolbar() && CreateRuler())
{
CreateMargins();
SetReadOnly(GetReadOnly());
UpdateToolbarButtons();
CRect rClient;
GetClientRect(rClient);
LayoutControls(rClient.Width(), rClient.Height());
return 0;
}
return -1;
}
void CRulerRichEditCtrl::OnEnHScroll()
{
m_ruler.Invalidate(FALSE);
m_ruler.UpdateWindow();
}
void CRulerRichEditCtrl::OnEnSelChange(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
// Update the toolbar
UpdateToolbarButtons();
// Update ruler
m_ruler.Invalidate(FALSE);
m_ruler.UpdateWindow();
*pResult = 0;
}
LRESULT CRulerRichEditCtrl::OnSetFont(WPARAM wp, LPARAM /*lp*/)
{
// reverse engineer the hFont and use the results
// for the rtf defaults
CString sFace;
int nPoint = Misc::GetFontNameSize((HFONT)wp, sFace);
if (nPoint && !sFace.IsEmpty())
{
// lets have a backup plan
if (!m_toolbar.SetFontName(sFace))
{
sFace = "MS Sans Serif";
nPoint = 9;
m_toolbar.SetFontName(sFace);
}
m_toolbar.SetFontSize(nPoint);
// update default char format
strcpy(m_cfDefault.szFaceName, sFace);
m_cfDefault.yHeight = nPoint * 20;
m_rtf.SetDefaultCharFormat(m_cfDefault);
}
// else eat it
return 0L;
}
void CRulerRichEditCtrl::OnPaint()
/* ============================================================
Function : CRulerRichEditCtrl::OnPaint
Description : Paints the ruler.
Access : Protected
Return : void
Parameters : none
Usage : Called from MFC.
============================================================*/
{
CPaintDC mainDC(this);
UpdateTabStops();
}
BOOL CRulerRichEditCtrl::OnEraseBkgnd(CDC* /*pDC*/)
/* ============================================================
Function : CRulerRichEditCtrl::OnEraseBkgnd
Description : Returns "TRUE" to avoid flicker.
Access : Protected
Return : BOOL - Always "TRUE",
Parameters : CDC* pDC - Not used
Usage : Called from MFC.
============================================================*/
{
return TRUE;
}
BOOL CRulerRichEditCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
/* ============================================================
Function : CRulerRichEditCtrl::OnNotify
Description : Called as the RTF-control is updated or
the selection changes.
Access : Protected
Return : BOOL - From base class
Parameters : WPARAM wParam - Control ID
LPARAM lParam - Not interested
LRESULT* pResult - Not interested
Usage : Called from MFC. We must check the control
every time the selection changes or the
contents are changed, as the cursor might
have entered a new paragraph, with new tab
and/or font settings.
============================================================*/
{
return CWnd::OnNotify(wParam, lParam, pResult);
}
void CRulerRichEditCtrl::OnSize(UINT nType, int cx, int cy)
/* ============================================================
Function : CRulerRichEditCtrl::OnSize
Description : We resize the embedded RTF-control.
Access : Protected
Return : void
Parameters : UINT nType - Not interested
int cx - New width
int cy - New height
Usage : Called from MFC.
============================================================*/
{
CWnd::OnSize(nType, cx, cy);
if (m_rtf.m_hWnd)
{
UpdateEditRect();
LayoutControls(cx, cy);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?