Visual C++. Лабораторная работа № 4.
Графический интерфейс с использованием списков, комбинированных полей. Решение
задач, использующих изучаемые элементы графического интерфейса, массивы и
структуры данных.
- Цель работы:
- Научиться пользоваться списками и комбинированными полями, а также
использовать структуры и массивы языка VC++. Получить практические навыки по
использованию различных элементов графического интерфейса и операторов языка VC++.
1. Создайте приложение с помощью MFС AppWizard (exe), с диалоговым окном в
качестве главного. Решить на основе данного приложения задачу из лабораторной
работы №3 (В гараже имеется несколько различных автомобилей (например: Ваз,
Газель, Газ-66, Мерседес), каждый автомобиль имеет свой расход топлива на 100 км
пути, а также свою стоимость топлива). Программа должна вычислять стоимость
поездки для заданной машины. Использовать списки и комбинированные поля. Для
хранения данных использовать массивы или структуру данных
2. Усовершенствовать полученную в первом пункте программу, добавив режим
заполнения данных для каждого автомобиля. При создании программы иметь в виду,
что количество автомобилей заранее не известно, заполнять список марок автомобилей
в ходе выполнения программы. Предусмотреть возможность удаления марок авто из
списка
3. Усовершенствовать полученную программу добавить грузоподъемность
автомобилей, и возможность указывать вес перевозимого груза. Программа должна
рассчитать оптимальный вариант по стоимости перевозки груза
4. Усовершенствовать полученную программу. Программа должна выполнять расчет и
выводить результаты и исходные данные по щелчку на элемент списка или
комбинированного поля
Не будем тратить время и выполним все задания в одной программе.
Создаем редактор (EditBox) и связываем с ним переменную m_edAdd типа CString.
Создаем список ListBox, с которым связываем переменную m_lbGarage. Добавляя
переменную для списка в поле Category нужно выбрать значение Control. Создадим
еще один список и свяжем его с переменной m_lbResult. В этот список будем заносить
результаты вычислений. Создадим также кнопки ДОБАВИТЬ и УДАЛИТЬ, с помощью которых
будем добавлять/удалять элементы, и кнопку ЗАПОМНИТЬ, с помощью которой будем
записывать данные в массивы.
На вкладке ClassView раскрываем Clab_04_1Dlg и дважды щелкаем по OnInitDialog().
Переходим в начало файла и после директивы #endif объявляем структуру и переменные:
struct Garage
{
float Litres; //Расход топлива
float Price; //Цена одного литра
float Way; //Расстояние
int Tonnage; //Грузоподъемность
int Weight; //Вес груза
};
Garage car[10]; //Объявить массив
float Result; //Объявить переменную
int NumCars; //Количество автомобилей в списке
Следует обратить внимание на точку с запятой после последней фигурной скобки.
При объявлении структур и классов она обязательна (в отличие от объявления функций).
Затем снова щелкаем дважды по OnInitDialog() и в тело функции CLab_04_1Dlg::OnInitDialog()
добавляем следующий код:
CDialog::OnInitDialog(); //Это добавлять не надо (уже есть)
//---Добавим в список автомобили--------------------------------
m_lbGarage.AddString("ВАЗ");
m_lbGarage.AddString("Газель");
m_lbGarage.AddString("ГАЗ-66");
m_lbGarage.AddString("Мерседес");
//---Заполняем массив данных: ВАЗ-------------------------------
car[0].Litres = 8.5;
car[0].Price = 15;
car[0].Way = 100;
car[0].Tonnage = 400;
car[0].Weight = 500;
//---Газель-----------------------------------------------------
car[1].Litres = 15;
car[1].Price = 12;
car[1].Way = 100;
car[1].Tonnage = 1500;
car[1].Weight = 500;
//---ГАЗ-66-----------------------------------------------------
car[2].Litres = 30;
car[2].Price = 10;
car[2].Way = 100;
car[2].Tonnage = 3500;
car[2].Weight = 500;
//---Мерседес---------------------------------------------------
car[3].Litres = 10;
car[3].Price = 17;
car[3].Way = 100;
car[3].Tonnage = 500;
car[3].Weight = 500;
NumCars = 4; //У нас пока четыре автомобиля
m_lbGarage.SetCurSel(0); //Выбрать 1-й элемент списка (ВАЗ)
//---Вывести данные о ВАЗе в редакторы--------------------------
m_edLitres = car[0].Litres;
m_edPrice = car[0].Price;
m_edWay = car[0].Way;
m_edTonnage = car[0].Tonnage;
m_edWeight = car[0].Weight;
m_edNum = 2;
UpdateData(0);
Result = (m_edWay/100)*m_edLitres*m_edPrice*m_edNum;
CString s; //Сформировать объект класса CString
s.Format("%0.2f", Result); //Преобразовать число в строку
m_lbResult.AddString(s);
m_lbResult.AddString("?");
m_lbResult.AddString("?");
m_lbResult.AddString("?");
Здесь мы добавили четыре автомобиля в список и записали информацию о них в массив
car. Затем выделили первый элемент списка и вывели соответствующие данные в
редакторы, которые били предварительно созданы аналогично предыдущей задаче.
Далее вычислили стоимость поездки для ВАЗа и заполнили второй список.
Вычисление результата будем производить непосредственно в обработчике события,
которое соответствует щелчку по списку автомобилей. Выбираем событие
LBN_SELCHANGE и пишем там:
void CLab_04_1Dlg::OnGarage()
{
int x = m_lbGarage.GetCurSel(); //Получить позицию в списке
m_edLitres = car[x].Litres;
m_edPrice = car[x].Price;
m_edWay = car[x].Way;
m_edTonnage = car[x].Tonnage;
m_edWeight = car[x].Weight;
float z; //Объявить переменную
if (m_edTonnage > 0) //Если грузоподъемность больше нуля
{
//---Вычислить кол-во поездок-----------------------------------
m_edNum = int(m_edWeight / m_edTonnage);
z = float(m_edWeight) / float(m_edTonnage);
if (m_edNum < z) m_edNum = m_edNum++;
}
else m_edNum = 1;
Result = (m_edWay/100)*m_edLitres*m_edPrice*m_edNum;
CString s; //Сформировать объект класса CString
s.Format("%0.2f", Result); //Преобразовать число в строку
m_lbResult.DeleteString(x); //Удалить строку из списка
m_lbResult.InsertString(x, s); //Вставить в сп. стр. с результатом
m_lbResult.SetCurSel(x); //Выделить строку
UpdateData(0);
}
Теперь по щелчку на списке программа будет вычислять стоимость поездки для
выбранного автомобиля и вставлять результат во второй список в соответствующую
позицию.
Далее добавим обработчик для кнопки ДОБАВИТЬ:
void CLab_04_1Dlg::OnAdd()
{
UpdateData(1); //Получить данные
if (m_edAdd != "" && NumCars < 10)
{
m_lbGarage.AddString(m_edAdd); //Добавить строку в список
car[NumCars].Litres = m_edLitres;
car[NumCars].Price = m_edPrice;
car[NumCars].Way = m_edWay;
car[NumCars].Tonnage = m_edTonnage;
car[NumCars].Weight = m_edWeight;
float z; //Объявить переменную
if (m_edTonnage > 0) //Если грузоподъемность больше нуля
{
//---Вычислить кол-во поездок-----------------------------------
m_edNum = int(m_edWeight / m_edTonnage);
z = float(m_edWeight) / float(m_edTonnage);
if (m_edNum < z) m_edNum = m_edNum++;
}
else m_edNum = 1;
car[NumCars].Num = m_edNum;
Result = (m_edWay/100)*m_edLitres*m_edPrice*m_edNum;
CString s; //Сформировать объект класса CString
s.Format("%0.2f", Result); //Преобразовать число в строку
m_lbResult.AddString(s); //Добавить строку во 2-й список
m_lbGarage.SetCurSel(NumCars); //Выделить строку
m_lbResult.SetCurSel(NumCars); //Выделить строку
NumCars++; //Увеличить кол-во автомобилей в списке
UpdateData(0);
}
}
А теперь для кнопки УДАЛИТЬ:
void CLab_04_1Dlg::OnDel()
{
Garage Mas[10]; //Объявить массив для временного хранения данных
int x = m_lbGarage.GetCurSel(); //Получить поз. курсора в списке
for (int i = 0; i < NumCars; i++) Mas[i] = car[i];
if (NumCars > 0) NumCars--; //Уменьшить кол-во автомобилей
for (i = 0; i < NumCars; i++) //Удалить соотв. запись из
if (i < x) car[i] = Mas[i]; //массива данных
else car[i] = Mas[i + 1];
m_lbGarage.DeleteString(x); //Удалить соотв.
m_lbResult.DeleteString(x); //строки из списков
if (NumCars > 0) //Если в списке остались строки
{
m_lbGarage.SetCurSel(NumCars - 1); //Установить курсор на
m_lbResult.SetCurSel(NumCars - 1); //последнюю строку
CLab_04_1Dlg::OnGarage(); //Обновить данные на экране
};
}
Добавим два флажка: УСТАНОВИТЬ ВЕС ГРУЗА ДЛЯ ВСЕХ (m_cbWeight) и УСТАНОВИТЬ
РАССТОЯНИЕ ДЛЯ ВСЕХ (m_cbWay). Если какой-либо из этих флажков установлен, то
при записи данных соответственно вес груза или расстояние будут установлены
одинаковыми для всех автомобилей. Добавим обработчик для кнопки ЗАПОМНИТЬ:
void CLab_04_1Dlg::OnSave()
{
int x = m_lbGarage.GetCurSel(); //Получить поз. курсора в сп.
UpdateData(1); //Получить данные
car[x].Litres = m_edLitres;
car[x].Price = m_edPrice;
car[x].Tonnage = m_edTonnage;
if (m_cbWay == 0) car[x].Way = m_edWay;
else
for (int i = 0; i < NumCars; i++) car[i].Way = m_edWay;
if (m_cbWeight == 0) car[x].Weight = m_edWeight;
else
for (int i = 0; i < NumCars; i++) car[i].Weight = m_edWeight;
for (int i = 0; i < NumCars; i++)
{
m_lbGarage.SetCurSel(i); //Установить поз. курсора в сп.
CLab_04_1Dlg::OnGarage(); //Обновить списки и выч. кол. поездок
UpdateData(0); //Обновить данные
}
m_lbGarage.SetCurSel(x); //Вернуться к текущей поз. курсора
CLab_04_1Dlg::OnGarage(); //Обновить списки и выч. кол. поездок
}
Здесь мы записываем данные в массивы, затем заново производим все вычисления и
обновляем экран.
Добавим кнопку ОПТИМАЛЬНЫЙ ВАРИАНТ. В обработчике будет код:
void CLab_04_1Dlg::OnOptimum()
{
for (int i = 0; i < NumCars; i++)
{
m_lbGarage.SetCurSel(i); //Установить поз. курсора в сп.
CLab_04_1Dlg::OnGarage(); //Обновить списки и выч. кол. поездок
UpdateData(0); //Обновить данные
}
if (NumCars > 0)
{
CString st;
m_lbResult.GetText(0, st); //Получить первый элемент списка
Result = atof(st); //и преобразовать его в число
int j = 0;
float n;
for (i = 1; i < NumCars; i++) //Найти наименьшую стоимость
{
m_lbResult.GetText(i, st); //Получить элемент списка
n = atof(st); //и преобразовать его в число
if (n < Result) //Если он меньше полученного ранее
{
Result = n;
j = i;
}
}
m_lbGarage.GetText(j, st); //Получить авт-ль, соотв. наим. стоим.
st = "Оптимальный вариант - автомобиль " + st;
AfxMessageBox(st); //Вывести сообщение
}
}
Здесь мы находим наименьшее значение в списке стоимостей поездок и выводим
сообщение с названием автомобиля, который соответствует наименьшей стоимости.
Результат наших мучений на рисунке: