Содержание
Содержание _
1. Введение _
2. Постановка задачи _
3. Структура выходных и входных данных _
4. Описание основных классов _
5. Листинг программы _
6. Результат работы программы _
7. Заключение _
8. Литература _
1. Введение
Язык программирования служит двумсвязанным между собой целям: он дает программисту аппарат для задания действий,которые должны быть выполнены, и формирует концепции, которыми пользуетсяпрограммист, размышляя о том, что делать. Первой цели идеально отвечает язык,который настолько «близок к машине», что всеми основными машиннымиаспектами можно легко и просто оперировать достаточно очевидным дляпрограммиста образом. С таким умыслом первоначально задумывался C. Второй целиидеально отвечает язык, который настолько «близок к решаемой задаче»,чтобы концепции ее решения можно было выражать прямо и коротко. С таким умысломпредварительно задумывались средства, добавленные к C для создания C++.
Связьмежду языком, на котором мы думаем/программируем, и задачами и решениями,которые мы можем представлять в своем воображении, очень близка. По этойпричине ограничивать свойства языка только целями исключения ошибокпрограммиста в лучшем случае опасно. Язык предоставляет программисту наборконцептуальных инструментов; если они не отвечают задаче, то их простоигнорируют. Например, серьезные ограничения концепции указателя заставляютпрограммиста применять вектора и целую арифметику, чтобы реализовать структуры,указатели и т.п. Хорошее проектирование и отсутствие ошибок не может гарантироватьсячисто за счет языковых средств. Система типов должна быть особенно полезна внетривиальных задачах. Действительно, концепция классов в C++ показала себямощным концептуальным средством.
2. Постановка задачи
Написатьинформационную систему по учёту автобусных рейсов. Информационная системадолжна позволять:
· Вестиучет автотранспорта (преимущественно автобусного). В свою очередь следует:
· учитыватьвремя отправления каждого автобуса;
· учитыватьтипы автобусов;
· привязыватьавтотранспорт (автобусы) к рейсам;
· Вестиучет рейсов. В свою очередь следует:
· учитыватьпути, составляющие рейс;
· Вестиучет остановочных пунктов
Система должна обеспечить выполнениеэтих возможностей путем реализации алгоритмов удаления, редактирования идобавления новой информации.
При этом при удалении следует обеспечитьцелостность данных и выводить предупреждение пользователю в тех случаях, когдаудаление информации невозможно в результате наличия связей с другимисущностями.
При добавлении необходимо разработатьмеханизм, реализующий проверку на уникальность, который в случаях, когданеобходимо соблюдать уникальность, будет предупреждать пользователя онедопустимости таких действий, а также будет препятствовать добавлению такойинформации. Также необходимо обеспечить проверку на пустоту и ограничиватьдействия пользователя в тех случаях, когда он пытается ввести пустые значения.
При редактировании следует аналогичнымобразом проверять редактируемые значения проверять на уникальность.
Для реализации поставленной задачииспользовать VisualStudioC++версии не ниже 6.0. В частности применить библиотеку MicrosoftFoundationClasses (MFC), представляющую интерфейс ODBC для доступа к базамданных и другие возможности.
3. Структура выходных и входных данных
Программа использует СУБД Access. В ней будетразработана основная база (bus.mdb). Разрабатываемаяпрограмма будет взаимодействовать с базой путем интерфейса MFC ODBC, что позволяет размещать данные какнепосредственно на локальном компьютере, так и на любой машине в сети,предоставляющий открытый доступ к такого рода ресурсам.
База данных содержит в себе необходимоеи достаточное количество нормализованных сущностей — таблиц:
· Bus — таблица, размещающая информацию об автобусах. Содержиттри поля: первое — это уникальный идентификатор автобуса, однозначноопределяющий его во всем множестве других автобусов, второе — тип автобуса,третье — уникальный идентификатор рейса.
Название
тип
bus_ID
счетчик
busType_ID
длинноецелое
race_ID
длинное целое
· Path — таблица путей. Она предназначена для связиразрозненных остановочных пунктов в элементарный неделимый маршрут из одногоостановочного пункта в другой. При этом направление не имеет значения. Таблицасостоит из 4 полей: первое — это уникальный идентификатор пути,однозначно определяющий его во всем множестве других путей, второе и третье — уникальныйидентификатор остановочного пункта, четвертое — расстояние междуостановочными пунктами, выраженное во времени прохождения их из первого вовторой либо из второго в первый.
Название
тип
path_ID
счетчик
start/end station_ID
длинное целое
end/start station_ID
длинное целое
time
длинное целое
· Race — таблица, размещающая информацию о рейсах. Имеет дваполя: первое — это уникальныйидентификатор рейса, однозначно определяющий его во всем множестве другихрейсов, второе — описание рейса.
Название
тип
race_ID
счетчик
description
поле memo
· Raceitems — таблица, организующая связь“многие ко многим” между таблицами Race и Path.Содержит два поля: первое — уникальный идентификатор рейса, второе — уникальныйидентификатор пути.
Название
тип
race_ID
счетчик
path_ID
полеmemo
· Station — таблица, размещающая информацию об остановочныхпунктах автобусов. Имеет два поля — это уникальный идентификаторостановочного пункта, однозначно определяющий его во всем множестве другихостановочных пунктах, и поле с его названием.
Название
тип
station_ID
длинное целое
name
длинное целое
· Time — таблица, размещающая информацию овременах отправлений автобусов[1].Автобусы, привязанные к одному рейсу, в течении определенного периода могутнеоднократно отправляться в рейс в разные часы, что и отражается структуройданной таблицы. Таблица состоит из 3 полей: первое — это уникальныйидентификатор времени, однозначно определяющий его во всем множестве другихвремен отправлений, второе поле — это идентификатор автобуса, свеянный стаблицей Bus (посколькутаблица Bus связанна с Time связью “один ко многим”,в Time можетприсутствовать несколько идентификаторов одного автобуса), третье поле — времяотправления.
Название
тип
time_ID
счетчик
bus_ID
длинное целое
time
длинное целое
· Type — таблица, размещающая информацию о типах автобусов(классов). Имеет два поля — это уникальный идентификатор типа,однозначно определяющий его во всем множестве других типов, и поле с названием типа.
Название
тип
busType_ID
счетчик
name
поле memo
Схема данных представлена в таблице 1.Она отражает сущности, а также связи и их типы.
Таблица 1 — схема данных
4. Описание основных классов
На рисунке 1 изображена диаграммаклассов. Она отражает все классы проекта. Практически все классы являютсяпользовательскими. Они переопределены от встроенных классов путем однократногои множественного наследования.
Класс CMyDBVariant представляет собой объект, способный хранить различныетипы данных. Он незаменим для работы с базой данный. Его прародителем сталкласс CDBVariant.Поскольку возможностей базового класса оказалось недостаточно, пришлось егопереопределить, вводя дополнительные переменные m_cstring для передачи строк типа Cstring и m_time для передачи времени типа CTime.
CMyDBRecordset – новый класс от CDBRecordset. Более гибок,нежели стандартный класс. Позволяет легко, без внедрения дополнительныхпереопределений, на месте, быстро создать представление сущности. В него добавлены:Count – член класса,хранящий количество записей (это сделано в силу того, что метод GetCount не возвращаетреального количества), DefineRealCount– метод, определяющий Count.Также в этот класс входит fieldnamesи fieldValues,позволяющий не передавать непосредственно переменные в метод DoFieldExchange а держать их прямо вклассе в качестве его членов, что значительно упрощает код и способ обращения кполям представления.
Полное описание классов находиться влистинге программы.
Рисунок 1 — Диаграмма классов
5. Листинг программы
CAboutForm.cpp
#include «stdafx.h»
#include "../main.h"
#include «CAboutForm.h»
CAboutForm::CAboutForm(CWnd*pParent):CDialog(CAboutForm::IDD,pParent){
//{{AFX_DATA_INIT(CAboutForm)
//}}AFX_DATA_INIT
}
void CAboutForm::DoDataExchange(CDataExchange*pDX){
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutForm)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutForm, CDialog)
//{{AFX_MSG_MAP(CAboutForm)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CAboutForm.h
#if!defined(AFX_CABOUTFORM_H__09D6634D_16A6_44E9_849C_AD1B2E71646D__INCLUDED_)
#defineAFX_CABOUTFORM_H__09D6634D_16A6_44E9_849C_AD1B2E71646D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CAboutForm.h: header file
//
/////////////////////////////////////////////////////////////////////////////
// CAboutForm dialog
class CAboutForm: public CDialog
{
// Construction
public:
CAboutForm(CWnd*pParent = NULL); // standardconstructor
// Dialog Data
//{{AFX_DATA(CAboutForm)
enum {IDD = AboutForm };
//NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
//ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutForm)
protected:
virtualvoid DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//Generated message map functions
//{{AFX_MSG(CAboutForm)
//NOTE: the ClassWizard will add member functions here
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additionaldeclarations immediately before the previous line.
#endif //!defined(AFX_CABOUTFORM_H__09D6634D_16A6_44E9_849C_AD1B2E71646D__INCLUDED_)
CBusForm.cpp
#include «stdafx.h»
#include "../main.h"
#include «CBusForm.h»
#include «CTypeForm.h»
#include "../ExLibrary/CMyRecordset.h"
char*toString(int value,int radix=10);
CStringIsEmpty_CEdit(CEdit* ctrl);
voidsqlFilter(CString* value);
boolisUnique(CString sql,CString fields);
boolisRelate(CString sql,CString fields);
voidLoad_List(CString sql,CString fields,CListBox* ctrl,voidclearIdxFunc(void),void initIdxFunc(int),void setIdxFunc(int,int));
voidLoad_List(CString sql,CString fields,CComboBox* ctrl,voidclearIdxFunc(void),void initIdxFunc(int),void setIdxFunc(int,int));
CBusForm::CBusForm(CWnd*pParent):CDialog(CBusForm::IDD, pParent){
//{{AFX_DATA_INIT(CBusForm)
//}}AFX_DATA_INIT
}
void CBusForm::DoDataExchange(CDataExchange* pDX){
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBusForm)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CBusForm, CDialog)
//{{AFX_MSG_MAP(CBusForm)
ON_BN_CLICKED(Button_showBusType,showBusType_onClick)
ON_BN_CLICKED(Button_DeleteBus,DeleteBus_onClick)
ON_BN_CLICKED(Button_EditBus,EditBus_onClick)
ON_BN_CLICKED(Button_AddBus,AddBus_onClick)
ON_BN_CLICKED(IDOK,OK_onClick)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/* ============================
=====User realization =====
============================ */
CListBox*pList_Bus;
CComboBox*pComboBox_BusType;
CComboBox*pComboBox_RaceInBus;
externCDatabase DB;
externCMyRecordset* RS;
/* ============================
======indexes & Funcn =====
============================ */
int*pList_Bus_indexes;
int*pLBiLen;
void ClearIndexes_pList_Bus_indexes(){
if(pList_Bus_indexes){
delete[]pList_Bus_indexes,pLBiLen;
pList_Bus_indexes=pLBiLen=NULL;}}
void InitIndexes_pList_Bus_indexes(int len){
pList_Bus_indexes=newint[len];
*(pLBiLen=new int)=len;}
void SetIndexes_pList_Bus_indexes(int idx,intvalue){
pList_Bus_indexes[idx]=value;}
int*pComboBox_BusType_indexes;
int*pCBBTiLen;
void ClearIndexes_pComboBox_BusType_indexes(){
if(pComboBox_BusType_indexes){
delete[]pComboBox_BusType_indexes,pCBBTiLen;
pComboBox_BusType_indexes=pCBBTiLen=NULL;}}
void InitIndexes_pComboBox_BusType_indexes(intlen){
pComboBox_BusType_indexes=newint[len];
*(pCBBTiLen=new int)=len;}
void SetIndexes_pComboBox_BusType_indexes(intidx,int value){
pComboBox_BusType_indexes[idx]=value;}
int*pComboBox_RaceInBus_indexes;
int*pCBRIBiLen;
void ClearIndexes_pComboBox_RaceInBus_indexes(){
if(pComboBox_RaceInBus_indexes){
delete[]pComboBox_RaceInBus_indexes,pCBRIBiLen;
pComboBox_RaceInBus_indexes=pCBRIBiLen=NULL;}}
void InitIndexes_pComboBox_RaceInBus_indexes(intlen){
pComboBox_RaceInBus_indexes=newint[len];
*(pCBRIBiLen=new int)=len;}
void SetIndexes_pComboBox_RaceInBus_indexes(intidx,int value){
pComboBox_RaceInBus_indexes[idx]=value;}
/* ============================
======… =====
============================ */
void Load_List_Bus(){
Load_List(«SELECTBus.bus_ID,Trim(Str(Bus.bus_ID))+') '+Race.description+' — '+Type.name FROMType INNER JOIN (Race INNER JOIN Bus ON Race.race_ID = Bus.race_ID) ONType.busType_ID = Bus.busType_ID ORDER BY Trim(Str(Bus.bus_ID))+')'+Race.description+' — '+Type.name»,"[bus_ID]&,[Expr1001]$",
pList_Bus,
ClearIndexes_pList_Bus_indexes,
InitIndexes_pList_Bus_indexes,
SetIndexes_pList_Bus_indexes);}
void Load_ComboBox_BusType(){
Load_List(«SELECTType.* FROM Type»,"[busType_ID]&,[name]$",
pComboBox_BusType,
ClearIndexes_pComboBox_BusType_indexes,
InitIndexes_pComboBox_BusType_indexes,
SetIndexes_pComboBox_BusType_indexes);}
void Load_ComboBox_RaceInBus(){
Load_List(«SELECTRace.race_ID,Trim(Str(Race.race_ID))+') '+Race.description FROMRace»,"[race_ID]&,[Expr1001]$",
pComboBox_RaceInBus,
ClearIndexes_pComboBox_RaceInBus_indexes,
InitIndexes_pComboBox_RaceInBus_indexes,
SetIndexes_pComboBox_RaceInBus_indexes);}
bool IsSelected_BusForm(){
if(pComboBox_BusType->GetCurSel()==-1||
pComboBox_RaceInBus->GetCurSel()==-1){
AfxMessageBox(«Nothingselected!»);
return0;}
return1;}
bool IsSelected_List_Bus(){
if(pList_Bus->GetCurSel()==-1){
AfxMessageBox(«Nothingselected!»);
return0;}
return1;}
void setCurSel_List_Bus(int fictionIndex){
for(inti=0;i
if(pList_Bus_indexes[i]==fictionIndex){
pList_Bus->SetCurSel(i);
return;}}
/* ============================
======Add Edit Remove =====
============================ */
void CBusForm::AddBus_onClick(){
if(!IsSelected_BusForm())return;
//>>>
longbysType=pComboBox_BusType_indexes[pComboBox_BusType->GetCurSel()];
longraceInBus=pComboBox_RaceInBus_indexes[pComboBox_RaceInBus->GetCurSel()];
//>>>
CStringinsertSql=«INSERT INTO Bus (busType_ID,race_ID) Values($$1,$$2)»;
insertSql.Replace("$$1",toString(bysType));
insertSql.Replace("$$2",toString(raceInBus));
DB.ExecuteSQL(insertSql);
Load_List_Bus();
// :::
RS=newCMyRecordset(&DB);
CStringgetNewIdSql=«SELECT TOP 1 Bus.bus_ID FROM Bus WHERE Bus.busType_ID=$$1 ANDBus.race_ID=$$2 ORDER BY Bus.bus_ID DESC»;
getNewIdSql.Replace("$$1",toString(bysType));
getNewIdSql.Replace("$$2",toString(raceInBus));
RS->Open(getNewIdSql,"[bus_ID]&");
RS->MoveFirst();
longnewId=RS->fieldsValue[0].m_lVal;
RS->Close();
deleteRS;
setCurSel_List_Bus(newId);}
void CBusForm::EditBus_onClick(){
if(!IsSelected_List_Bus())return;
if(!IsSelected_BusForm())return;
//>>>
longcID=pList_Bus_indexes[pList_Bus->GetCurSel()];
longbysType=pComboBox_BusType_indexes[pComboBox_BusType->GetCurSel()];
longraceInBus=pComboBox_RaceInBus_indexes[pComboBox_RaceInBus->GetCurSel()];
// >>>
CStringupdateSql=«UPDATE Bus SET Bus.busType_ID=$$1,Bus.race_ID=$$2 WHEREBus.bus_ID=$$3»;
updateSql.Replace("$$1",toString(bysType));
updateSql.Replace("$$2",toString(raceInBus));
updateSql.Replace("$$3",toString(cID));
DB.ExecuteSQL(updateSql);
Load_List_Bus();
setCurSel_List_Bus(cID);}
void CBusForm::DeleteBus_onClick(){
if(!IsSelected_List_Bus())return;
//>>>
longcID=pList_Bus_indexes[pList_Bus->GetCurSel()];
//>>>
CStringdeleteSql=«DELETE Bus.*, Bus.bus_ID FROM Bus WHERE Bus.bus_ID=$$$»;
deleteSql.Replace("$$$",toString(cID));
DB.ExecuteSQL(deleteSql);
longoldSel=pList_Bus->GetCurSel();
Load_List_Bus();
// :::
pList_Bus->SetCurSel(oldSel>pList_Bus->GetCount()-1?pList_Bus->GetCount()-1:oldSel);}
/* ============================
===OnInitDialog OnClose ===
============================ */
voidCBusForm::OK_onClick(){SendMessage(WM_CLOSE,0,0);}
BOOLCBusForm::OnInitDialog(){CDialog::OnInitDialog();
//>>>
pList_Bus=(CListBox*)GetDlgItem(List_Bus);
pComboBox_BusType=(CComboBox*)GetDlgItem(ComboBox_BusType);
pComboBox_RaceInBus=(CComboBox*)GetDlgItem(ComboBox_RaceInBus);
//>>>
Load_List_Bus();
Load_ComboBox_BusType();
Load_ComboBox_RaceInBus();
//>>>
returnTRUE;}
void CBusForm::OnClose(){CDialog::OnClose();
ClearIndexes_pList_Bus_indexes();
ClearIndexes_pComboBox_BusType_indexes();
ClearIndexes_pComboBox_RaceInBus_indexes();}
void CBusForm::showBusType_onClick(){
CTypeFormtypeForm;
typeForm.DoModal();
Load_ComboBox_BusType();}
CBusForm.h
#if !defined(AFX_CBUSFORM_H__15C9D50F_B1DF_4489_9E98_8BAF03968B1A__INCLUDED_)
#defineAFX_CBUSFORM_H__15C9D50F_B1DF_4489_9E98_8BAF03968B1A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CBusForm.h: header file
//
/////////////////////////////////////////////////////////////////////////////
// CBusForm dialog
class CBusForm: public CDialog
{
// Construction
public:
CBusForm(CWnd*pParent = NULL); // standardconstructor
// Dialog Data
//{{AFX_DATA(CBusForm)
enum {IDD = BusForm };
//NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
//ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBusForm)
protected:
virtualvoid DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//Generated message map functions
//{{AFX_MSG(CBusForm)
afx_msgvoid showBusType_onClick();
afx_msgvoid DeleteBus_onClick();
afx_msgvoid EditBus_onClick();
afx_msgvoid AddBus_onClick();
afx_msgvoid OK_onClick();
virtualBOOL OnInitDialog();
afx_msgvoid OnClose();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additionaldeclarations immediately before the previous line.
#endif // !defined(AFX_CBUSFORM_H__15C9D50F_B1DF_4489_9E98_8BAF03968B1A__INCLUDED_)
CMainForm.cpp
#include «stdafx.h»
#include "../main.h"
#include «CMainForm.h»
#include «CAboutForm.h»
#include «CTimeForm.h»
#include «CStationForm.h»
#include «CPathForm.h»
#include «CRaceForm.h»
#include «CBusForm.h»
#include "../ExLibrary/CMyRecordset.h"
CMainForm::CMainForm(CWnd*pParent):CDialog(CMainForm::IDD, pParent){
//{{AFX_DATA_INIT(CMainForm)
//}}AFX_DATA_INIT
}
void CMainForm::DoDataExchange(CDataExchange*pDX){
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMainForm)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMainForm, CDialog)
//{{AFX_MSG_MAP(CMainForm)
ON_BN_CLICKED(Button_showTime,showTime_onClick)
ON_BN_CLICKED(Button_showStation,showStation_onClick)
ON_BN_CLICKED(Button_showPath,showPath_onClick)
ON_BN_CLICKED(Button_showAbout,showAbout_onClick)
ON_BN_CLICKED(Button_showRace,showRace_onClick)
ON_BN_CLICKED(Button_showBus,showBus_onClick)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/* ============================
=====User realization =====
============================ */
void CMainForm::showTime_onClick(){
CTimeFormtimeForm;
timeForm.DoModal();}
void CMainForm::showStation_onClick(){
CStationFormstationForm;
stationForm.DoModal();}
void CMainForm::showPath_onClick(){
CPathFormpathForm;
pathForm.DoModal();}
void CMainForm::showAbout_onClick(){
CAboutFormaboutForm;
aboutForm.DoModal();}
void CMainForm::showRace_onClick(){
CRaceFormraceForm;
raceForm.DoModal();}
void CMainForm::showBus_onClick(){
CBusFormbusForm;
busForm.DoModal();}
BOOL CMainForm::OnInitDialog(){
CDialog::OnInitDialog();
//>>>
externCDatabase DB;
try{
DB.Open(«ODBC;DSN=»);}
catch(CDBException*pError){
CStringstr;
str+=pError->m_strStateNativeOrigin;str+=«n»; str+=pError->m_strError;
AfxMessageBox(str);
pError->Delete();};
//>>>
returnTRUE;}
CMainForm.h
#if!defined(AFX_CMAINFORM_H__43C7FDB1_2162_4824_BBAC_EAF31944B6FB__INCLUDED_)
#defineAFX_CMAINFORM_H__43C7FDB1_2162_4824_BBAC_EAF31944B6FB__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CMainForm.h: header file
//
/////////////////////////////////////////////////////////////////////////////
// CMainForm dialog
class CMainForm: public CDialog
{
// Construction
public:
CMainForm(CWnd*pParent = NULL); // standardconstructor
// Dialog Data
//{{AFX_DATA(CMainForm)
enum {IDD = MainForm };
//NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
//ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainForm)
protected:
virtualvoid DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//Generated message map functions
//{{AFX_MSG(CMainForm)
afx_msgvoid showTime_onClick();
afx_msgvoid showStation_onClick();
afx_msgvoid showPath_onClick();
afx_msgvoid showAbout_onClick();
afx_msgvoid showRace_onClick();
afx_msgvoid showBus_onClick();
virtualBOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additionaldeclarations immediately before the previous line.
#endif //!defined(AFX_CMAINFORM_H__43C7FDB1_2162_4824_BBAC_EAF31944B6FB__INCLUDED_)
CPathForm.cpp
#include «stdafx.h»
#include "../main.h"
#include «CPathForm.h»
#include "../ExLibrary/CMyRecordset.h"
char*toString(int value,int radix=10);
CStringIsEmpty_CEdit(CEdit* ctrl);
voidsqlFilter(CString* value);
boolisUnique(CString sql,CString fields);
boolisRelate(CString sql,CString fields);
CPathForm::CPathForm(CWnd*pParent):CDialog(CPathForm::IDD,pParent){
//{{AFX_DATA_INIT(CPathForm)
//}}AFX_DATA_INIT
}
void CPathForm::DoDataExchange(CDataExchange*pDX){
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPathForm)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPathForm, CDialog)
//{{AFX_MSG_MAP(CPathForm)
ON_BN_CLICKED(Button_AddPath,AddPath_onClick)
ON_BN_CLICKED(Button_EditPath,EditPath_onClick)
ON_BN_CLICKED(Button_DeletePath,DeletePath_onClick)
ON_BN_CLICKED(IDOK,OK_onClick)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/* ============================
=====User realization =====
============================ */
CListBox*pList_Pathes;
CComboBox*pComboBox_Station1;
CComboBox*pComboBox_Station2;
CEdit*pEdit_pathTime;
externCDatabase DB;
externCMyRecordset* RS;
/* ============================
======indexes & Funcn =====
============================ */
int*pList_Pathes_indexes;
int*pLPiLen;
void ClearIndexes_pList_Pathes_indexes(){
if(pList_Pathes_indexes){
delete[]pList_Pathes_indexes,pLPiLen;
pList_Pathes_indexes=pLPiLen=NULL;}}
void InitIndexes_pList_Pathes_indexes(int len){
pList_Pathes_indexes=newint[len];
*(pLPiLen=new int)=len;}
int*pComboBox_Stations_indexes;
int*pCBSiLen;
void ClearIndexes_pComboBox_Stations_indexes(){
if(pComboBox_Stations_indexes){
delete[]pComboBox_Stations_indexes,pCBSiLen;
pComboBox_Stations_indexes=pCBSiLen=NULL;}}
void InitIndexes_pComboBox_Stations_indexes(intlen){
pComboBox_Stations_indexes=newint[len];
*(pCBSiLen=new int)=len;}
/* ============================
======… =====
============================ */
void Load_ComboBox_Stations(){
pComboBox_Station1->ResetContent();
pComboBox_Station2->ResetContent();
RS=newCMyRecordset(&DB);
RS->Open(«SELECTStation.* FROM Station»,"[station_ID]&,[name]$");
RS->DefineRealCount();
ClearIndexes_pComboBox_Stations_indexes();
if(RS->Count){
InitIndexes_pComboBox_Stations_indexes(RS->Count);
for(inti=0;iCount;i++){
pComboBox_Stations_indexes[i]=RS->fieldsValue[0].m_lVal;
pComboBox_Station1->InsertString(i,RS->fieldsValue[1].m_cstring);
pComboBox_Station2->InsertString(i,RS->fieldsValue[1].m_cstring);
RS->MoveNext();}}
RS->Close();
deleteRS;}
void Load_List_Pathes(){
pList_Pathes->ResetContent();
RS=newCMyRecordset(&DB);
RS->Open(«SELECTPath.path_ID, Station_1.name+' '+Station_2.name+' — ('+Trim(Str(Path.time))+' min)' FROM Station AS Station_2 INNER JOIN (Station ASStation_1 INNER JOIN Path ON Station_1.station_ID = Path.[start/endstation_ID]) ON Station_2.station_ID = Path.[end/start station_ID] ORDER BYStation_1.name,Station_2.name,Path.time»,"[path_ID]&,[Expr1001]$");
RS->DefineRealCount();
ClearIndexes_pList_Pathes_indexes();
if(RS->Count){
InitIndexes_pList_Pathes_indexes(RS->Count);
for(inti=0;iCount;i++){
pList_Pathes_indexes[i]=RS->fieldsValue[0].m_lVal;
pList_Pathes->InsertString(i,RS->fieldsValue[1].m_cstring);
RS->MoveNext();}}
RS->Close();
deleteRS;}
bool IsSelected_PathStations(){
if(pComboBox_Station1->GetCurSel()==-1||
pComboBox_Station2->GetCurSel()==-1){
AfxMessageBox(«Nothingselected!»);
return0;}
return1;}
bool IsSelected_List_Pathes(){
if(pList_Pathes->GetCurSel()==-1){
AfxMessageBox(«Nothingselected!»);