//
/// \file transfer.h
/// Utilities for transferring data in and out of controls
//
// Part of OWLNext - the next generation Object Windows Library
// Copyright � 2010-2011 Vidar Hasfjord
//
// For more information, including license details, see
// http://owlnext.sourceforge.net
//
#ifndef OWL_TRANSFER_H
#define OWL_TRANSFER_H
#if defined(BI_COMP_BORLANDC)
# pragma warn -inl // Disable warning "Functions containing 'statement' is not expanded inline".
#endif
#include <owl/dialog.h>
#include <utility>
#include <functional>
#include <algorithm>
#include <type_traits>
#include <initializer_list>
namespace owl {
class _OWLCLASS TComboBoxData;
class _OWLCLASS TComboBoxExData;
class _OWLCLASS TCheckListData;
class _OWLCLASS TDateTimePickerData;
class _OWLCLASS TIPAddressBits;
class _OWLCLASS TListBoxData;
struct _OWLCLASS TMonthCalendarData;
struct _OWLCLASS TScrollBarData;
class _OWLCLASS TSystemTime;
//
/// \name Overloaded global functions
/// Avoid hiding - we are adding overloads of these.
/// @{
//
using ::GetDlgItemText;
using ::SetDlgItemText;
using ::CheckDlgButton;
/// @}
//
/// \name Utility functions for control data transfer
/// @{
//
/// String overload
//
inline _OWLFUNC(tstring) GetDlgItemText(HWND ctrl)
{return TWindow(GetParent(ctrl)).GetDlgItemText(GetDlgCtrlID(ctrl));}
//
/// String overload
//
inline _OWLFUNC(void) SetDlgItemText(HWND ctrl, const tstring& text)
{::SetDlgItemText(GetParent(ctrl), GetDlgCtrlID(ctrl), text.c_str());}
//
/// Returns true if the given control has BST_CHECKED state.
//
inline _OWLFUNC(bool) IsChecked(HWND ctrl)
{return ::IsDlgButtonChecked(GetParent(ctrl), GetDlgCtrlID(ctrl)) == BST_CHECKED;}
//
/// Returns true if the given control has BST_UNCHECKED state.
//
inline _OWLFUNC(bool) IsUnchecked(HWND ctrl)
{return ::IsDlgButtonChecked(GetParent(ctrl), GetDlgCtrlID(ctrl)) == BST_UNCHECKED;}
//
/// Returns true if the given control has BST_INDETERMINATE state.
//
inline _OWLFUNC(bool) IsIndeterminate(HWND ctrl)
{return ::IsDlgButtonChecked(GetParent(ctrl), GetDlgCtrlID(ctrl)) == BST_INDETERMINATE;}
//
/// Sets the state of the given control to BST_CHECKED (or BST_UNCHECKED).
//
inline _OWLFUNC(void) CheckDlgButton(HWND ctrl, bool checked = true)
{::CheckDlgButton(GetParent(ctrl), ::GetDlgCtrlID(ctrl), checked ? BST_CHECKED : BST_UNCHECKED);}
//
/// Sets the state of the given control to BST_UNCHECKED (or BST_CHECKED).
//
inline _OWLFUNC(void) UncheckDlgButton(HWND ctrl, bool unchecked = true)
{::CheckDlgButton(GetParent(ctrl), ::GetDlgCtrlID(ctrl), unchecked ? BST_UNCHECKED : BST_CHECKED);}
//
/// Returns the zero-based index of the selected radiobutton in the group of controls starting
/// with the given control. The function searches controls until the next control with the
/// WS_GROUP is found.
//
_OWLFUNC(int) GetSelectedRadioButtonIndex(HWND firstCtrl);
//
/// Selects the control with the given zero-based index in the group of controls starting with
/// the given control. The search for the control ends when the next control with the WS_GROUP
/// style is found, i.e. the function will not select a control beyond the first group.
//
_OWLFUNC(void) SetSelectedRadioButtonIndex(HWND firstCtrl, int selIndex);
/// @}
//
/// \name Utility functions for control data transfer - integer child ID overloads
/// @{
inline _OWLFUNC(tstring) GetDlgItemText(HWND parent, int ctrl)
{return TWindow(parent).GetDlgItemText(ctrl);}
inline _OWLFUNC(void) SetDlgItemText(HWND parent, int ctrl, const tstring& text)
{::SetDlgItemText(parent, ctrl, text.c_str());}
inline _OWLFUNC(bool) IsChecked(HWND parent, int ctrl)
{return IsChecked(GetDlgItem(parent, ctrl));}
inline _OWLFUNC(bool) IsUnchecked(HWND parent, int ctrl)
{return IsUnchecked(GetDlgItem(parent, ctrl));}
inline _OWLFUNC(bool) IsIndeterminate(HWND parent, int ctrl)
{return IsIndeterminate(GetDlgItem(parent, ctrl));}
inline _OWLFUNC(void) CheckDlgButton(HWND parent, int ctrl, int state)
{::CheckDlgButton(parent, ctrl, static_cast<UINT>(state));}
inline _OWLFUNC(void) CheckDlgButton(HWND parent, int ctrl, bool checked = true)
{CheckDlgButton(GetDlgItem(parent, ctrl), checked);}
inline _OWLFUNC(void) UncheckDlgButton(HWND parent, int ctrl, bool unchecked = true)
{UncheckDlgButton(GetDlgItem(parent, ctrl), unchecked);}
inline _OWLFUNC(int) GetSelectedRadioButtonIndex(HWND parent, int ctrl)
{return GetSelectedRadioButtonIndex(GetDlgItem(parent, ctrl));}
inline _OWLFUNC(void) SetSelectedRadioButtonIndex(HWND parent, int ctrl, int selIndex)
{SetSelectedRadioButtonIndex(GetDlgItem(parent, ctrl), selIndex);}
/// @}
//
/// Used to pass information to transfer functions.
//
struct TTransferInfo
{
HWND Window;
TTransferDirection Operation;
};
//
/// \name Transfer utility functions
/// @{
//
/// Transfers the state of the checkbox to the given bool variable.
//
_OWLFUNC(void) TransferCheckBoxData(const TTransferInfo&, HWND ctrl, bool& b);
//
/// Transfers the state of the checkbox to the given integer variable.
/// This overload supports tri-state check boxes (BST_CHECKED, BST_INDETERMINATE, BST_UNCHECKED).
//
_OWLFUNC(void) TransferCheckBoxData(const TTransferInfo&, HWND ctrl, UINT& state);
//
/// Transfers all the data for a check list box.
//
_OWLFUNC(void) TransferCheckListData(const TTransferInfo&, HWND ctrl, TCheckListData& data);
//
/// Transfers all the data for a combo box control.
//
_OWLFUNC(void) TransferComboBoxData(const TTransferInfo&, HWND ctrl, TComboBoxData& data);
//
/// Transfers the selection index of a combo box control.
//
_OWLFUNC(void) TransferComboBoxData(const TTransferInfo&, HWND ctrl, int& selIndex);
//
/// Transfers the selection string of a combo box control.
//
_OWLFUNC(void) TransferComboBoxData(const TTransferInfo&, HWND ctrl, tstring& selString, bool exact = false);
//
/// Transfers all the data for an extended combo box control.
//
_OWLFUNC(void) TransferComboBoxExData(const TTransferInfo&, HWND ctrl, TComboBoxExData& data);
//
/// Transfers all the data for a date and time picker control.
//
_OWLFUNC(void) TransferDateTimePickerData(const TTransferInfo&, HWND ctrl, TDateTimePickerData& data);
//
/// Transfers the selected date and time of a date and time picker control.
//
_OWLFUNC(void) TransferDateTimePickerData(const TTransferInfo&, HWND ctrl, TSystemTime& selTime);
//
/// Transfers the selected date and time of a date and time picker control as a string.
/// If the string is empty and the transfer direction is tdSetData, the control is set to no "no date", provided
/// that the control has the DTS_SHOWNONE style. Otherwise the control is set to the default (current) date and time.
/// If the string is non-empty, the transfer direction is tdSetData, and parsing fails, a TXOwl exception is thrown.
//
_OWLFUNC(void) TransferDateTimePickerData(const TTransferInfo&, HWND ctrl, tstring& selTime);
//
/// Transfers the text contents of a control.
//
_OWLFUNC(void) TransferDlgItemText(const TTransferInfo&, HWND ctrl, tstring& text);
//
/// Contains stream formatting parameters for use with TransferDlgItemText.
//
struct TTransferFormat
{
std::ios_base::fmtflags Flags; ///< See std::ios_base::flags.
std::streamsize Precision; ///< See std::ios_base::precision.
std::streamsize Width; ///< See std::ios_base::width.
tchar Fill; // See std::basic_ios::fill.
//
/// Mutator; can be chained, e.g. TTransferFormat().SetFlags(std::ios::showbase).SetWidth(7);
//
TTransferFormat& SetFlags(std::ios_base::fmtflags v) {Flags = v; return *this;}
//
/// Mutator; can be chained, e.g. TTransferFormat().SetPrecision(2).SetFlags(std::ios::fixed);
//
TTransferFormat& SetPrecision(std::streamsize v) {Precision = v; return *this;}
//
/// Mutator; can be chained, e.g. TTransferFormat().SetWidth(7).SetFlags(std::ios::scientific);
//
TTransferFormat& SetWidth(std::streamsize v) {Width = v; return *this;}
//
/// Mutator; can be chained, e.g. TTransferFormat().SetFill(' ').SetFlags(0);
//
TTransferFormat& SetFill(tchar v) {Fill = v; return *this;}
};
//
/// Transfers the lexical conversion of the text contents of a control using the given format.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferDlgItemText(const TTransferInfo& i, HWND ctrl, T& value, const TTransferFormat& f)
{
if (i.Operation == tdSetData)
{
tostringstream os;
os.flags(f.Flags);
if (f.Precision > 0) os.precision(f.Precision);
if (f.Width > 0) os.width(f.Width);
if (f.Fill > 0) os.fill (f.Fill);
os << value;
tstring s = os.str();
TransferDlgItemText(i, ctrl, s);
}
else if (i.Operation == tdGetData)
{
tstring s;
TransferDlgItemText(i, ctrl, s);
tistringstream is(s);
is.flags(f.Flags);
is >> value;
}
}
//
/// Overload - won't compile
/// The sole purpose of this overload is to forbid pointers.
//
template <class T>
void TransferDlgItemText(const TTransferInfo&, HWND, T* value, const TTransferFormat&)
{int pointers_are_not_allowed = value;}
//
/// Transfers the lexical conversion of the text contents of a control.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferDlgItemText(const TTransferInfo& i, HWND ctrl, T& value)
{
// Set precision to support loss-less conversion of IEEE 754 double-precision.
//
TransferDlgItemText(i, ctrl, value, TTransferFormat().SetPrecision(17));
}
//
/// Transfers the lexical conversion of the text contents of an edit control.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferEditData(const TTransferInfo& i, HWND ctrl, T& value)
{TransferDlgItemText(i, ctrl, value);}
//
/// Transfers the lexical conversion of the text contents of an edit control using the given format.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferEditData(const TTransferInfo& i, HWND ctrl, T& value, const TTransferFormat& f)
{TransferDlgItemText(i, ctrl, value, f);}
//
/// Transfers the hotkey value of a hotkey control.
//
_OWLFUNC(void) TransferHotKeyData(const TTransferInfo&, HWND ctrl, uint16& key);
//
/// Transfers the address of a IP address control as an object.
//
_OWLFUNC(void) TransferIPAddressData(const TTransferInfo&, HWND ctrl, TIPAddressBits& data);
//
/// Transfers the address for a IP address control as a 32-bit value.
//
_OWLFUNC(void) TransferIPAddressData(const TTransferInfo&, HWND ctrl, uint32& data);
//
/// Transfers all the data for a list box control.
//
_OWLFUNC(void) TransferListBoxData(const TTransferInfo&, HWND ctrl, TListBoxData& data);
//
/// Transfers the selection index of a list box control.
//
_OWLFUNC(void) TransferListBoxData(const TTransferInfo&, HWND ctrl, int& selIndex);
//
/// Transfers the selection string of a list box control.
//
_OWLFUNC(void) TransferListBoxData(const TTransferInfo&, HWND ctrl, tstring& selString, bool exact = false);
//
/// Transfers all the data for a calendar control.
//
_OWLFUNC(void) TransferMonthCalendarData(const TTransferInfo&, HWND ctrl, TMonthCalendarData& data);
//
/// Transfers the selected date and time of a calendar control.
//
_OWLFUNC(void) TransferMonthCalendarData(const TTransferInfo&, HWND ctrl, TSystemTime& curSel);
//
/// Transfers the selection range of a calendar control.
//
_OWLFUNC(void) TransferMonthCalendarData(const TTransferInfo&, HWND ctrl, std::pair<TSystemTime, TSystemTime>& rangeSel);
//
/// Transfers the index of the selected radio button within a group.
//
_OWLFUNC(void) TransferRadioButtonData(const TTransferInfo&, HWND ctrl, int& selIndex);
//
/// Transfers all the data for a scroll bar control.
//
_OWLFUNC(void) TransferScrollBarData(const TTransferInfo&, HWND ctrl, TScrollBarData& data);
//
/// Transfers the current position of a scroll bar control.
//
_OWLFUNC(void) TransferScrollBarData(const TTransferInfo&, HWND ctrl, int& position);
//
/// Transfers all the data for a slider control.
//
_OWLFUNC(void) TransferSliderData(const TTransferInfo&, HWND ctrl, TScrollBarData& data);
//
/// Transfers the current position of a slider control.
//
_OWLFUNC(void) TransferSliderData(const TTransferInfo&, HWND ctrl, int& position);
//
/// Transfers the lexical conversion of the text contents of a static control.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferStaticData(const TTransferInfo& i, HWND ctrl, T& value)
{TransferDlgItemText(i, ctrl, value);}
//
/// Transfers the lexical conversion of the text contents of a static control using the given format.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferStaticData(const TTransferInfo& i, HWND ctrl, T& value, const TTransferFormat& f)
{TransferDlgItemText(i, ctrl, value, f);}
/// @}
//
/// \name Transfer utility functions - integer child ID overloads
/// @{
//
/// Transfers the state of the checkbox to the given variable.
//
template <class T>
void TransferCheckBoxData(const TTransferInfo& i, int ctrl, T& value)
{TransferCheckBoxData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers all the data for an a check list box.
//
inline _OWLFUNC(void) TransferCheckListData(const TTransferInfo& i, int ctrl, TCheckListData& data)
{TransferCheckListData(i, GetDlgItem(i.Window, ctrl), data);}
//
/// Transfers the data or selection index of a combo box control.
//
template <class T>
void TransferComboBoxData(const TTransferInfo& i, int ctrl, T& value)
{TransferComboBoxData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the selection string of a combo box control.
//
inline _OWLFUNC(void) TransferComboBoxData(const TTransferInfo& i, int ctrl, tstring& selString, bool exact = false)
{TransferComboBoxData(i, GetDlgItem(i.Window, ctrl), selString, exact);}
//
/// Transfers all the data for an extended combo box control.
//
inline _OWLFUNC(void) TransferComboBoxExData(const TTransferInfo& i, int ctrl, TComboBoxExData& data)
{TransferComboBoxExData(i, GetDlgItem(i.Window, ctrl), data);}
//
/// Transfers the data or selected date and time of a date and time picker.
//
template <class T>
void TransferDateTimePickerData(const TTransferInfo& i, int ctrl, T& value)
{TransferDateTimePickerData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the lexical conversion of the text contents of a control.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferDlgItemText(const TTransferInfo& i, int ctrl, T& value)
{TransferDlgItemText(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the lexical conversion of the text contents of a control using the given format.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferDlgItemText(const TTransferInfo& i, int ctrl, T& value, const TTransferFormat& f)
{TransferDlgItemText(i, GetDlgItem(i.Window, ctrl), value, f);}
//
/// Transfers the lexical conversion of the text contents of an edit control.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferEditData(const TTransferInfo& i, int ctrl, T& value)
{TransferEditData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the lexical conversion of the text contents of an edit control using the given format.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferEditData(const TTransferInfo& i, int ctrl, T& value, const TTransferFormat& f)
{TransferEditData(i, GetDlgItem(i.Window, ctrl), value, f);}
//
/// Transfers the hotkey value of a hotkey control.
//
inline _OWLFUNC(void) TransferHotKeyData(const TTransferInfo& i, int ctrl, uint16& key)
{TransferHotKeyData(i, GetDlgItem(i.Window, ctrl), key);}
//
/// Transfers the address for a IP address control.
//
template <class T>
void TransferIPAddressData(const TTransferInfo& i, int ctrl, T& value)
{TransferIPAddressData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the data or selection index of a list box control.
//
template <class T>
void TransferListBoxData(const TTransferInfo& i, int ctrl, T& value)
{TransferListBoxData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the selection string of a list box control.
//
inline _OWLFUNC(void) TransferListBoxData(const TTransferInfo& i, int ctrl, tstring& selString, bool exact = false)
{TransferListBoxData(i, GetDlgItem(i.Window, ctrl), selString, exact);}
//
/// Transfers the data or selected date and time of a calendar control.
//
template <class T>
void TransferMonthCalendarData(const TTransferInfo& i, int ctrl, T& value)
{TransferMonthCalendarData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the index of the selected radio button within a group.
//
inline _OWLFUNC(void) TransferRadioButtonData(const TTransferInfo& i, int ctrl, int& selIndex)
{TransferRadioButtonData(i, GetDlgItem(i.Window, ctrl), selIndex);}
//
/// Transfers the data or current position of a scroll bar control.
//
template <class T>
void TransferScrollBarData(const TTransferInfo& i, int ctrl, T& value)
{TransferScrollBarData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the data or current position of a slider control.
//
template <class T>
void TransferSliderData(const TTransferInfo& i, int ctrl, T& value)
{TransferSliderData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the lexical conversion of the text contents of a static control.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferStaticData(const TTransferInfo& i, int ctrl, T& value)
{TransferStaticData(i, GetDlgItem(i.Window, ctrl), value);}
//
/// Transfers the lexical conversion of the text contents of a static control using the given format.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void TransferStaticData(const TTransferInfo& i, int ctrl, T& value, const TTransferFormat& f)
{TransferStaticData(i, GetDlgItem(i.Window, ctrl), value, f);}
/// @}
/// \name Transfer utility functions - DDX-like overloads
/// @{
//
/// Transfers the selection index of a combo box control.
//
inline _OWLFUNC(void) DDX_CBIndex(const TTransferInfo& i, int id, int& selIndex)
{TransferComboBoxData(i, id, selIndex);}
//
/// Transfers the selection string of a combo box control.
//
inline _OWLFUNC(void) DDX_CBString(const TTransferInfo& i, int id, tstring& selString)
{TransferComboBoxData(i, id, selString, false);}
//
/// Transfers the exact selection string of a combo box control.
//
inline _OWLFUNC(void) DDX_CBStringExact(const TTransferInfo& i, int id, tstring& selString)
{TransferComboBoxData(i, id, selString, true);}
//
/// Transfers the state of the checkbox to the given integer variable.
/// This overload supports tri-state check boxes (BST_CHECKED, BST_INDETERMINATE, BST_UNCHECKED).
//
inline _OWLFUNC(void) DDX_Check(const TTransferInfo& i, int id, UINT& state)
{TransferCheckBoxData(i, id, state);}
//
/// Transfers the selected date and time of a date and time picker control.
//
inline _OWLFUNC(void) DDX_DateTimeCtrl(const TTransferInfo& i, int id, TSystemTime& selTime)
{TransferDateTimePickerData(i, id, selTime);}
//
/// Transfers the selected date and time of a date and time picker control as a string.
//
inline _OWLFUNC(void) DDX_DateTimeCtrl(const TTransferInfo& i, int id, tstring& selTime)
{TransferDateTimePickerData(i, id, selTime);}
//
/// Transfers the hotkey value of a hotkey control.
//
inline _OWLFUNC(void) DDX_HotKey(const TTransferInfo& i, int id, uint16& key)
{TransferHotKeyData(i, id, key);}
//
/// Transfers the address for a IP address control as a 32-bit value.
//
inline _OWLFUNC(void) DDX_IPAddress(const TTransferInfo& i, int id, uint32& data)
{TransferIPAddressData(i, id, data);}
//
/// Transfers the selection index of a list box control.
//
inline _OWLFUNC(void) DDX_LBIndex(const TTransferInfo& i, int id, int& selIndex)
{TransferListBoxData(i, id, selIndex);}
//
/// Transfers the selection string of a list box control.
//
inline _OWLFUNC(void) DDX_LBString(const TTransferInfo& i, int id, tstring& selString)
{TransferListBoxData(i, id, selString, false);}
//
/// Transfers the exact selection string of a list box control.
//
inline _OWLFUNC(void) DDX_LBStringExact(const TTransferInfo& i, int id, tstring& selString)
{TransferListBoxData(i, id, selString, true);}
//
/// Transfers the selected date and time of a calendar control.
//
inline _OWLFUNC(void) DDX_MonthCalCtrl(const TTransferInfo& i, int id, TSystemTime& curSel)
{TransferMonthCalendarData(i, id, curSel);}
//
/// Transfers the index of the selected radio button within a group.
//
inline _OWLFUNC(void) DDX_Radio(const TTransferInfo& i, int id, int& selIndex)
{TransferRadioButtonData(i, id, selIndex);}
//
/// Transfers the current position of a scroll bar control.
//
inline _OWLFUNC(void) DDX_Scroll(const TTransferInfo& i, int id, int& position)
{TransferScrollBarData(i, id, position);}
//
/// Transfers all the data for a slider control.
//
inline _OWLFUNC(void) DDX_Slider(const TTransferInfo& i, int id, int& position)
{TransferSliderData(i, id, position);}
//
/// Transfers the lexical conversion of the text contents of a static control.
/// For example, numbers will be transferred as their representation as text.
//
template <class T>
void DDX_Text(const TTransferInfo& i, int id, T& value)
{TransferDlgItemText(i, id, value);}
/// @}
namespace detail
{
//
// Implementation of indirect transfer
//
// This implementation is used by all the indirect Transfer* functions, passing the specific transfer
// function for the respective control as the last parameter. Rather than pass a function pointer as
// the 'transfer' parameter, clients should pass a functor wrapper so that overload resolution is
// deferred until the actual call. This technique allows this function to serve as an indirect call to
// a whole set of overloaded transfer functions.
//
// The type of data to be transferred is deduced from the return type of the passed 'get' functor.
//
template <class TCtrl, class TGet, class TSet, class TTransfer>
void Transfer(const TTransferInfo& i, const TCtrl& ctrl, TGet get, TSet set, TTransfer transfer)
{
typedef typename std::invoke_result_t<TGet> TDataConstRef;
typedef typename std::remove_reference<TDataConstRef>::type TDataConst;
typedef typename std::remove_cv<TDataConst>::type TData;
TData data(get()); // Always initialize; the transfer function may treat it as an in-out parameter.
transfer(i, ctrl, data);
if (i.Operation == tdGetData) set(data);
}
//
// Implementation of indirect transfer, with one extra transfer parameter
//
// See the Transfer(const TTransferInfo&, const TCtrl&, TGet, TSet, TTransfer) for details.
//
template <class TCtrl, class TArg1, class TGet, class TSet, class TTransfer>
void Transfer(const TTransferInfo& i, const TCtrl& ctrl, TArg1 arg1, TGet get, TSet set, TTransfer transfer)
{
typedef typename std::invoke_result_t<TGet> TDataConstRef;
typedef typename std::remove_reference<TDataConstRef>::type TDataConst;
typedef typename std::remove_cv<TDataConst>::type TData;
TData data(get()); // Always initialize; the transfer function may treat it as an in-out parameter.
transfer(i, ctrl, data, arg1);
if (i.Operation == tdGetData) set(data);
}
//
// Implementation of indirect transfer using member functions
//
// See the Transfer(const TTransferInfo&, const TCtrl&, TGet, TSet, TTransfer) for details.
//
template <class TCtrl, class TDataSource, class R, class A, class TTransfer>
void Transfer(const TTransferInfo& i, const TCtrl& ctrl, TDataSource* d, R (TDataSource::*get)() const, void (TDataSource::*set)(A), TTransfer transfer)
{Transfer(i, ctrl, std::bind(get, d), std::bind(set, d, std::placeholders::_1), transfer);}
//
// Implementation of indirect transfer, with one extra transfer parameter, using member functions
//
// See the Transfer(const TTransferInfo&, const TCtrl&, TGet, TSet, TTransfer) for details.
//
template <class TCtrl, class TArg1, class TDataSource, class R, class A, class TTransfer>
void Transfer(const TTransferInfo& i, const TCtrl& ctrl, TArg1 arg1, TDataSource* d, R (TDataSource::*get)() const, void (TDataSource::*set)(A), TTransfer transfer)
{Transfer(i, ctrl, arg1, std::bind(get, d), std::bind(set, d, std::placeholders::_1), transfer);}
//
// Functor for deferred overload resolution
//
struct TTransferCheckBoxData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferCheckBoxData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferCheckListData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferCheckListData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferComboBoxData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferComboBoxData(i, ctrl, data);}
template <class TCtrl, class TData, class TArg1>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data, TArg1 arg1)
{TransferComboBoxData(i, ctrl, data, arg1);}
};
//
// Functor for deferred overload resolution
//
struct TTransferComboBoxExData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferComboBoxExData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferDateTimePickerData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferDateTimePickerData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferDlgItemText
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferDlgItemText(i, ctrl, data);}
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data, const TTransferFormat& f)
{TransferDlgItemText(i, ctrl, data, f);}
};
//
// Functor for deferred overload resolution
//
struct TTransferEditData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferEditData(i, ctrl, data);}
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data, const TTransferFormat& f)
{TransferEditData(i, ctrl, data, f);}
};
//
// Functor for deferred overload resolution
//
struct TTransferHotKeyData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferHotKeyData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferIPAddressData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferIPAddressData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferListBoxData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferListBoxData(i, ctrl, data);}
template <class TCtrl, class TData, class TArg1>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data, TArg1 arg1)
{TransferListBoxData(i, ctrl, data, arg1);}
};
//
// Functor for deferred overload resolution
//
struct TTransferMonthCalendarData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferMonthCalendarData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferRadioButtonData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferRadioButtonData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferScrollBarData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferScrollBarData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferSliderData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferSliderData(i, ctrl, data);}
};
//
// Functor for deferred overload resolution
//
struct TTransferStaticData
{
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data)
{TransferStaticData(i, ctrl, data);}
template <class TCtrl, class TData>
void operator()(const TTransferInfo& i, const TCtrl& ctrl, TData& data, const TTransferFormat& f)
{TransferStaticData(i, ctrl, data, f);}
};
}
/// \name Transfer utility functions - indirect transfer via member functions
/// @{
//
/// Transfers the state of the checkbox using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferCheckBoxData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferCheckBoxData());}
//
/// Transfers data for a check list box using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferCheckListData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferCheckListData());}
//
/// Transfers data for a combo box using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferComboBoxData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferComboBoxData());}
//
/// Transfers data for a combo box using the given data source and member functions.
/// This overload supports an extra transfer function argument.
//
template <class TCtrl, class TArg1, class D, class R, class A>
void TransferComboBoxData(const TTransferInfo& i, const TCtrl& ctrl, TArg1 arg1, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, arg1, d, get, set, detail::TTransferComboBoxData());}
//
/// Transfers data for a date and time picker control using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferDateTimePickerData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferDateTimePickerData());}
//
/// Transfers the text contents of a control using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferDlgItemText(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferDlgItemText());}
//
/// Transfers the text contents of a control using the given data source and member functions.
/// The given format is used to format the text when transferring data to the control.
//
template <class TCtrl, class D, class R, class A>
void TransferDlgItemText(const TTransferInfo& i, const TCtrl& ctrl, const TTransferFormat& f, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, f, d, get, set, detail::TTransferDlgItemText());}
//
/// Transfers data for a edit control using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferEditData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferEditData());}
//
/// Transfers data for a edit control using the given data source and member functions.
/// The given format is used to format the text when transferring data to the control.
//
template <class TCtrl, class D, class R, class A>
void TransferEditData(const TTransferInfo& i, const TCtrl& ctrl, const TTransferFormat& f, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, f, d, get, set, detail::TTransferEditData());}
//
/// Transfers data for a hotkey control using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferHotKeyData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferHotKeyData());}
//
/// Transfers data for an IP address control using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferIPAddressData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferIPAddressData());}
//
/// Transfers data for a list box using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferListBoxData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferListBoxData());}
//
/// Transfers data for a list box using the given data source and member functions.
/// This overload supports an extra transfer function argument.
//
template <class TCtrl, class TArg1, class D, class R, class A>
void TransferListBoxData(const TTransferInfo& i, const TCtrl& ctrl, TArg1 arg1, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, arg1, d, get, set, detail::TTransferListBoxData());}
//
/// Transfers data for a list box using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferMonthCalendarData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferMonthCalendarData());}
//
/// Transfers the index of the selected radio button within a group using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferRadioButtonData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferRadioButtonData());}
//
/// Transfers data for a scroll bar control using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferScrollBarData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferScrollBarData());}
//
/// Transfers data for a slider control using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferSliderData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferSliderData());}
//
/// Transfers data for a static control using the given data source and member functions.
//
template <class TCtrl, class D, class R, class A>
void TransferStaticData(const TTransferInfo& i, const TCtrl& ctrl, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, d, get, set, detail::TTransferStaticData());}
//
/// Transfers data for a static control using the given data source and member functions.
/// The given format is used to format the text when transferring data to the control.
//
template <class TCtrl, class D, class R, class A>
void TransferStaticData(const TTransferInfo& i, const TCtrl& ctrl, const TTransferFormat& f, D* d, R (D::*get)() const, void (D::*set)(A))
{detail::Transfer(i, ctrl, f, d, get, set, detail::TTransferStaticData());}
/// @}
/// \name Transfer utility functions - indirect transfer via functors
/// @{
//
/// Transfers the state of the checkbox using the given functors.
//
template <class TCtrl, class G, class S>
void TransferCheckBoxData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferCheckBoxData());}
//
/// Transfers data for a check list box using the given functors.
//
template <class TCtrl, class G, class S>
void TransferCheckListData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferCheckListData());}
//
/// Transfers data for a combo box using the given functors.
//
template <class TCtrl, class G, class S>
void TransferComboBoxData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferComboBoxData());}
//
/// Transfers data for a combo box using the given functors.
/// This overload supports an extra transfer function argument.
//
template <class TCtrl, class TArg1, class G, class S>
void TransferComboBoxData(const TTransferInfo& i, const TCtrl& ctrl, TArg1 arg1, G get, S set)
{detail::Transfer(i, ctrl, arg1, get, set, detail::TTransferComboBoxData());}
//
/// Transfers data for a date and time picker control using the given functors.
//
template <class TCtrl, class G, class S>
void TransferDateTimePickerData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferDateTimePickerData());}
//
/// Transfers the text contents of a control using the given functors.
//
template <class TCtrl, class G, class S>
void TransferDlgItemText(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferDlgItemText());}
//
/// Transfers the text contents of a control using the given functors.
/// The given format is used to format the text when transferring data to the control.
//
template <class TCtrl, class G, class S>
void TransferDlgItemText(const TTransferInfo& i, const TCtrl& ctrl, const TTransferFormat& f, G get, S set)
{detail::Transfer(i, ctrl, f, get, set, detail::TTransferDlgItemText());}
//
/// Transfers data for a edit control using the given functors.
//
template <class TCtrl, class G, class S>
void TransferEditData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferEditData());}
//
/// Transfers data for a edit control using the given functors.
/// The given format is used to format the text when transferring data to the control.
//
template <class TCtrl, class G, class S>
void TransferEditData(const TTransferInfo& i, const TCtrl& ctrl, const TTransferFormat& f, G get, S set)
{detail::Transfer(i, ctrl, f, get, set, detail::TTransferEditData());}
//
/// Transfers data for a hotkey control using the given functors.
//
template <class TCtrl, class G, class S>
void TransferHotKeyData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferHotKeyData());}
//
/// Transfers data for an IP address control using the given functors.
//
template <class TCtrl, class G, class S>
void TransferIPAddressData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferIPAddressData());}
//
/// Transfers data for a list box using the given functors.
//
template <class TCtrl, class G, class S>
void TransferListBoxData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferListBoxData());}
//
/// Transfers data for a list box using the given functors.
/// This overload supports an extra transfer function argument.
//
template <class TCtrl, class TArg1, class G, class S>
void TransferListBoxData(const TTransferInfo& i, const TCtrl& ctrl, TArg1 arg1, G get, S set)
{detail::Transfer(i, ctrl, arg1, get, set, detail::TTransferListBoxData());}
//
/// Transfers data for a list box using the given functors.
//
template <class TCtrl, class G, class S>
void TransferMonthCalendarData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferMonthCalendarData());}
//
/// Transfers the index of the selected radio button within a group using the given functors.
//
template <class TCtrl, class G, class S>
void TransferRadioButtonData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferRadioButtonData());}
//
/// Transfers data for a scroll bar control using the given functors.
//
template <class TCtrl, class G, class S>
void TransferScrollBarData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferScrollBarData());}
//
/// Transfers data for a slider control using the given functors.
//
template <class TCtrl, class G, class S>
void TransferSliderData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferSliderData());}
//
/// Transfers data for a static control using the given functors.
//
template <class TCtrl, class G, class S>
void TransferStaticData(const TTransferInfo& i, const TCtrl& ctrl, G get, S set)
{detail::Transfer(i, ctrl, get, set, detail::TTransferStaticData());}
//
/// Transfers data for a static control using the given functors.
/// The given format is used to format the text when transferring data to the control.
//
template <class TCtrl, class G, class S>
void TransferStaticData(const TTransferInfo& i, const TCtrl& ctrl, const TTransferFormat& f, G get, S set)
{detail::Transfer(i, ctrl, f, get, set, detail::TTransferStaticData());}
/// @}
//
/// Mix-in class template providing support for data transfer to and from controls
//
template <class TDataSource>
class TTransferWindow
: virtual public TWindow
{
public:
TTransferWindow()
: DataSource(0)
{}
TTransferWindow(TDataSource& ds)
: DataSource(&ds)
{}
//
/// Transfer the state of the window into the given data source.
//
void GetData(TDataSource& ds) const
{
TTransferInfo i = {GetHandle(), tdGetData};
const_cast<TTransferWindow*>(this)->DoTransferData(i, ds);
}
//
/// Function style overload
/// Requires that the data source type is a value type with a default constructor and
/// a copy constructor. For types without a default constructor or copy constructor,
/// use GetData(TDataSource&) instead.
//
TDataSource GetData() const
{
TDataSource ds;
GetData(ds);
return ds;
}
//
/// Transfers the state of the given data source into the window.
//
void SetData(const TDataSource& ds)
{
TTransferInfo i = {GetHandle(), tdSetData};
DoTransferData(i, const_cast<TDataSource&>(ds));
}
//
/// TWindow override
/// Initialises the transfer info and dispatches to DoTransferData.
//
virtual void TransferData(TTransferDirection d)
{
if (!DataSource) return;
TTransferInfo i = {GetHandle(), d};
DoTransferData(i, *DataSource);
}
//
/// \name Convenience functions for working with dialog items
/// @{
//
//
/// Enables (or disables) the given control.
//
void EnableDlgItem(int ctrl, bool enabled = true)
{::EnableWindow(GetDlgItem(ctrl), enabled);}
//
/// Enables (or disables) all the controls in the given sequence.
//
template <class It>
void EnableDlgItem(It first, It last, bool enabled = true)
{for (; first != last; ++first) EnableDlgItem(*first, enabled);}
//
/// Enables (or disables) all the controls in the given array.
//
template <int N>
void EnableDlgItem(const int (&id)[N], bool enabled = true)
{EnableDlgItem(id, id + N, enabled);}
//
/// Enables (or disables) all the controls in the given initializer list.
//
void EnableDlgItem(const std::initializer_list<int>& id, bool enabled = true)
{EnableDlgItem(std::begin(id), std::end(id), enabled);}
//
/// Disables (or enables) the given control.
//
void DisableDlgItem(int ctrl, bool disabled = true)
{EnableDlgItem(ctrl, !disabled);}
//
/// Disables (or enables) all the controls in the given sequence.
//
template <class It>
void DisableDlgItem(It first, It last, bool disabled = true)
{EnableDlgItem(first, last, !disabled);}
//
/// Disables (or enables) all the controls in the given array.
//
template <int N>
void DisableDlgItem(const int (&id)[N], bool disabled = true)
{EnableDlgItem(id, !disabled);}
//
/// Disables (or enables) all the controls in the given initializer list.
//
void DisableDlgItem(const std::initializer_list<int>& id, bool disabled = true)
{EnableDlgItem(std::begin(id), std::end(id), !disabled);}
//
/// Shows (or hides) the given control.
//
void ShowDlgItem(int ctrl, bool visible = true)
{::ShowWindow(GetDlgItem(ctrl), visible ? SW_SHOW : SW_HIDE);}
//
/// Shows (or hides) all the controls in the given sequence.
//
template <class It>
void ShowDlgItem(It first, It last, bool visible = true)
{for (; first != last; ++first) ShowDlgItem(*first, visible);}
//
/// Shows (or hides) all the controls in the given array.
//
template <int N>
void ShowDlgItem(const int (&id)[N], bool visible = true)
{ShowDlgItem(id, id + N, visible);}
//
/// Shows (or hides) all the controls in the given initializer list.
//
void ShowDlgItem(const std::initializer_list<int>& id, bool visible = true)
{ShowDlgItem(std::begin(id), std::end(id), visible);}
//
/// Hides (or shows) the given control.
//
void HideDlgItem(int ctrl, bool hidden = true)
{ShowDlgItem(ctrl, !hidden);}
//
/// Hides (or shows) all the controls in the given sequence.
//
template <class It>
void HideDlgItem(It first, It last, bool hidden = true)
{ShowDlgItem(first, last, !hidden);}
//
/// Hides (or shows) all the controls in the given array.
//
template <int N>
void HideDlgItem(const int (&id)[N], bool hidden = true)
{ShowDlgItem(id, !hidden);}
//
/// Hides (or shows) all the controls in the given initializer list.
//
void HideDlgItem(const std::initializer_list<int>& id, bool hidden = true)
{ShowDlgItem(std::begin(id), std::end(id), !hidden);}
//
/// Returns true if the given control has BST_CHECKED state.
//
bool IsChecked(int ctrl) const
{return IsDlgButtonChecked(ctrl) == BST_CHECKED;}
//
/// Returns true if any control in the given sequence has BST_CHECKED state.
//
template <class It>
bool IsChecked(It first, It last) const
{for (; first != last; ++first) if (IsChecked(*first)) return true; return false;}
//
/// Returns true if any control in the given array has BST_CHECKED state.
//
template <int N>
bool IsChecked(const int (&id)[N]) const
{return IsChecked(id, id + N);}
//
/// Returns true if any control in the given initializer list has BST_CHECKED state.
//
bool IsChecked(const std::initializer_list<int>&id) const
{return IsChecked(std::begin(id), std::end(id));}
//
/// Returns true if the given control has BST_UNCHECKED state.
//
bool IsUnchecked(int ctrl) const
{return IsDlgButtonChecked(ctrl) == BST_UNCHECKED;}
//
/// Returns true if any control in the given sequence has BST_UNCHECKED state.
//
template <class It>
bool IsUnchecked(It first, It last) const
{for (; first != last; ++first) if (IsUnchecked(*first)) return true; return false;}
//
/// Returns true if any control in the given array has BST_UNCHECKED state.
//
template <int N>
bool IsUnchecked(const int (&id)[N]) const
{return IsUnchecked(id, id + N);}
//
/// Returns true if any control in the given initializer list has BST_UNCHECKED state.
//
bool IsUnchecked(const std::initializer_list<int>&id) const
{return IsUnchecked(std::begin(id), std::end(id));}
//
/// Returns true if the given control has BST_INDETERMINATE state.
//
bool IsIndeterminate(int ctrl) const
{return IsDlgButtonChecked(ctrl) == BST_INDETERMINATE;}
//
/// Returns true if any control in the given sequence has BST_INDETERMINATE state.
//
template <class It>
bool IsIndeterminate(It first, It last) const
{for (; first != last; ++first) if (IsIndeterminate(*first)) return true; return false;}
//
/// Returns true if any control in the given array has BST_INDETERMINATE state.
//
template <int N>
bool IsIndeterminate(const int (&id)[N]) const
{return IsIndeterminate(id, id + N);}
//
/// Returns true if any control in the given initializer list has BST_INDETERMINATE state.
//
bool IsIndeterminate(const std::initializer_list<int>&id) const
{return IsIndeterminate(std::begin(id), std::end(id));}
//
/// using TWindow::CheckDlgButton;
//
void CheckDlgButton(int ctrl, uint state)
{TWindow::CheckDlgButton(ctrl, state);}
//
/// Resolves an integer state argument.
/// The button state macros; BST_CHECKED etc.; are of type int while the TWindow
/// function takes an uint.
//
void CheckDlgButton(int ctrl, int state)
{TWindow::CheckDlgButton(ctrl, static_cast<uint>(state));}
//
/// Sets the state of the given control to BST_CHECKED (or BST_UNCHECKED).
//
void CheckDlgButton(int ctrl, bool checked = true)
{CheckDlgButton(ctrl, checked ? BST_CHECKED : BST_UNCHECKED);}
//
/// Sets the state of the given control to BST_UNCHECKED (or BST_CHECKED).
//
void UncheckDlgButton(int ctrl, bool unchecked = true)
{CheckDlgButton(ctrl, unchecked ? BST_UNCHECKED : BST_CHECKED);}
//
/// See owl::GetSelectedRadioButtonIndex.
//
int GetSelectedRadioButtonIndex(HWND firstCtrl) const
{return owl::GetSelectedRadioButtonIndex(firstCtrl);}
//
/// See owl::GetSelectedRadioButtonIndex.
//
int GetSelectedRadioButtonIndex(int firstCtrl) const
{return GetSelectedRadioButtonIndex(GetDlgItem(firstCtrl));}
//
/// See owl::SetSelectedRadioButtonIndex.
//
void SetSelectedRadioButtonIndex(HWND firstCtrl, int selIndex)
{owl::SetSelectedRadioButtonIndex(firstCtrl, selIndex);}
//
/// See owl::SetSelectedRadioButtonIndex.
//
void SetSelectedRadioButtonIndex(int firstCtrl, int selIndex)
{SetSelectedRadioButtonIndex(GetDlgItem(firstCtrl), selIndex);}
/// @}
protected:
TDataSource* DataSource;
//
/// Transfers data between window and data source in the direction specified by the given transfer information.
/// Default implementation; forwards the call to DoGetData or DoSetData, depending on the transfer direction.
//
virtual void DoTransferData(const TTransferInfo& i, TDataSource& ds)
{
if (i.Operation == tdGetData)
DoGetData(i, ds);
else if (i.Operation == tdSetData)
DoSetData(i, ds);
}
//
/// Transfers the state of the window into the given data source.
/// Default implementation; does nothing.
//
virtual void DoGetData(const TTransferInfo&, TDataSource&) const
{}
//
/// Transfers the state of the given data source into the window.
/// Default implementation; does nothing.
//
virtual void DoSetData(const TTransferInfo&, const TDataSource&)
{}
};
//
/// Dialog class derived from TTransferWindow
/// Provides convenient initialization of the dialog and transfer window bases.
//
template <class TDataSource, class TDialogBase = TDialog>
class TTransferDialog
: virtual public TTransferWindow<TDataSource>,
public TDialogBase
{
public:
TTransferDialog(TWindow* parent, TResId id, TDataSource& ds, TModule* m = 0)
: TDialogBase(parent, id, m)
{this->DataSource = &ds;}
};
//
/// TWindow mix-in
/// Delegates the job of transferring data to the given function object.
//
class _OWLCLASS TDelegatedTransferWindow
: virtual public TWindow
{
public:
typedef void TTransferFunctionSignature(const TTransferInfo&);
typedef std::function<TTransferFunctionSignature> TTransferFunction;
TDelegatedTransferWindow(TTransferFunction f);
//
/// TWindow override
/// Dispatches to the transfer function.
//
virtual void TransferData(TTransferDirection d);
private:
TTransferFunction TransferFunction;
};
//
/// Dialog derivative of TDelegatedTransferWindow
//
class _OWLCLASS TDelegatedTransferDialog
: public TDialog,
public TDelegatedTransferWindow
{
public:
TDelegatedTransferDialog(TWindow* parent, TResId id, TTransferFunction f, TModule* module = 0);
};
//
/// Maps between application-specific value and a selection index, such as a radio-button group
/// index or a list box selection.
//
template <class TValue>
class TSelectionIndexMapper
{
public:
//
/// Constructs a new mapper given an array of values, a getter and a setter.
/// The order of the values passed determines the mapping of the selection indexes.
//
template <int N, class TGet, class TSet>
TSelectionIndexMapper(const TValue (&values)[N], TGet get, TSet set)
: Begin(&values[0]), End(&values[0] + N), Getter(get), Setter(set)
{}
//
/// Overload; specialized for member functions
//
template <int N, class D, class R, class A>
TSelectionIndexMapper(const TValue (&values)[N], D* d, R (D::*get)() const, void (D::*set)(A))
: Begin(&values[0]), End(&values[0] + N),
Getter(std::bind(get, d)),
Setter(std::bind(set, d, std::placeholders::_1))
{}
//
/// Uses the stored getter to get the application-specific value, then converts it to a selection
/// index. Returns N, the size of the value array, if the conversion can not be done.
//
int Get() const
{return static_cast<int>(std::find(Begin, End, Getter()) - Begin);}
//
/// Converts the given selection index to an application-specific value, then calls the stored
/// setter, passing the value as an argument. Does nothing if the conversion can not be done.
//
void Set(int index)
{
if (index < 0 || index > static_cast<int>(End - Begin)) return;
Setter(Begin[index]);
}
private:
const TValue* Begin;
const TValue* End;
std::function<TValue()> Getter;
std::function<void(TValue)> Setter;
};
} // OWL namespace
#if defined(BI_COMP_BORLANDC)
# pragma warn .inl // Restore warning "Functions containing 'statement' is not expanded inline".
#endif
#endif
↑ V802 On 32-bit platform, structure size can be reduced from 32 to 24 bytes by rearranging the fields according to their sizes in decreasing order.