Now we will take care of exchanging data between different
list boxes.
- Add a new label on the right side of the group box with a caption of
Sample Fields
- Add a new list box under the Sample Fields label. Set its ID to
IDC_SAMPLEFIELDS and remove the check box on its Sort property
- Right-click the new list box and click ClassWizard.
- Click the Member Variables property sheet. Double-click
IDC_SAMPLEFIELDS
- Set the variable name to m_SampleFields and the Category to control
to make it a CListBox type.
- Click OK.
- In the header file of CTableWizardDlg class, declare additional
CString arrays as follows:
/////////////////////////////////////////////////////////////////////////////
// CTableWizardDlg dialog
const CString Business[] = { "Contacts",
"Customers",
"Employees",
"Products",
"Orders",
"Suppliers",
"Payments",
"Invoices",
"Projects",
"Events",
"Transactions",
"Notes" };
const CString Personal[] = { "Addresses",
"Video Collection",
"Authors",
"Books",
"Categories",
"Music Collection",
"Investments",
"Notes" };
const CString Contacts[] = { "MailingListID",
"SocialTitle",
"FirstName",
"MiddleName",
"LastName",
"Suffix",
"Nickname",
"HomeAddress",
"City",
"StateOrProvince",
"PostalCode",
"CountryOrRegion",
"HomePhone",
"WorkPhone",
"Extension",
"MobileNumber",
"EmergencyName",
"EmergencyPhone",
"Notes" };
const CString Customers[] = { "CustomerID",
"CompanyName",
"CompanyAddress",
"CompanyCity",
"CompanyState",
"companyZIPCode",
"CompanyCountry",
"CompanyPhone",
"BillingAddress",
"FaxNumber",
"WebSite",
"ContactPhone",
"ContactEMail" };
const CString Employees[] = { "EmployeeID",
"EmployeeNumber",
"DateHired",
"Title",
"FirstName",
"MI",
"LastName",
"Address",
"City",
"State",
"ZIPCode",
"Country",
"HomePhone",
"WorkPhone",
"Extension",
"CellPhone",
"EmergencyName",
"EmergencyPhone",
"Comments" };
const CString Addresses[] = { "AddressID",
"FirstName",
"LastName",
"MaritalStatus",
"Address",
"City",
"StateOrProvince",
"PostalCode",
"CountryOrRegion",
"EmergencyName",
"EmergencyPhone",
"Notes" };
const CString VideoCollection[] = { "VideoID",
"VideoTitle",
"CategoryID",
"Director",
"Rating",
"Length",
"VideoReview" };
const CString Categories[] = { "CategoryID",
"Category",
"Description" };
const CString Authors[] = { "AuthorID",
"FullName",
"Nationality",
"BirthDate",
"BirthPlace",
"AliveDead",
"Comments" };
const CString Books[] = { "BookID",
"BookTitle",
"Author",
"CategoryID",
"Publisher",
"YearPublished",
"NumberOfPages",
"ISBNNumber",
"BookReview" };
|
- In the private section of the class, add new integer variables to
hold the dimensions of the arrays as follows:
private:
// Variables used to hold the number of items in their respective array
int SizeBusiness;
int SizePersonal;
int SizeContacts;
int SizeEmployees;
int SizeAddresses;
int SizeCustomers;
int SizeVideoCollection;
int SizeCategories;
int SizeAuthors;
int SizeBooks;
};
|
- Access the TableWizardDlg.cpp file
- To make sure that the Sample Fields list is initially filled up with
the right fields, change the OnInitDialog() function as follows:
BOOL CTableWizardDlg::OnInitDialog()
{
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);
}
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// Select the Business radio button
m_SelectBusiness.SetCheck(1);
// Get the number of items in the array
SizeBusiness = sizeof(Business) / sizeof(CString);
SizePersonal = sizeof(Personal) / sizeof(CString);
SizeContacts = sizeof(Contacts) / sizeof(CString);
SizeAddresses = sizeof(Addresses) / sizeof(CString);
SizeEmployees = sizeof(Business) / sizeof(CString);
SizeCustomers = sizeof(Business) / sizeof(CString);
SizeVideoCollection = sizeof(VideoCollection) / sizeof(CString);
SizeCategories = sizeof(Categories) / sizeof(CString);
SizeAuthors = sizeof(Authors) / sizeof(CString);
SizeBooks = sizeof(Books) / sizeof(CString);
// Fill out the Sample Tables list with the Business items
for(int i = 0; i < SizeBusiness; i++)
m_SampleTables.AddString(Business[i]);
// Select the first item in the Sample Tables list box
m_SampleTables.SetCurSel(0);
// Fill out the Sample Fields list box
for(int j = 0; j < SizeContacts; j++)
m_SampleFields.AddString(Contacts[j]);
// Select the first item in the Sample Fields list box
m_SampleFields.SetCurSel(0);
return TRUE; // return TRUE unless you set the focus to a control
}
|
- You can test the program now if you want. Then close the Table
Wizard dialog box.
To make sure that the Sample Fields list is updated when one of the
radio buttons is selected, change the OnSelectBusiness() and the
OnSelectPersonal() functions as follows:
void CTableWizardDlg::OnSelectBusiness()
{
// Empty the lists
m_SampleTables.ResetContent();
m_SampleFields.ResetContent();
// Fill out the list with Business items
for(int i = 0; i < SizeBusiness; i++)
m_SampleTables.AddString(Business[i]);
m_SampleTables.SetCurSel(0);
// Fill out the Sample Fields list and select the first item
for(int j = 0; j < SizeContacts; j++)
m_SampleFields.AddString(Contacts[j]);
m_SampleFields.SetCurSel(0);
}
void CTableWizardDlg::OnSelectPersonal()
{
// Empty the lists
m_SampleTables.ResetContent();
m_SampleFields.ResetContent();
// Fill out the list
for(int i = 0; i < SizePersonal; i++)
m_SampleTables.AddString(Personal[i]);
m_SampleTables.SetCurSel(0);
// Fill out the Sample Fields list and select the first item
for(int j = 0; j < SizeAddresses; j++)
m_SampleFields.AddString(Addresses[j]);
m_SampleFields.SetCurSel(0);
}
|
- Test your program and return to MSVC
- When the user clicks a table in the Sample Tables list box, we must
change the content of the Sample Fields list box and fill it out with
the fields that are part of the selected table.
Press Ctrl + W to access the ClassWizard
- Click the Message Maps property sheet. In the Object IDs list, click
IDC_SAMPLE_TABLES
- In the Messages list, double-click LBN_SELCHANGE
- Change the name of the function to OnSelectSampleTables and click OK
- Click Edit Code and implement the function as follows:
void CTableWizardDlg::OnSelectSampleTables()
{
// Before filling out the Sample Fields list box, empty it first
m_SampleFields.ResetContent();
// This string variable will identify the selected table
CString ItemSelected;
// Get the name of the item selected in the Sample Tables list box
// and store it in the CString variable declared above
m_SampleTables.GetText(m_SampleTables.GetCurSel(), ItemSelected);
// Fill out the Sample Fields list box according to the selected table
if( ItemSelected == "Contacts" )
{
for(int i = 0; i < SizeContacts; i++)
m_SampleFields.AddString(Contacts[i]);
}
else if( ItemSelected == "Customers" )
{
for(int i = 0; i < SizeCustomers; i++)
m_SampleFields.AddString(Customers[i]);
}
else if( ItemSelected == "Employees" )
{
for(int i = 0; i < SizeEmployees; i++)
m_SampleFields.AddString(Employees[i]);
}
else if( ItemSelected == "Addresses" )
{
for(int i = 0; i < SizeAddresses; i++)
m_SampleFields.AddString(Addresses[i]);
}
else if( ItemSelected == "VideoCollection" )
{
for(int i = 0; i < SizeVideoCollection; i++)
m_SampleFields.AddString(VideoCollection[i]);
}
else if( ItemSelected == "Categories" )
{
for(int i = 0; i < SizeCategories; i++)
m_SampleFields.AddString(Categories[i]);
}
else if( ItemSelected == "Authors" )
{
for(int i = 0; i < SizeAuthors; i++)
m_SampleFields.AddString(Authors[i]);
}
else if( ItemSelected == "Books" )
{
for(int i = 0; i < SizeBooks; i++)
m_SampleFields.AddString(Books[i]);
}
else // If we didn't create a list for the selected table, show nothing
m_SampleFields.ResetContent();
// Select the first item, if any, in the Sample Fields list box
m_SampleFields.SetCurSel(0);
}
|
- Test your program. Click different radio buttons and click different
tables in the Sample Tables list
- Return to MSVC
Here is the dialog we are going to design:
- Add a new label to the top right section of the dialog and set its
caption to Selected Fields
- Add a new list box under the Selected Fields label.
- Change its ID to IDC_SELECTEDFIELDS and remove the check mark of its
Sort property.
- Right-click the new list box and click ClassWizard
- Click the Member Variables property sheet and double-click IDC_SELECTEDFIELDS
- Change the variable name to m_SelectedFields and make it a Control (CListBox
type)
- Add a Button between the right list boxes. Set its ID to IDC_BTN_SELECTONE
and its Caption to >
- Add a new button under the previous one. Set its ID to IDC_BTN_SELECTALL
and its Caption to >>
- Add a new button under the previous one. Set its ID to
IDC_BTN_REMOVEONE and its Caption to <
- Add a new button under the previous one. Set its ID to IDC_BTN_REMOVEALL
and its Caption to <<
- Press Ctrl + W to call the ClassWizard dialog.
- Click the Member Variables property sheet.
Double each of the newly added buttons and create a variable for each
as follows:
- Click the Message Maps property sheet.
- In the Object IDs list, Click IDC_BTN_SELECTONE.
- In the Messages list box, double-click BN_CLICKED
- Change the name of the function to OnSelectOne and click OK.
- Click Edit Code/
- First of all, when the dialog box opens, the Selected Fields list is
empty, which means the Remove buttons are not useful. Therefore, we
should disable them. To do this, make the following change in the
OnInitDialog() function:
// Since the Selected Field list box is empty, disable the Remove buttons
m_RemoveOne.EnableWindow(FALSE);
m_RemoveAll.EnableWindow(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
|
- You can test your program if you want and return to MSVC.
To be able to select an item from the Sample Fields list and transfer
it to the Selected Fields list box, implement the function as follows:
void CTableWizardDlg::OnSelectOne()
{
// Variable that identifies what item is selected in the sample fields
CString SourceSelected;
// Find out what item is selected
// Store it in the above variable
m_SampleFields.GetText(m_SampleFields.GetCurSel(), SourceSelected);
// Add the item to the Selected Fields list box
m_SelectedFields.AddString(SourceSelected);
}
|
- Test your program. Select different items in the Sample Fields list
and click the > button
- Return to MSVC.
- First of all, to enhance our application, we need to make sure that
the user can double-click an item in the Sample Fields list box and
obtain the same behavior as if the > button had been clicked.
Therefore, press Ctrl + W
- In the Message Maps of the ClassWizard, in the Object IDs list,
click IDC_SAMPLEFIELDS
- In the Messages list, double-click LBN_DBLCLK
- Change the name of the function to OnDblClkSampleFields and click
OK.
- Click Edit Code and implement the function as follows:
void CTableWizardDlg::OnDblClkSampleFields()
{
// When the user double-clicks an item in the Sample Fields list
// behave as if the Select One button was clicked
OnSelectOne();
}
|
- One of the problems we have at this time is that the user can select
the same item more than once, which is not practical for a database's table. Therefore, when the user selects an item, we first
need to check whether the Selected Fields list box already contains
the item. If it does, we will not allow adding the item. In Microsoft
Access, if the item already exists, its name is incremented by 1 and
added to the right list. For this exercise, I decided not to
implement that behavior, you can do it as an exercise. I will provide
an alternate solution shortly.
Also, once at least one item has been added to the Selected Fields
list, we can enable the Remove buttons.
Change the content of the OnSelectOne() function as follows:
void CTableWizardDlg::OnSelectOne()
{
// Variable that identifies what item is selected in the sample fields
CString SourceSelected;
// Find out what item is selected
// Store it in the above variable
m_SampleFields.GetText(m_SampleFields.GetCurSel(), SourceSelected);
// Find out if the Selected Fields list is empty
if( m_SelectedFields.GetCount() == 0 )
{
// Since the list is empty, add the selected item
m_SelectedFields.AddString(SourceSelected);
// Select the newly added item
m_SelectedFields.SetCurSel(0);
}
else // Since the list is not empty
{
// Look for the selected item in the Selected Fields list
int Found = m_SelectedFields.FindString(0, SourceSelected);
// If the item is not yet in the Selected Fields list, prepare to add it
if( Found == -1 )
{
// Because there is always an item selected in any of our list,
// get the index of the currently selected item
int CurrentlySelected = m_SelectedFields.GetCurSel();
// Add the new item under the selected one
m_SelectedFields.InsertString(CurrentlySelected + 1, SourceSelected);
// Select the newly added item
m_SelectedFields.SetCurSel(CurrentlySelected + 1);
}
}
// Since an item has been selected, enable the Remove buttons
m_RemoveOne.EnableWindow();
m_RemoveAll.EnableWindow();
}
|
- Test your program. Double-click various items in the Sample Fields
list box and observe the behavior.
- Return to MSVC.
- Now, we need to deal with the Select All button. What we need to do
is to select all items in the Sample Fields list and copy them to the
Selected Fields list. As previously, we need to avoid duplicating the
names of fields in the same table. Therefore, to add the items to the
list, first select one at a time, look for it in the Selected Fields
list. If it doesn't exist, then add it. If it already exists, ignore
it and consider the next item. This behavior can be performed in a for
loop that is used to navigate the items in an array.
Press Ctrl + W.
- In the Object IDs list, click IDC_BTN_SELECTALL
- In the Messages list, double-click BN_CLICKED
- Change the name of the function to OnSelectAll and click OK
- Click Edit Code and implement the function as follows:
void CTableWizardDlg::OnSelectAll()
{
// This string will represent an item in the Sample Fields list
CString Item;
// This "for" loop will be used to navigate the Sample Fields list
for(int i = 0; i < m_SampleFields.GetCount(); i++)
{
// Consider an item in the Sample Fields list
// Store it in the above declared Item variable
m_SampleFields.GetText(i, Item);
// Look for the item in the Selected Fields list
// Make sure you start at the beginning of the list, which is item 0
int Found = m_SelectedFields.FindString(0, Item);
// If the item is not yet in the Selected Fields list, prepare to add it
if( Found == -1 )
{
// Add the new item at the end of the Selected Fields list
m_SelectedFields.AddString(Item);
// Select the last item of the Selected Fields list
m_SelectedFields.SetCurSel(m_SelectedFields.GetCount() - 1);
} // Consider the next item
}
// Since there is at least one item in the Selected Fields list,
// enable the Remove buttons
m_RemoveOne.EnableWindow();
m_RemoveAll.EnableWindow();
}
|
- Test your program and return to MSVC
- The < button works by removing, from the Selected Fields list
box, the item that is selected. To do this, we first need to make sure
that an item is selected. All the previous code took care of selecting
an item in each list. The problem is that, this time, the selected
item is removed. Therefore, we have the responsibility of selecting a new
item.
When an item has been removed, we will select the item that was
under it. What if we had removed the item that was at the bottom of
the list? In that case, we will select the new last item in the list.
Press Ctrl + W
- In the Object IDs, click IDC_BTN_REMOVEONE
- In the Messages list, double-click BN_CLICKED
- Change the name of the function OnRemoveOne and press Enter
- Click Edit Code and implement the function as follows:
void CTableWizardDlg::OnRemoveOne()
{
// Based on previous code, an item should be selected
// in the Selected Fields list
// Get the index of the currently selected item
int CurrentlySelected = m_SelectedFields.GetCurSel();
// Remove the item from the list
m_SelectedFields.DeleteString(CurrentlySelected);
// Find out whether the list has just been emptied or not
// If the Selected Fields list is empty,
if( m_SelectedFields.GetCount() == 0 )
{
// then disable the Remove buttons
m_RemoveOne.EnableWindow(FALSE);
m_RemoveAll.EnableWindow(FALSE);
}
else // Since the Selected Fields list still contains something
{
// Find out if the item that has just been removed was the last in the list
if( CurrentlySelected == m_SelectedFields.GetCount() )
{
// Select the last item in the list
m_SelectedFields.SetCurSel(m_SelectedFields.GetCount() - 1);
}
else // Otherwise
{
// Select the item that was above the one that was just deleted
m_SelectedFields.SetCurSel(CurrentlySelected);
}
}
}
|
- We also want the user to be able to remove an item by double-clicking it. This is
the way it is done in Microsoft Access. Of course this is, not only
optional, but also application independent because another program
would have a different behavior when the item is double-clicked.
Press Ctrl + W
- In the Object IDs list, click IDC_SELECTEDFIELDS
- In the Messages list, double-click LBN_DBLCLK
- Change the function name to OnDblClkSelectedFields and press Enter
- Click Edit Code and implement the function as follows:
void CTableWizardDlg::OnDblClkSelectedFields()
{
// When the user double-clicks an item in the Selected Fields list,
// behave as if the < button has been clicked
OnRemoveOne();
}
|
- Test your program and return to MSVC.
- The << button is used to simply empty the Selected Fields
list. It doesn't perform any checking of any kind. The only thing we
need to do is to disable the Remove buttons after the Selected Fields
list has been emptied.
Press Ctrl + W
- In the Object IDs list, click IDC_BTN_REMOVEALL
- In the Messages list, double-click BN_CLICKED
- Change the function name to OnRemoveAll and press Enter
- Click Edit Code and implement the function as follows:
void CTableWizardDlg::OnRemoveAll()
{
m_SelectedFields.ResetContent();
// Since the Selected Fields list is now empty,
// disable the Remove buttons
m_RemoveOne.EnableWindow(FALSE);
m_RemoveAll.EnableWindow(FALSE);
}
|
- Test your program and return to MSVC.
- Since we, or I, decided not to increment the name of an already
existing field in the Selected Fields list, we will solve this problem
otherwise. In fact, we will solve two problems with one approach. We
are going to allow the user to rename an item.
Only an item from the Selected Fields list can be renamed. To do this,
we will first make sure that an item is selected. If an item is
selected, we will allow the user to click the Rename Field button. A dialog
box will open with the name of the selected field. The user will have
the option of changing the field's name or dismissing the operation.
If the user clicked OK, we will change the old item with the new one
and select the new item. This operation will not only allow the user
to set an appropriate or friendlier name but can also let the user have
fields such as Address1 and Address2.
- Press Ctrl + R to call the Insert Resource dialog box.
- Click Dialog and click New
- Press Alt + Enter to call the Properties dialog box.
- Change the ID of the dialog box to IDD_DLG_RENAMEFIELD and change
its Caption to Rename Field
- Using the Toolbox, add an Edit Box control to the dialog box.
- Change its ID to IDC_EDIT_RENAME
- Add a Static Text with a Caption of Rename Field on the left side of
the edit box.
- While the dialog is selected, on the main menu, click Layout ->
Tab Order
- Click the edit box to make sure that it receives focus when the
dialog is opened:
- Right-click the edit box and click ClassWizard.
- On the Adding A Class dialog box, click the Create A New Class radio
button and click OK
- Type the class name as CRenameFieldDlg
- Make sure the Base Class is CDialog and the Dialog ID is IDD_DLG_RENAMEFIELD. Click OK
- Click the Member Variables property sheet. Double-click
IDC_EDIT_RENAME
- Set the name of the variable to m_RenameField
- Make sure its Category is Value and its Variable Type is CString.
Click OK twice
- Open the main dialog box, the Table Wizard.
- Using the Toolbox, add a button identified as IDC_BTN_RENAMEFIELD
- Change its Caption to &Rename Field...
- Press Ctrl + W
- In the Member Variables property sheet, double-click
IDC_BTN_RENAMEFIELD
- Change its name to m_RenameField
- Make sure its Category is Control and its Type is CButton. Click OK
- Click the Message Maps property sheet.
- In the Class Name combo box, select CTableWizardDlg (it should be
selected by default, but just in case...).
In the Object IDs list, click IDC_BTN_RENAMEFIELD
- In the Messages list box, double-click BN_CLICKED
- Change the name of the function to OnRenameField and press Enter.
- Click Edit Code.
Since the Selected Fields list is empty when the dialog opens, the
Rename Field button should be disabled. In fact the Rename Field
button should be disabled whenever the Selected Field list box is
empty or not item is selected in the Selected Fields list.
- Make the following changes to the whole file:
// TableWizardDlg.cpp : implementation file
//
#include "stdafx.h"
#include "TableWizard.h"
#include "TableWizardDlg.h"
#include "RenameFieldDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTableWizardDlg dialog
CTableWizardDlg::CTableWizardDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTableWizardDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTableWizardDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTableWizardDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTableWizardDlg)
DDX_Control(pDX, IDC_BTN_RENAMEFIELD, m_RenameField);
DDX_Control(pDX, IDC_BTN_SELECTONE, m_SelectOne);
DDX_Control(pDX, IDC_BTN_SELECTALL, m_SelectAll);
DDX_Control(pDX, IDC_BTN_REMOVEONE, m_RemoveOne);
DDX_Control(pDX, IDC_BTN_REMOVEALL, m_RemoveAll);
DDX_Control(pDX, IDC_SELECTEDFIELDS, m_SelectedFields);
DDX_Control(pDX, IDC_SAMPLEFIELDS, m_SampleFields);
DDX_Control(pDX, IDC_RDO_PERSONAL, m_SelectPersonal);
DDX_Control(pDX, IDC_RDO_BUSINESS, m_SelectBusiness);
DDX_Control(pDX, IDC_SAMPLE_TABLES, m_SampleTables);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTableWizardDlg, CDialog)
//{{AFX_MSG_MAP(CTableWizardDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_RDO_BUSINESS, OnSelectBusiness)
ON_BN_CLICKED(IDC_RDO_PERSONAL, OnSelectPersonal)
ON_BN_CLICKED(IDC_BTN_SELECTONE, OnSelectOne)
ON_LBN_SELCHANGE(IDC_SAMPLE_TABLES, OnSelectSampleTables)
ON_LBN_DBLCLK(IDC_SAMPLEFIELDS, OnDblClkSampleFields)
ON_BN_CLICKED(IDC_BTN_SELECTALL, OnSelectAll)
ON_BN_CLICKED(IDC_BTN_REMOVEONE, OnRemoveOne)
ON_LBN_DBLCLK(IDC_SELECTEDFIELDS, OnDblClkSelectedFields)
ON_BN_CLICKED(IDC_BTN_REMOVEALL, OnRemoveAll)
ON_BN_CLICKED(IDC_BTN_RENAMEFIELD, OnRenameField)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTableWizardDlg message handlers
BOOL CTableWizardDlg::OnInitDialog()
{
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);
}
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// Select the Business radio button
m_SelectBusiness.SetCheck(1);
// Get the number of items in the array
SizeBusiness = sizeof(Business) / sizeof(CString);
SizePersonal = sizeof(Personal) / sizeof(CString);
SizeContacts = sizeof(Contacts) / sizeof(CString);
SizeAddresses = sizeof(Addresses) / sizeof(CString);
SizeEmployees = sizeof(Business) / sizeof(CString);
SizeCustomers = sizeof(Business) / sizeof(CString);
SizeVideoCollection = sizeof(VideoCollection) / sizeof(CString);
SizeCategories = sizeof(Categories) / sizeof(CString);
SizeAuthors = sizeof(Authors) / sizeof(CString);
SizeBooks = sizeof(Books) / sizeof(CString);
// Fill out the Sample Tables list with the Business items
for(int i = 0; i < SizeBusiness; i++)
m_SampleTables.AddString(Business[i]);
// Select the first item in the Sample Tables list box
m_SampleTables.SetCurSel(0);
// Fill out the Sample Fields list box
for(int j = 0; j < SizeContacts; j++)
m_SampleFields.AddString(Contacts[j]);
// Select the first item in the Sample Fields list box
m_SampleFields.SetCurSel(0);
// Since the Selected Field list box is empty, disable the Remove buttons
m_RemoveOne.EnableWindow(FALSE);
m_RemoveAll.EnableWindow(FALSE);
// The Selected Fields list is empty.
// There is not need for the Rename Field button
m_RenameField.EnableWindow(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CTableWizardDlg::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 CTableWizardDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (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();
}
}
HCURSOR CTableWizardDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CTableWizardDlg::OnSelectBusiness()
{
// Empty the lists
m_SampleTables.ResetContent();
m_SampleFields.ResetContent();
// Fill out the list with Business items
for(int i = 0; i < SizeBusiness; i++)
m_SampleTables.AddString(Business[i]);
m_SampleTables.SetCurSel(0);
// Fill out the Sample Fields list and select the first item
for(int j = 0; j < SizeContacts; j++)
m_SampleFields.AddString(Contacts[j]);
m_SampleFields.SetCurSel(0);
}
void CTableWizardDlg::OnSelectPersonal()
{
// Empty the lists
m_SampleTables.ResetContent();
m_SampleFields.ResetContent();
// Fill out the list
for(int i = 0; i < SizePersonal; i++)
m_SampleTables.AddString(Personal[i]);
m_SampleTables.SetCurSel(0);
// Fill out the Sample Fields list and select the first item
for(int j = 0; j < SizeAddresses; j++)
m_SampleFields.AddString(Addresses[j]);
m_SampleFields.SetCurSel(0);
}
void CTableWizardDlg::OnSelectSampleTables()
{
// Before filling out the Sample Fields list box, empty it first
m_SampleFields.ResetContent();
// This string variable will identify the selected table
CString ItemSelected;
// Get the name of the item selected in the Sample Tables list box
// and store it in the CString variable declared above
m_SampleTables.GetText(m_SampleTables.GetCurSel(), ItemSelected);
// Fill out the Sample Fields list box according to the selected table
if( ItemSelected == "Contacts" )
{
for(int i = 0; i < SizeContacts; i++)
m_SampleFields.AddString(Contacts[i]);
}
else if( ItemSelected == "Customers" )
{
for(int i = 0; i < SizeCustomers; i++)
m_SampleFields.AddString(Customers[i]);
}
else if( ItemSelected == "Employees" )
{
for(int i = 0; i < SizeEmployees; i++)
m_SampleFields.AddString(Employees[i]);
}
else if( ItemSelected == "Addresses" )
{
for(int i = 0; i < SizeAddresses; i++)
m_SampleFields.AddString(Addresses[i]);
}
else if( ItemSelected == "VideoCollection" )
{
for(int i = 0; i < SizeVideoCollection; i++)
m_SampleFields.AddString(VideoCollection[i]);
}
else if( ItemSelected == "Categories" )
{
for(int i = 0; i < SizeCategories; i++)
m_SampleFields.AddString(Categories[i]);
}
else if( ItemSelected == "Authors" )
{
for(int i = 0; i < SizeAuthors; i++)
m_SampleFields.AddString(Authors[i]);
}
else if( ItemSelected == "Books" )
{
for(int i = 0; i < SizeBooks; i++)
m_SampleFields.AddString(Books[i]);
}
else // If we didn't create a list for the selected table, show nothing
m_SampleFields.ResetContent();
// Select the first item, if any, in the Sample Fields list box
m_SampleFields.SetCurSel(0);
}
void CTableWizardDlg::OnSelectOne()
{
// Variable that identifies what item is selected in the sample fields
CString SourceSelected;
// Find out what item is selected
// Store it in the above variable
m_SampleFields.GetText(m_SampleFields.GetCurSel(), SourceSelected);
// Find out if the Selected Fields list is empty
if( m_SelectedFields.GetCount() == 0 )
{
// Since the list is empty, add the selected item
m_SelectedFields.AddString(SourceSelected);
// Select the newly added item
m_SelectedFields.SetCurSel(0);
}
else // Since the list is not empty
{
// Look for the selected item in the Selected Fields list
int Found = m_SelectedFields.FindString(0, SourceSelected);
// If the item is not yet in the Selected Fields list, prepare to add it
if( Found == -1 )
{
// Because there is always an item selected in any of our list,
// Get the index of the currently selected item
int CurrentlySelected = m_SelectedFields.GetCurSel();
// Add the new item under the selected one
m_SelectedFields.InsertString(CurrentlySelected + 1, SourceSelected);
// Selected the newly added item
m_SelectedFields.SetCurSel(CurrentlySelected + 1);
}
}
// Since an item has been selected, enable the Remove buttons
m_RemoveOne.EnableWindow();
m_RemoveAll.EnableWindow();
// Since an item is selected, enable the Rename button
m_RenameField.EnableWindow();
}
void CTableWizardDlg::OnDblClkSampleFields()
{
// When the user double-clicks an item in the Sample Fields list
// behave as if the Select One button was clicked
OnSelectOne();
}
void CTableWizardDlg::OnSelectAll()
{
// This string will represent an item in the Sample Field list
CString Item;
// This "for" loop will be used to navigate the Sample Fields list
for(int i = 0; i < m_SampleFields.GetCount(); i++)
{
// Consider an item in the Sample Fields list
// Store it in the above declared Item variable
m_SampleFields.GetText(i, Item);
// Look for the item in the Selected Fields list
int Found = m_SelectedFields.FindString(0, Item);
// If the item is not yet in the Selected Fields list, prepare to add it
if( Found == -1 )
{
// Add the new item at the end of the Selected Fields list
m_SelectedFields.AddString(Item);
// Selected the last item of the Selected Fields list
m_SelectedFields.SetCurSel(m_SelectedFields.GetCount() - 1);
}
}
// Since there is at least one item in the Selected Fields list
// enable the Remove buttons
m_RemoveOne.EnableWindow();
m_RemoveAll.EnableWindow();
// Enable the Rename button
m_RenameField.EnableWindow();
}
void CTableWizardDlg::OnRemoveOne()
{
// Based on previous code, an item should be selected
// in the Selected Fields list
// Get the index of the currently selected item
int CurrentlySelected = m_SelectedFields.GetCurSel();
m_SelectedFields.DeleteString(CurrentlySelected);
// Find out whether the list has just been emptied or not
// If the Selected Fields list is empty
if( m_SelectedFields.GetCount() == 0 )
{
// disable the Remove buttons
m_RemoveOne.EnableWindow(FALSE);
m_RemoveAll.EnableWindow(FALSE);
//and disable the Rename button
m_RenameField.EnableWindow(FALSE);
}
else // Since the Selected Fields list still contains something
{
// Find out if the item that has just been removed was the last in the list
if( CurrentlySelected == m_SelectedFields.GetCount() )
{
// Selected the last item in the list
m_SelectedFields.SetCurSel(m_SelectedFields.GetCount() - 1);
}
else // Otherwise
{
// Select the item that was above the one that was just deleted
m_SelectedFields.SetCurSel(CurrentlySelected);
}
}
}
void CTableWizardDlg::OnDblClkSelectedFields()
{
// When the user double-clicks an item in the Selected Fields list
// behave as if the Remove One button has been clicked
OnRemoveOne();
}
void CTableWizardDlg::OnRemoveAll()
{
m_SelectedFields.ResetContent();
// Since the Selected Fields list is now empty,
// disable the Remove buttons
m_RemoveOne.EnableWindow(FALSE);
m_RemoveAll.EnableWindow(FALSE);
// and enable the Rename button
m_RenameField.EnableWindow(FALSE);
}
void CTableWizardDlg::OnRenameField()
{
// Declare a variable to store the currently selected item
CString SelectedItem;
// Get the index of the currently selected item
int CurrentlySelected = m_SelectedFields.GetCurSel();
// The dialog box that will be called
CRenameFieldDlg Dlg;
// Retrieve the string of the currently selected item
// and store it in the SelectedItem variable
m_SelectedFields.GetText(m_SelectedFields.GetCurSel(), SelectedItem);
// Put the selected string int the Edit box of the Rename Field dialog
Dlg.m_RenameField.Format("%s", SelectedItem);
// Now call the Rename Field dialog box
// Show the field to the user
// Find out if the user clicked OK when dismissing the dialog box
if( Dlg.DoModal() )
{
// Since the user has clicked OK on the Rename Field dialog box,
// before proceeding, delete the old string from the list
m_SelectedFields.DeleteString(CurrentlySelected);
LPTSTR NewItem;
NewItem = Dlg.m_RenameField.GetBuffer(10);
// Look for the new item in the Selected Fields list
int Found = m_SelectedFields.FindString(0, NewItem);
// If the item is not yet in the Selected Fields list, prepare to add it
if( Found == -1 )
{
// Add the new item under the selected one
m_SelectedFields.InsertString(CurrentlySelected, NewItem);
// Select the newly added item
m_SelectedFields.SetCurSel(CurrentlySelected);
}
Dlg.m_RenameField.ReleaseBuffer();
}
}
|
- Test your program
|