While CHARFORMAT is a structure used to format characters and text in a
CRichEditView application, the PARAFORMAT structure is used to perform paragraph formatting in the same application. You are encouraged to consult their documentations in the MSDN (CD-ROM or web site) which are fairly large. By their definitions, they have all the attributes
necessary to do their respective formatting, but you still need the aid of the
CRichEditCtrl class to control the setting of the attributes you specify for a particular situation. To start, keep in mind that there are practically three behaviors a toolbar button has:
- You press a button and it performs an operation but it doesn't change its state, it stays up, an example is the ID_FILE_NEW
- You press a button and it stays down throughout its operation until you depress it, this behavior is the same as a check box, an example is a bold, italic, or underline
buttons
- A few buttons stay in a group like radio buttons. Only one in the group can be and stay pressed at a
time. An example is the group of Left, Center, and Right buttons.
So, we need to treat some buttons as standalone and others as a group. A button that behaves as a check box has a
Boolean attribute because its state always tells the user that it is pressed or it is not, and it only controls its own behavior. We will treat the other three buttons as a group (and that's what they are).
To manually configure the buttons on the toolbar,
whenever the user clicks a Boolean-based button, we need to reverse its state, if it is down, we want it up, and vice versa. And we will implement the same logic for the other format character buttons:
void CExoView::OnBold()
{
bBold = !bBold;
}
void CExoView::OnCharItalic()
{
bItalic = !bItalic;
}
void CExoView::OnCharUnderline()
{
bUnderline = !bUnderline;
}
void CExoView::OnCharStrikeout()
{
bStrikeout = !Strikeout;
}
|
If the user clicks a button in a group, we just want to keep that particular button as pressed even if it is already:
void CExoView::OnLeft()
{
m_Justify = LEFT;
}
d) Use the same logics for the Center and the Right justified buttons.
void CExoView::OnParaCenter()
{
m_Justify = CENTER;
}
void CExoView::OnParaRight()
{
m_Justify = RIGHT;
}
|
For the character buttons, as you already know, the character formatting buttons behave like check boxes. So, we will call the
CCmdUI::SetCheck() function for each button and use its Boolean attribute as its argument:
void CExoView::OnUpdateBold(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( bBold );
}
void CExoView::OnUpdateCharItalic(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( bItalic );
}
void CExoView::OnUpdateCharUnderline(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( bUnderline );
}
void CExoView::OnUpdateCharStrikeout(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( bStrikeout );
}
|
You already know that the paragraph formatting buttons act like radio buttons. So, for the paragraph formatting buttons, we will call the CCmdUI::SetRadio() function and set the enumerated value as the argument:
void CExoView::OnUpdateLeft(CCmdUI* pCmdUI)
{
pCmdUI->SetRadio( m_Justify == LEFT );
}
|
When you finish, your buttons should express their
Boolean features. Of course, you know that the ID_CHAR_COLOR and the ID_INSERT_BULLET buttons don't use/need any of those
behaviors
Over all, this formatting follows this approach:
- Create a CRichEditCtrl object:
CRichEditCtrl& rCtrl = GetRichEditCtrl();
- declare a CHARFORMAT structure:
CHARFORMAT cf;
- Before doing anything you need to get the current selection:
rCtrl.GetSelectionCharFormat(cf);
- Now, assign the attributes you want for this particular button:
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_BOLD;
cf.dwEffects ^= CFE_BOLD;
- Finally, assign those attributes to the current selection:
rCtrl.SetSelectionCharFormat(cf);
- Keep the boolean argument at the end of the function
|