📄 addtbdlg.cpp
字号:
// now set the states that depend on the type
setTypeDependentStatesAndExisting(m_FI.m_nType, FALSE);
// update the controls with new info
UpdateData(FALSE);
}
// user can scroll in dropdown--must handle this possibility. Just pretend
// it is a selection that ended OK
void CDlgAddTable::OnCloseupType()
{
OnSelendokType();
}
// user is done adding/viewing/deleting fields and is ready to finalize
// the table structure
void CDlgAddTable::OnDone()
{
// by default, we are ready to exit the dialog
int retCode = IDYES;
// if user has entered a field name, then warn them they will lose
// it if it is not explicitly added--we don't want to do an auto-add
// since user may have entered name without meaning to add another field
//
// see if there is a field name specified
CString name;
CEdit *pEdit = (CEdit *)GetDlgItem(IDC_NAME);
pEdit->GetWindowText(name);
// if there is a name, then warn the user
if (name.GetLength() != 0)
{
// only an issue if this is not an existing field
if (!IsExistentField(m_pTableDef, name))
retCode = AfxMessageBox(_T("Current field will be ignored unless added. Continue anyway?"),
MB_YESNO);
}
// either there never was a field name specified or the user has
// chosen not to add the field
if (retCode == IDYES)
{
// done with tabledef object
delete m_pTableDef;
// end the dialog
CDialog::EndDialog(0);
}
}
// user cancelled tabledef creation process
void CDlgAddTable::OnClose()
{
// if we have already allocated a tabledef object, better
// clean it up
if (m_pTableDef != NULL)
delete m_pTableDef;
// let the base class cleanup the rest
CDialog::OnClose();
}
// user selected to move to previous existing field, prompt for acceptance since
// we lose any currently specified field unless is is added to the collection
void CDlgAddTable::OnPreviousField()
{
// can't go previous if at 0th index
if (m_nFieldIndex >= 1)
{
// 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!
// by default, move previous
int retCode = IDYES;
// if user has entered a field name, then warn them they will lose
// it if it is not explicitly added--we don't want to do an auto-add
// since user may have entered name without meaning to add another field
//
// if there is a name, then warn the user
if (m_FI.m_strName != _T(""))
{
// only an issue if this is not an existing field
if (!IsExistentField(m_pTableDef, m_FI.m_strName))
retCode = AfxMessageBox(_T("Current field will be ignored unless added. Continue anyway?"),
MB_YESNO);
}
// either there never was a field name specified or the user has
// chosen not to add the field
if (retCode == IDYES)
{
// move previous
m_nFieldIndex -= 1;
// get the information for the previous field (no error reporting)
// if there is info, display appropriate to existing field
// if no info, treat this as a new field the user can set
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);
}
// update the dialog controls with new values
UpdateData(FALSE);
}
}
}
// user has selected to delete the current field, prompt for acceptance
void CDlgAddTable::OnDeleteField()
{
// get values from control -- don't continue if failure
if (!UpdateData(TRUE))
return;
// can only delete existing fields
if (IsExistentField(m_pTableDef, m_FI.m_strName))
{
// is user sure?
if (IDYES == AfxMessageBox(_T("Delete current field?"), MB_YESNO))
{
// only react if field is deleted!
if (deleteField(m_pTableDef, m_FI.m_strName))
{
// index into collection is unchanged, so
// get the information for this field if there is one
// (no error reporting)
if (getFieldInfo(m_pTableDef, &m_FI, m_nFieldIndex, FALSE))
{
// there is a field, so set type depenedent properties
// and existing field properties of controls
setTypeDependentStatesAndExisting(m_FI.m_nType, TRUE);
}
else
{
// there is no field in collection following the
// deletion at this index, so
// set the field info to initial state
fieldInitializer(FALSE);
// clear read-only status of control
setTypeDependentStatesAndExisting(m_FI.m_nType, FALSE);
}
// update the dialog controls to erase deleted field
UpdateData(FALSE);
}
}
}
}
// control availability depends on two things--the type of the field and
// whether this is an existing field or new. Some controls only make
// sense for certain types (like autoincrement for longs only). Existing
// fields have primarily read-only properties. This function takes both
// into account when setting control states
//
// Note: since disabled is acceptable for existing field controls, you will
// not see the bExisting taken into consideration if we are disabling
// a control based on type
//
// IN: theType--the type of the current field (long, text, etc.)
// IN: bExistingField--TRUE if this is an existing field, else false
//
void CDlgAddTable::setTypeDependentStatesAndExisting(int theType, BOOL bExistingField)
{
// only longs can be auto increment
if (theType == dbLong)
m_AutoIncrFieldControl.EnableWindow(TRUE && (!bExistingField));
else
m_AutoIncrFieldControl.EnableWindow(FALSE);
// except for text, setting variability of
// field size is not an option
if (theType == dbText)
{
// the state of controls depends on if this is an existing field or new
CButton *pButton = (CButton *)GetDlgItem(IDC_FIXED_FIELD);
pButton->EnableWindow(!bExistingField);
pButton = (CButton *)GetDlgItem(IDC_VARIABLE_FIELD);
pButton->EnableWindow(!bExistingField);
}
else
{
// the controls are disabled for all but non-existing text fields
CButton *pButton = (CButton *)GetDlgItem(IDC_FIXED_FIELD);
pButton->EnableWindow(FALSE);
pButton = (CButton *)GetDlgItem(IDC_VARIABLE_FIELD);
pButton->EnableWindow(FALSE);
}
// by default, the default value depends only on field existence
m_DefaultValueControl.EnableWindow(TRUE && (!bExistingField));
// by default the validation depends only on field existence
m_ValidationTextControl.SetReadOnly(bExistingField);
m_ValidationRuleControl.SetReadOnly(bExistingField);
// In general, the selected type determines the following:
// * the size of the field (in bytes)
// * whether the size is user modifiable or not
// * what the setting for field variability is by default
switch(theType)
{
case dbBoolean:
case dbByte: m_SizeControl.SetReadOnly();
m_FI.m_lSize = 1;
// set to fixed field type
m_FI.m_lAttributes &= ~dbVariableField;
m_FI.m_lAttributes |= dbFixedField;
break;
case dbInteger: m_SizeControl.SetReadOnly();
m_FI.m_lSize = 2;
// set to fixed field type
m_FI.m_lAttributes &= ~dbVariableField;
m_FI.m_lAttributes |= dbFixedField;
break;
case dbLong:
case dbSingle: m_SizeControl.SetReadOnly();
m_FI.m_lSize = 4;
// set to fixed field type
m_FI.m_lAttributes &= ~dbVariableField;
m_FI.m_lAttributes |= dbFixedField;
break;
case dbCurrency:
case dbDate:
case dbDouble: m_SizeControl.SetReadOnly();
m_FI.m_lSize = 8;
// set to fixed field type
m_FI.m_lAttributes &= ~dbVariableField;
m_FI.m_lAttributes |= dbFixedField;
break;
case dbText: m_SizeControl.SetReadOnly(FALSE | bExistingField);
// set to variable field type
m_FI.m_lAttributes &= ~dbFixedField;
m_FI.m_lAttributes |= dbVariableField;
break;
case dbLongBinary:
m_SizeControl.SetReadOnly(FALSE | bExistingField);
// set to variable field type
m_FI.m_lAttributes &= ~dbFixedField;
m_FI.m_lAttributes |= dbVariableField;
break;
case dbMemo: m_SizeControl.SetReadOnly(FALSE | bExistingField);
// set to variable field type
m_FI.m_lAttributes &= ~dbFixedField;
m_FI.m_lAttributes |= dbVariableField;
break;
} // end of switch
// now handle setting availability for controls that are not type
// dependent
m_NameControl.SetReadOnly(bExistingField);
m_OrdinalPositionControl.SetReadOnly(bExistingField);
m_TypeControl.EnableWindow(!bExistingField);
m_RequireControl.EnableWindow(!bExistingField);
UpdateData(FALSE);
}
// user selected to add a new field to the collection
// NOTE: here is also where the tabledef is created and
// appended to the tabledef collection. The tabledef
// is created before the first field is created and appended
// after which it is appended to the tabledef collection
void CDlgAddTable::OnAddField()
{
// get values from control -- don't continue if failure
if (!UpdateData(TRUE))
return;
// don't do anything if this is an existing field (except
// say so)
if (!IsExistentField(m_pTableDef, m_FI.m_strName))
{
// if no fields added yet, then this is first so create the tabledef
if (!m_bFirstFieldAdded)
{
// try to create the tabledef, if failure, stop processing
if (!createNewTableDef(m_pDatabase, &m_pTableDef, m_strTableName))
return;
}
// try to create the field with error checking--may fail if a
// duplicate named field already exists. Note: creating a field
// also appends it to the tabledef's field collection
if (!createNewField(m_pTableDef, &m_FI))
{
// if this is the first field, then failure means we delete the
// table we just created
if (!m_bFirstFieldAdded)
deleteTable(m_pDatabase, m_strTableName);
// done
return;
}
// field created successfully, so continue doing required
// initialization
if (!m_bFirstFieldAdded)
{
// append the tabldef to the database collection of tabledefs
// this must be done after at least the first first field
// has been added
if (!appendTableDef(m_pDatabase, m_pTableDef))
{
// if append fails, then we should delete the first field
// since it is probably the culprit and we should allow
// user to set new properties
deleteField(m_pTableDef, m_FI.m_strName);
// delete the table too if since this is the first field
// that failed--else we will have a created table that is
// not appended
deleteTable(m_pDatabase, m_strTableName);
// done
return;
}
else
// now first field has been added successfully
m_bFirstFieldAdded = TRUE;
// now that first field added, can possbily be "done"
CButton *pButton = (CButton *)GetDlgItem(IDOK);
pButton->EnableWindow(TRUE);
}
// clean out all fields except ordinal position to prepare
// user to enter next field's properties
fieldInitializer(FALSE);
// manage the ordinal position -- autoincrement
// Note: it is OK for fields to have the same ordinal position--
// see the DAO docs for this property.
// also increment the index into the collection
m_FI.m_nOrdinalPosition += 1;
m_nFieldIndex += 1;
// performs visible clearing of controls that are initialized
UpdateData(FALSE);
}
else
{
AfxMessageBox(_T("Can't add field--it already exists in the TableDef."));
}
// set focus to name of field edit box
CEdit *pEdit = (CEdit *)GetDlgItem(IDC_NAME);
pEdit->SetFocus();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -