📄 addtbdlg.cpp
字号:
// AddTdDlg.cpp : implementation file for dialog that allows user to
// specify fields that constitute the tabledef's structure
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "daotable.h"
#include "tabledef.h"
#include "field.h"
#include "AddTbDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgAddTable dialog
// default constructor
CDlgAddTable::CDlgAddTable(CWnd* pParent /*=NULL*/)
: CDialog(CDlgAddTable::IDD, pParent)
{
// call centralized initialization function
initializer();
}
// the constructor that will generally be called to create this dialog
//
// IN: pDatabase--pointer to an open database object
// IN: strTableName--name of table whose fields will be added, deleted, or viewed
// IN: pParent--pointer to parent of the dialog
//
CDlgAddTable::CDlgAddTable(CDaoDatabase *pDatabase, CString strTableName,
CWnd * pParent)
: CDialog(CDlgAddTable::IDD, pParent)
{
// the incoming database pointer that is used in creating the tabledef
m_pDatabase = pDatabase;
// transfer name of table (if any) to member
m_strTableName = strTableName;
// call centralized function to initialize dialog data and other
// member data
initializer();
}
// set up the members of this class
void CDlgAddTable::initializer()
{
// initialize the field info members (including ordinal position)
fieldInitializer(TRUE);
// no fields added to table yet
m_bFirstFieldAdded = FALSE;
// when DoDataExchange is executed, check validity of transferred data
m_bCheckDDV = TRUE;
// no tabledef until it is created with the user specified name
m_pTableDef = NULL;
// the index into the collection of fields for the current field
m_nFieldIndex = 0;
// initialize type map. The combobox list is sequential, the internal
// constants for DAO are not.
m_nTypeMap[Boolean] = dbBoolean;
m_nTypeMap[Byte] = dbByte;
m_nTypeMap[Currency] = dbCurrency;
m_nTypeMap[Date] = dbDate;
m_nTypeMap[Double] = dbDouble;
m_nTypeMap[Long] = dbLong;
m_nTypeMap[LongBinary] = dbLongBinary;
m_nTypeMap[Memo] = dbMemo;
m_nTypeMap[Short] = dbInteger; // it is really a short integer
m_nTypeMap[Single] = dbSingle;
m_nTypeMap[Text] = dbText;
}
// initialize the field information to a default state.
// IN: bInitOrdPos -- The ordinal position is conditionally initialized
// to allow for it autoincrementing with each addition of a field to the
// tabledef--TRUE by default
void CDlgAddTable::fieldInitializer(BOOL bInitOrdPos /* = TRUE */)
{
// conditionally initialize the ordinal position
if (bInitOrdPos)
m_FI.m_nOrdinalPosition = 0;
// always initialize the rest
m_FI.m_strName = _T("");
m_FI.m_nType = -1; // initialized for the benefit of the combox
m_FI.m_lSize = 0;
m_FI.m_strDefaultValue = _T("");
m_FI.m_bRequired = FALSE;
m_FI.m_lAttributes = dbUpdatableField;
#if _MFC_VER == 0x400
m_FI.m_bAllowZeroLength = TRUE;
#else
m_FI.m_bAllowZeroLength = FALSE;
#endif;
m_FI.m_strValidationRule = _T("");
m_FI.m_strValidationText = _T("");
}
void CDlgAddTable::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgAddTable)
DDX_Control(pDX, IDC_VALIDATION_TEXT, m_ValidationTextControl);
DDX_Control(pDX, IDC_VALIDATION_RULE, m_ValidationRuleControl);
DDX_Control(pDX, IDC_REQUIRED, m_RequireControl);
DDX_Control(pDX, IDC_POSITION, m_OrdinalPositionControl);
DDX_Control(pDX, IDC_NAME, m_NameControl);
DDX_Control(pDX, IDC_THE_SIZE, m_SizeControl);
DDX_Control(pDX, IDC_DEFAULT_VALUE, m_DefaultValueControl);
DDX_Control(pDX, IDC_AUTO_INCR_FIELD, m_AutoIncrFieldControl);
DDX_Control(pDX, IDC_FIXED_FIELD, m_FieldVariabilityControl);
DDX_Text(pDX, IDC_TABLE_NAME, m_strTableName);
//}}AFX_DATA_MAP
// move those DDX calls that use DDV or map directly to members
// of the field info struct, or require special processing outside
// of the wizard block
DDX_Control(pDX, IDC_TYPE, m_TypeControl);
// only check validity if so instructed--avoids unnecessary warnings
if (m_bCheckDDV)
// user must select a type for the field
DDV_NoSel(pDX, &m_TypeControl);
// direct mapping to field info struct
DDX_Text(pDX, IDC_POSITION, m_FI.m_nOrdinalPosition);
DDX_Text(pDX, IDC_NAME, m_FI.m_strName);
DDX_Text(pDX, IDC_VALIDATION_RULE, m_FI.m_strValidationRule);
DDX_Text(pDX, IDC_VALIDATION_TEXT, m_FI.m_strValidationText);
DDX_Text(pDX, IDC_THE_SIZE, m_FI.m_lSize);
DDX_Text(pDX, IDC_DEFAULT_VALUE, m_FI.m_strDefaultValue);
DDX_Check(pDX, IDC_REQUIRED, m_FI.m_bRequired);
// manage the type control directly since we need to use the type
// map (combobox uses sequential index, DAO types are non-sequential)
if (pDX->m_bSaveAndValidate)
{
// when transferring from dialog control to member, use map the
// easy way--just index into it
theTypes selectedType = (theTypes) m_TypeControl.GetCurSel();
m_FI.m_nType = m_nTypeMap[selectedType];
}
else
{
// if the type is -1, then no type selected
if (m_FI.m_nType == -1)
{
// update control appropriately
m_TypeControl.SetCurSel(m_FI.m_nType);
}
else
{
// must search the map looking for a match--
// search for actual type to determine internally used type
for (int i = 0; (i < MAX_TYPES) && (m_nTypeMap[i] != m_FI.m_nType); i++)
;
// update control appropriately
m_TypeControl.SetCurSel(i);
}
}
// do attribute specific processing -- member values are encoded in
// the m_lAttributes of CDaoFieldInfo struct
if (pDX->m_bSaveAndValidate)
{
// first do transfer
DDX_Radio(pDX, IDC_FIXED_FIELD, m_FieldVariability);
DDX_Check(pDX, IDC_AUTO_INCR_FIELD, m_bAutoIncrField);
// if transferring to member from control, determine the
// attributes value to store for field
if (m_bAutoIncrField)
m_FI.m_lAttributes |= dbAutoIncrField;
else
m_FI.m_lAttributes &= ~dbAutoIncrField;
// for text fields only, set the variability
if (m_FI.m_nType == dbText)
if (m_FieldVariability == 0)
m_FI.m_lAttributes |= dbFixedField;
else
m_FI.m_lAttributes |= dbVariableField;
}
else
{
// transferring from field attributes to controls
m_bAutoIncrField = (m_FI.m_lAttributes & dbAutoIncrField) == dbAutoIncrField;
if ((m_FI.m_lAttributes & dbFixedField) == dbFixedField)
m_FieldVariability = 0;
else
m_FieldVariability = 1;
// now transfer the information to the controls
DDX_Radio(pDX, IDC_FIXED_FIELD, m_FieldVariability);
DDX_Check(pDX, IDC_AUTO_INCR_FIELD, m_bAutoIncrField);
}
}
// check if a type selection was made--one must be made
void CDlgAddTable::DDV_NoSel(CDataExchange* pDX, CComboBox *theControl)
{
// only process if transferring to member from control. If
// no selection has been made, this constitutes an error condition
if (pDX->m_bSaveAndValidate && (CB_ERR == theControl->GetCurSel()))
{
AfxMessageBox(_T("You must select a type."), MB_ICONEXCLAMATION);
pDX->m_hWndLastControl = theControl->m_hWnd;
pDX->Fail();
}
}
BEGIN_MESSAGE_MAP(CDlgAddTable, CDialog)
//{{AFX_MSG_MAP(CDlgAddTable)
ON_BN_CLICKED(IDC_NEXT_FIELD, OnNextField)
ON_CBN_SELENDOK(IDC_TYPE, OnSelendokType)
ON_BN_CLICKED(IDOK, OnDone)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_PREVIOUS_FIELD, OnPreviousField)
ON_BN_CLICKED(IDC_DELETE_FIELD, OnDeleteField)
ON_BN_CLICKED(IDC_ADD_FIELD, OnAddField)
ON_CBN_CLOSEUP(IDC_TYPE, OnCloseupType)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgAddTable message handlers
BOOL CDlgAddTable::OnInitDialog()
{
CDialog::OnInitDialog();
// user either specified new table or existing table
if(!IsExistentTable(m_pDatabase, m_strTableName))
{
// initialize size control to disabled until we know field type
// since that is what defines size (unless variable field type)
m_SizeControl.EnableWindow(FALSE);
// until a field has been added, can not be "done" since a tabledef
// must contain at least one field
CButton *pButton = (CButton *)GetDlgItem(IDOK);
pButton->EnableWindow(FALSE);
}
else
{
// user specified existing table, so populate
// dialog with information from first field
//
// open the table rather than creating it
if (!openTableDef(m_pDatabase, &m_pTableDef, m_strTableName))
return TRUE;
// get the information for the first field (no error reporting)
if (getFieldInfo(m_pTableDef, &m_FI, m_nFieldIndex, FALSE))
{
// there is a first field so set controls appropriate
setTypeDependentStatesAndExisting(m_FI.m_nType, TRUE);
}
else
{
// no first field (user must have delete all of them),
// so come up initialized and updatable first time
fieldInitializer(FALSE);
setTypeDependentStatesAndExisting(m_FI.m_nType, FALSE);
}
// the first field has already been added long ago
m_bFirstFieldAdded = TRUE;
UpdateData(FALSE);
}
// set focus to name of field edit box
CEdit *pEdit = (CEdit *)GetDlgItem(IDC_NAME);
pEdit->SetFocus();
// set the range of the spin control
CSpinButtonCtrl* pOrdPosSpin =
(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ORDINAL_POSITION);
pOrdPosSpin->SetRange(0,100);
return FALSE; // return TRUE unless you set the focus to a control
}
// user selected to go to next existing field--prompt for acceptance
// since we lose the currently specified field if it is not added
void CDlgAddTable::OnNextField()
{
// get values from control -- no validity checking
m_bCheckDDV = FALSE; // turn validity checking off
UpdateData(TRUE);
m_bCheckDDV = TRUE; // turn checking back on--don't forget this!
// action depends on if this is an existing field or not
// if this is a new field see if user wants to save it
// or not--if not, then try to move to next field
if ((m_FI.m_strName != _T("")) && (!IsExistentField(m_pTableDef, m_FI.m_strName)))
if (IDYES != AfxMessageBox(_T("Current field will be ignored unless added. Continue anyway?"),
MB_YESNO))
return;
// can only move next if there is a item at the current index in the
// collection--else you keep indexing into unused parts of the index.
// So, check for existence of current indexed item and only increment
// the index if there is an item (no error reporting)
if (getFieldInfo(m_pTableDef, &m_FI, m_nFieldIndex, FALSE))
// move to next field index
m_nFieldIndex += 1;
// get the information for the next field if possible--
// last parameter indicates no failure reporting
if (getFieldInfo(m_pTableDef, &m_FI, m_nFieldIndex, FALSE))
{
// some settings are type dependent
setTypeDependentStatesAndExisting(m_FI.m_nType, TRUE);
}
else
{
// initialize field property values for new field
fieldInitializer(FALSE);
// set ordinal position to this index just for neatness
m_FI.m_nOrdinalPosition = m_nFieldIndex;
// some settings are type dependent
setTypeDependentStatesAndExisting(m_FI.m_nType, FALSE);
}
UpdateData(FALSE);
// set focus to name of field edit box
CEdit *pEdit = (CEdit *)GetDlgItem(IDC_NAME);
pEdit->SetFocus();
}
// user selected a type for the field from the type combobox
void CDlgAddTable::OnSelendokType()
{
// need to transfer values into member variables
// otherwize the UpdateData(FALSE) at the end will
// wipe out all the values the user entered.
// Do not do any validity checks
m_bCheckDDV = FALSE; // turn validity checking off
UpdateData(TRUE);
m_bCheckDDV = TRUE; // turn checking back on--don't forget this!
// once a type is selected, it is time to enable the size edit control
m_SizeControl.EnableWindow();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -