.
Environment: VC6
Introduction
I frequently find a need to have a control that needs to be represented differently
at run-time depending on various circumstances.
The control presented here can be switched at run-time between a number of
controls including edit, combobox, static, and checkbox controls. Another advantage
is that this control will contain both the label and the ‘user’ control items
(edits/combos/etc), which makes it easier to work with (eg disable) pairs of
labels and edit controls for instance.
The features are summarised below:
- – Dynamically switchable at run-time to one of a number of controls
- Can be made to behave as an edit, combo, static, checkbox, or date/time
control simply by setting its type at run-time
- – Eases use of control/label pairings
- The control can contain both the label and the user input control, thus
making the pair easy to disable, hide, move etc
- – Makes it easy to add tool-tips to controls
- The control may have tool-tip text set for it which appears for both the
input control and the label. CMultiCtrl manages the enabling and disabling
of tool-tips - – Provides status-bar help text for user while entering data into the
control - If tool-tip text has been set for the control, then, when the focus is set
to the control the tool-tip text appears in the status bar - – still allows working directly with underlying controls
- CMultiCtrl has methods which return (a pointer to) the underlying controls,
eg GetEditCtrl(), which allows you to easily manipulate
the control contents directly
How to use it
Follow the steps below to add a CMultiCtrl to an existing project.
- After putting the source files (MultiCtrl.cpp/h and BrowseEdit.cpp/h) into
the directory you wish to use them from, add the files to your Visual Studio
project. Note also, that MultiCtrl uses my previously published CHistoryCombo,
which can be found here,
so HistoryCombo.cpp/h need adding to your project. - In the resource editor, add a static (label) control where you wish to have
your switchable control. Give it an ID other than the default IDC_STATIC,
eg IDC_CTRL_1. - Resize the static control to reflect the size you wish to use for the mutli-ctrl.
I find it easier to work with the controls if I set the control to be centred
vertically, and to have a client-edge. (Don’t give it a border, as this cannot
be removed at run-time). - Set the text for the control to the initial label text you wish to use.
- Using the Class Wizard, add a member variable for your static control, selecting
"Control" from the "Category" list, and selecting "CMultiCtrl"
from the "Variable Type" list. (If CMultiCtrl does not appear in
the list, you may need to delete your class wizard file (.clw) and regenerate
it). I will assume your control variable name is m_ctrl. - Add a handler for WM_INITDIALOG in your dialog class if you don’t already
have one, and add the following code to it:
m_ctrl.SetType(MCT_EDIT); // set the control's type
m_ctrl.SetValueText("Hello"); // set the initial edit control text
m_ctrl.SetHelpString("This is my control"); // set the tool-tip/status-bar
text
(see the documentation for SetType() for other control
types) - In order to set and get the value, or the label, use the following functions:
To set the value:
m_ctrl.SetValueText("New control text");
To get the value:
CString sText = m_ctrl.GetValueText();
Notes on usage
As the CMultiCtrl type is changed, the underlying controls get destroyed/created
as necessary. While the value text, label text, and help-string are preserved,
any other state in the controls is not. For instance, if you are using the control
with type MCT_COMBO, and you have added items to the underlying combo’s list,
then on switching it to another type the list contents will be lost.
In a similar way, changing the styles of a control, using SetType()
may cause the control to be destroyed and recreated. This is due to the fact
that some control styles can only be set at the time of creation of the control.
Documentation
The list below shows the public functions of the CMultiCtrl class:
- void SetType(MULTICTRLTYPE mct, DWORD dwStyleAdd
= 0, DWORD dwStyleRemove = 0); - sets the control’s current type. The value can be one of the following types:
-
Type Description MCT_NONE empty invisible control MCT_STATIC static control MCT_STATICBTN static control, with label as button MCT_EDIT single edit control MCT_UPDOWNEDIT edit with nested up/down control MCT_DROPLIST drop-down list MCT_COMBO combo box MCT_CHECKBOX check box control MCT_DATETIME date/time picker MCT_RICHEDIT rich-edit control - This function also allows a style to be specified for the underlying control.
For example, when using a control as a combo-box, you could ensure that the
list is not sorted, and that the edit control auto-scrolls, using the following
code:m_ctrl.SetType(MCT_COMBO, CBS_AUTOHSCROLL, CBS_SORT);
- MULTICTRLTYPE GetType();
- returns the control’s current type, as value from the table above
- void SetAttributes(int nAttrib);
- sets the attributes of the control. The value can be a combination of the
following values: -
Attribute Description MCA_NORMAL normal – label visible, control visible and enabled MCA_READONLY label visible and enabled, control visible but disabled MCA_DISABLED everything visible but disabled MCA_HIDDEN everything hidden MCA_NOLABEL label hidden. If type is MCT_STATICBTN, this attribute
causes the label (the button) to be shown, and the static control to
be hiddenMCA_BROWSEBTN include ‘…’ button on the right of the control – currently
only available for MCT_EDIT type controlsMCA_HISTORY combo box is a history combo - Note that MCA_NORMAL, MCA_READONLY, MCA_DISABLED, and MCA_HIDDEN should
be considered as being mutually exclusive. - int GetAttributes();
- returns the controls currently set attributes, as listed above
- void SetHelpString(LPCSTR lpszHelpString);
- Sets the tool-tip/status-bar text. If lpszHelpString is NULL or points to
an empty string, tool-tips are cleared, and disabled - CString GetHelpString();
- Returns the current tool-tip/status-bar text set for the control
- void SetLabelWidth(int nWidth = MCSLW_DEFAULT);
- sets the width of the label. If nWidth is MCSLW_DEFAULT it is a pre-defined
default width, else if nWidth is MCSLW_AUTO - int GetLabelWidth(BOOL bAuto = FALSE);
- returns the width of the label. If bAuto is TRUE, returns the width which
would be used if the label was set to auto-size - BOOL IsValueChanged();
- returns whether the user has changed the value text since the last call
to SetValueText - void EnableControl(BOOL bEnable = TRUE);
- enables or disables the control
- void ResetContent();
- clears the value of the control, and also clears the drop-down list if the
control is currently a drop-list or combo - CString GetTypeName();
- returns a string representation of the current control type eg "MCT_EDIT".
Can be used for debugging. - CButton* GetButtonCtrl();
- returns a pointer to the button control, or NULL if type does not use a
button - CDateTimeCtrl* GetDateTimeCtrl();
- returns a pointer to the date/time control, or NULL if type does not use
a date/time control - CHistoryCombo* GetComboCtrl();
- returns a pointer to the combo-box control, or NULL if type doed not use
a combo-box - CStatic* GetLabelStaticCtrl();
- returns a pointer to the label static control, or NULL if label is not used,
or if it is a button - CStatic* GetStaticCtrl();
- returnsa pointer to the static control, or NULL if the type does not use
a static control - CEdit* GetEditCtrl();
- returns a pointer to the edit control, or NULL if the type does not use
an edit control - CSpinButtonCtrl* GetSpinCtrl();
- returns a pointer to the up/down control, or NULL if type does not use an
up/down control - void AddListItems(CStringList& list);
- adds string items to the combo control’s list, if the type uses a combo-box.
- void AddListItem(LPCTSTR lpszText);
- adds a string item to the combo control’s list, if the type uses a combo-box
- CString GetValueText() const;
- returns the current value text
- void SetValueText(LPCTSTR lpszValue);
- sets the value text to the value pointed to by lpszValue
- CString GetLabelText() const;
- returns the current label text
- void SetLabelText(LPCTSTR lpszString);
- sets the control’s label text
- int GetWindowText (LPTSTR lpszBuffer, int nMax) const;
- retrieves the control’s value text
- void GetWindowText (CString &rText) const;
- retreives the control’s value text
- int GetWindowTextLength() const;
- returns the length of the control’s current value text
- void SetWindowText(LPCTSTR lpszText);
- sets the control’s value text
- void SetFont(CFont *pFont, BOOL bRedraw = TRUE);
- sets the current font for the control
- void SetTextLimit(UINT nMax);
- sets the maximum length of text that be entered in the control when the
control includes an edit control, or combo-box - BOOL Create(LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff);
- Used for creating the control dynamically
- virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
- Used for creating the control dynamically
- void CheckBoxUseLabel(BOOL bUseLabel = TRUE);
- For a checkbox, uses the label text as the checkbox text, instead of the value text
- void OffsetCheckbox(BOOL bOffset = TRUE);
- Makes the left edge of the text box line up with the left edge of edit controls etc, ie it
moves the checkbox right by the label width - void SetCheckText(LPCSTR lpszChecked, LPCSTR lpszUnchecked, LPCSTR lpszIndeterminate = NULL);
- Specifies what text values should represent the checked/unchecked/indeterminate states
of the checkbox. When getting getting the value of the checkbox, the string returned will
be the string representing the current check-state - void SetCheckText(CStringList& slistChecked, CStringList& slistUnChecked, CStringList& slistIndeterminate);
- Specifies lists of possible text values which should represent the
checked/unchecked/indeterminate states of the checkbox. When getting getting the value
of the checkbox, the string returned will be the first string in the list representing
the current check-state - int GetCheckState(LPCSTR lpszValue);
- Returns the check-state represented by the value specified. If no strings match
then BST_UNCHECKED is returned - int GetEditSettings(int& nStart, int &nEnd);
- Retrieves the current selection settings of the edit control, if the control is
currently set to be an edit control. The start and end of the current selection are
returned in nStart and nEnd respectively. The function returns the first visible line - void SetEditSettings(int nStart, int nEnd, int nFirst);
- Sets the edit control’s selection to the values specified for the nStart and nEnd, if the
control is currently set to be an edit control. The nFirst parameter specifies the
first line which should be visible (applies only to multi-line edit controls) - void Initialise();
- Sets up the control’s font, dialog units, and initial type and attributes. Called from
PreSubclassWindow(), and Create() - virtual CWnd* GetMainCtrl();
- Returns a CWnd* which points to the current ‘main’ control. So, for example, if the
control is currently set to an edit control, this returns (CWnd*)GetEditControl() - BOOL IsValueChanged(LPCSTR lpszValue);
- If lpszValue is NULL, returns TRUE if the value has been changed by the user since
the last call to SetValueText(), else FALSE. If lpszValue is non-NULL, then the
function just returns whether the control contains that value. - CRichEditCtrl* GetRichEditCtrl();
- returns a pointer to the rich edit control, or NULL if type does not use
a rich edit control - CButton* GetLabelButtonCtrl();
- returns a pointer to the button used for the label control, or NULL if
the control type is not MCT_STATICBTN - void ModifyAttributes(int nAdd, int nRemove = 0);
- Modifies the control’s current attributes
- int AddListItems(CStringList& list);
- If the control is set to use a combo-box, then this function adds the items
specified in list as combo list items, and returns the number of items added.
The return value is -1 if the control does not use a combo-box - int AddListItem(LPCTSTR lpszText);
- If the control is set to use a combo-box, then this function adds the item
specified in lpszText to the combo’s list, and returns the list index of the item.
The return value is -1 if the control does not use a combo-box, or if lpszText is
NULL
Downloads
Download source – 17.0 Kb
Download demo – 120 Kb
– Version 2.1: Mar 06, 2002
Modified CBrowseEdit so that when it is created with ES_READONLY, the button is disabled. (Thanks to Ernest Laurentin for pointing out this omission!)
– Version 2: Mar 05, 2002
- added Rich Edit control to available control types
- added support for ALT+
accelerators - improved check-box support – now takes lists of strings to use for each of the check states
- new public functions:
- BOOL Create(LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff);
- virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
- void CheckBoxUseLabel(BOOL bUseLabel = TRUE);
- void OffsetCheckbox(BOOL bOffset = TRUE);
- void SetCheckText(LPCSTR lpszChecked, LPCSTR lpszUnchecked, LPCSTR lpszIndeterminate = NULL);
- void SetCheckText(CStringList& slistChecked, CStringList& slistUnChecked, CStringList& slistIndeterminate);
- int GetCheckState(LPCSTR lpszValue);
- void SetEditSettings(int nStart, int nEnd, int nFirst);
- int GetEditSettings(int& nStart, int &nEnd);
- void Initialise();
- virtual CWnd* GetMainCtrl();
- BOOL IsValueChanged(LPCSTR lpszValue);
- CRichEditCtrl* GetRichEditCtrl();
- CButton* GetLabelButtonCtrl();
- void ModifyAttributes(int nAdd, int nRemove = 0);
- int AddListItems(CStringList& list);
- int AddListItem(LPCTSTR lpszText);