// EnumBinderDlg.cpp : implementation file
//
#include "stdafx.h"
#include "EnumBinderApp.h"
#include "EnumBinderDlg.h"
#define REGISTRY_STEVE
#ifdef REGISTRY_STEVE
#include "Registry_Steve.h"
#else // REGISTRY_STEVE
#include "Registry_Robert.h"
#endif // REGISTRY_STEVE
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
void CEnumBinderDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO_SHAPES, m_comboShapes);
DDX_Control(pDX, IDC_LIST_CANADA, m_listCanada);
DDX_Control(pDX, IDC_COMBO_FRUIT, m_comboFruit);
DDX_Control(pDX, IDC_COMBO_WEEKDAYS, m_comboWeekdays);
// these transfer both ways just like a regular DDX
// (the default value is set in the dialog constructor)
// once the DDX_Control is used to hook it up to the control
// everything can be accessed using the enum variable
EnumShapes::DDX_Control(pDX, m_comboShapes, m_shape);
EnumCanada::DDX_Control(pDX, m_listCanada, m_canada);
EnumFruit::DDX_Control(pDX, m_comboFruit, m_fruit);
EnumWeekdaysCustom::DDX_Control(pDX, m_comboWeekdays, m_weekday);
DDX_Control(pDX, IDC_IMAGE, m_weekdayImage);
}
void CEnumBinderDlg::OnBnClickedButtonCheckValues()
{
if(UpdateData(TRUE)){
const CString messageStr
= _T("Shapes: ")
+ EnumShapes::EnumToUserString(m_shape)
+ _T("\n\nFruit: ")
+ EnumFruit::EnumToUserString(m_fruit)
+ _T("\n\nWeekdays: ")
+ EnumWeekdaysCustom::EnumToUserString(m_weekday)
+ _T("\n\nProvinces: ")
+ EnumCanada::EnumToUserString(m_canada)
;
AfxMessageBox(messageStr);
}
}
void CEnumBinderDlg::OnLbnSelchangeListCanada()
{
eCanadianProvinces selectedProvince(eCanadianProvinceON);
if(EnumCanada::GetCurSel(m_listCanada, selectedProvince)) // can fail (e.g. if there is nothing selected)
{
// in this case we are just using the code string here as a second "user string"
const CString abbreviation = EnumCanada::EnumToCodeString(selectedProvince);
SetDlgItemText(IDC_EDIT_ABBREVIATION, abbreviation);
}
}
void CEnumBinderDlg::OnCbnSelchangeComboWeekdays()
{
eWeekdays selectedDay(eTuesday);
if(EnumWeekdaysCustom::GetCurSel(m_comboWeekdays, selectedDay)) // can fail (e.g. if there is nothing selected)
{
const UINT resourceID = EnumWeekdaysCustom::GetAt(selectedDay).m_iconID;
const UINT offsetX = EnumWeekdaysCustom::GetAt(selectedDay).m_offsetX;
// change the icon
m_weekdayImage.SetIcon(AfxGetApp()->LoadIcon(resourceID));
// move the window
CRect weekdayRect;
m_comboWeekdays.GetWindowRect(weekdayRect);
CPoint newLocation(weekdayRect.right + offsetX, weekdayRect.top);
ScreenToClient(&newLocation);
m_weekdayImage.SetWindowPos(
NULL, // ignored, per flags
newLocation.x, newLocation.y,
0,0, // ignored, per flags
(SWP_NOSIZE | SWP_NOZORDER) );
}
}
void CEnumBinderDlg::OnBnClickedButtonUnitTest()
{
const bool passCanada = EnumCanada::UnitTest();
const bool passShapes = EnumShapes::UnitTest();
const bool passFruit = EnumFruit::UnitTest();
const bool passWeekdaysCustom = EnumWeekdaysCustom::UnitTest();
if( ! passCanada ) { AfxMessageBox(_T("Unit Test Failed: EnumCanada") ); }
if( ! passShapes ) { AfxMessageBox(_T("Unit Test Failed: EnumShapes") ); }
if( ! passFruit ) { AfxMessageBox(_T("Unit Test Failed: EnumFruit") ); }
if( ! passWeekdaysCustom ) { AfxMessageBox(_T("Unit Test Failed: EnumWeekdaysCustom") ); }
// should fail
if(passCanada && passShapes && passFruit && passWeekdaysCustom) {
AfxMessageBox(
_T("All unit tests passed\n")
_T("\n")
_T("To see a unit test failure, refer to the comment above the\n")
_T("BIND_ENUM(eFruit, EnumFruit) declaration in EnumBinderDlg.h")
);
}
}
void CEnumBinderDlg::RegistryExchange(bool readFromRegistry)
{
// This function shows the use of EnumBinder with two different registry classes
const CString regBaseLocation(_T("Software\\EnumBinder\\Examples"));
#ifdef REGISTRY_STEVE
// refer to the article: "Another registry class" by SteveKing
// http://www.codeproject.com/system/registryvars.asp
// for more details on this registry class
//
CRegString shapeStr(regBaseLocation + _T("\\Shapes"), EnumShapes::EnumToCodeString(m_shape)); // for default value convert existing value to string form
EnumShapes::CodeStringEnumExchange(shapeStr, m_shape, readFromRegistry);
CRegString canadaStr(regBaseLocation + _T("\\Canada"), EnumShapes::EnumToCodeString(m_shape)); // for default value convert existing value to string form
EnumCanada::CodeStringEnumExchange(canadaStr, m_canada, readFromRegistry);
CRegString fruitStr(regBaseLocation + _T("\\Fruit"), EnumFruit::EnumToCodeString(m_fruit)); // for default value convert existing value to string form
EnumFruit::CodeStringEnumExchange(fruitStr, m_fruit, readFromRegistry);
CRegString weekDaysStr(regBaseLocation + _T("\\Weekdays"), EnumWeekdaysCustom::EnumToCodeString(m_weekday)); // for default value convert existing value to string form
EnumWeekdaysCustom::CodeStringEnumExchange(weekDaysStr, m_weekday, readFromRegistry);
#else // REGISTRY_STEVE
// refer to the article "Registry Class" By Robert Pittenger
// http://www.codeproject.com/system/registry.asp
// for more details on this registry class
CRegistry Reg;
Reg.SetRootKey(HKEY_CURRENT_USER);
if (Reg.SetKey(regBaseLocation, ( ! readFromRegistry) )){
const CString regTagFruit( _T("Fruit"));
const CString regTagShapes( _T("Shapes"));
const CString regTagCanada( _T("Canada"));
const CString regTagWeekday(_T("Weekdays"));
if(readFromRegistry){
EnumFruit::CodeStringToEnum(Reg.ReadString(regTagFruit, _T("")), m_fruit);
EnumShapes::CodeStringToEnum(Reg.ReadString(regTagShapes, _T("")), m_shape);
EnumCanada::CodeStringToEnum(Reg.ReadString(regTagCanada, _T("")), m_canada);
EnumWeekdaysCustom::CodeStringToEnum(Reg.ReadString(regTagWeekday, _T("")), m_weekday);
}else{
Reg.WriteString(regTagFruit, EnumFruit::EnumToCodeString(m_fruit));
Reg.WriteString(regTagShapes, EnumShapes::EnumToCodeString(m_shape));
Reg.WriteString(regTagCanada, EnumCanada::EnumToCodeString(m_canada));
Reg.WriteString(regTagWeekday, EnumWeekdaysCustom::EnumToCodeString(m_weekday));
}
}
#endif // REGISTRY_STEVE
}
void CEnumBinderDlg::OnBnClickedOk()
{
if(UpdateData(TRUE)){
RegistryExchange(false);
OnOK();
}
}
void CEnumBinderDlg::OnBnClickedCancel()
{
if(UpdateData(TRUE)){
RegistryExchange(false);
}
OnCancel();
}
CEnumBinderDlg::CEnumBinderDlg(CWnd* pParent /*=NULL*/)
: CDialog(CEnumBinderDlg::IDD, pParent)
, m_shape(eRectangle) // just some default value
, m_canada(eCanadianProvinceON) // just some default value
, m_fruit(ePear) // just some default value
, m_weekday(eWednesday) // just some default value
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
BOOL CEnumBinderDlg::OnInitDialog()
{
// Example of indexing by enum, and changing the strings in the enum at run time
EnumCanada::ElementAt(eCanadianProvinceNU).m_stringUser += _T(" (this text changed at run time)");
RegistryExchange(true);
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
EnumBinderExamples();
OnLbnSelchangeListCanada(); // to load edit box
OnCbnSelchangeComboWeekdays(); // to load icon
return TRUE; // return TRUE unless you set the focus to a control
}
void CEnumBinderDlg::EnumBinderExamples()
{
for(int i=0; i<EnumWeekdays::GetSize(); ++i){
TRACE(_T("\n%s"), EnumWeekdays::GetAt(i).m_stringUser);
}
TRACE(_T("\n%s"), EnumWeekdays::GetAt(eTuesday).m_stringCode);
TRACE(_T("\n%s"), EnumWeekdays::GetAt(eTuesday).m_stringUser);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// No example Code below here
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// CEnumBinderDlg dialog
BEGIN_MESSAGE_MAP(CEnumBinderDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_CHECK_VALUES, OnBnClickedButtonCheckValues)
ON_LBN_SELCHANGE(IDC_LIST_CANADA, OnLbnSelchangeListCanada)
ON_BN_CLICKED(IDOK, OnBnClickedOk)
ON_BN_CLICKED(IDC_BUTTON_UNIT_TEST, OnBnClickedButtonUnitTest)
ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel)
ON_CBN_SELCHANGE(IDC_COMBO_WEEKDAYS, OnCbnSelchangeComboWeekdays)
END_MESSAGE_MAP()
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
public:
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
void CEnumBinderDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CEnumBinderDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CEnumBinderDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}