分类: C/C++
2008-09-14 20:40:32
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.
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
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:
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:
|
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. |
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->SetShowFrame(true); 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); } }