Preface
I was going through my old projects recently and have found an interesting
control I have wrote several years ago which was never actually used. I'm not
sure if anybody still interested in MFC controls nowadays, but just in case
somebody is I decided to publish this control. Maybe you'll make use of it. I
hope you'll find it useful.
Introduction
Have you ever used a function of Microsoft� Excel to import text data with
fixed width where fields are aligned in columns with spaces between each field
(Fig. 1)?
Fig. 1. The import text dialog of Microsoft Excel
Have you ever needed/wanted to use similar functionality in your own
application to allow user split the text into columns with fixed width? Using a
separator control presented by this article you may easily introduce this
functionality into your application. An example of separator control you can se
on the Fig. 2.
Fig. 2. An example of separator control in use
General appearance
CSeparatorsCtrl
is an MFC control that provides functionality
to request a user to select/split text into fixed width columns.
CScaleLine
is a control that represents a scale line with
numbers on the top of a separator control and used by
CSeparatorsCtrl
.
CFlatDisplay
is a control that displays a text and columns it
is split to by user. It is also used by CSeparatorsCtrl
.
You may think of facade pattern in place of CSeparatorsCtrl
that
uses extended functionality of CScaleLine
and
CFlatDisplay
controls to hide away their complexity and bring to
developer a plain interface of a single control.
An instance of CSeparatorsCtrl
control might be created during
design time in the form designer of Visual Studio with a help of custom control
as well as dynamically at runtime.
This control takes advantage of using CAutoFont
class that is
written by Jamie Nordmeyer and might be found here: http://www.codeproject.com/gdi/autofont.asp
Functionality provided by CSeparatorsCtrl
class:
void SetDisplayFontSize(long size) |
Sets the font size of displayed text. |
void SetDisplayColor(COLORREF txtColor, COLORREF lineColor, COLORREF
bgColor) |
Sets the colors of CFlatDisplay control:
- txtColor - the color of text (default color is black);
- lineColor - the color of separator lines (default color is black);
- bgColor - the background color of text field (default color is white).
|
void SetScaleColor(COLORREF value) |
Sets the color of CScaleLine control. |
void SetScaleIntervals(long nBig, long nSmall) |
Sets the scale intervals. nBig defines big intervals where the
numbers are displayed, nSmall defines smaller intervals that are
marked out only by the size of stroke. |
void SetShowFrame(bool value) |
Defines whether to show a frame around separator control or not. |
void SetText(CString text) |
Sets the text that is displayed in separator control. |
long GetCharHeight() |
Returns the height of displayed characters (the monospaced font is
used). |
long GetCharWidth() |
Returns the width of displayed characters. |
CDWordArray * GetSeparators() |
Returns the reference to dynamic DWORD array of separators
selected by user. |
virtual bool OnBeforeAddColumn(long nPos) |
The event handler that is called before column is added when user has
clicked a mouse. Declared as virtual so that you may override it if inheriting
from this control. If this method returns false a new column
separator will not be added. |
virtual bool OnBeforeRemoveColumn(long nPos) |
The event handler that is called before column is removed when user has
clicked a mouse. If this method returns false the column separator
will not be removed. |
Usage of control
To use a separator control simply place a custom control on your dialog and
declare a property to be an instance of CSeparatorsCtrl
class. Then
you may use this property after dialog is created, for example to set initial
properties of separator control place the following code into
OnCreate
method of your dialog:
int CSepCtrlTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
m_SepCtrl.SetShowFrame(true);
m_SepCtrl.SetText("Text to fill up the content of separator control");
m_SepCtrl.SetDisplayFontSize(12);
return 0;
}
You may also create an instance of separator control at runtime and place it
on your dialog, for example:
void CTestDynamicDlg::OnCreateCtrl()
{
if (m_pSepCtrl == NULL)
{
m_pSepCtrl = new CSeparatorsCtrl;
m_pSepCtrl->Create("MFCSeparatorsCtrl",
"Doesn't matter",
WS_CHILD | WS_VISIBLE,
CRect(0, 0, 400, 150),
this,
1);
m_pSepCtrl->SetText("something for test -------->>>> ----->>>");
m_pSepCtrl->GetSeparators()->Add(9);
m_pSepCtrl->GetSeparators()->Add(13);
m_pSepCtrl->SetScaleIntervals(5, 0);
m_pSepCtrl->SetScaleColor(RGB(0,0,155));
m_pSepCtrl->SetDisplayColor(RGB(0,0,0), RGB(0,155,0), RGB(200,200,200));
m_pSepCtrl->SetDisplayFontSize(18);
}
}
To list all selected by user columns you can use GetSeparators method
provided by CSeparatorsCtrl
class as it is shown here:
void CSepCtrlTestDlg::OnShowSeparators()
{
CDWordArray * pX = m_SepCtrl.GetSeparators();
CString str;
for (int i = 0; i < pX->GetSize(); i++)
{
str.Format("Col: %d", pX->GetAt(i));
AfxMessageBox(str);
}
}
History
- Version 1.0 - once upon a time in 2001, published 28 Apr 2004.