Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual1.doc
Скачиваний:
8
Добавлен:
07.03.2016
Размер:
4.35 Mб
Скачать

8.8.3. Клас Cdlg

Структура для зберігання інформації про автомобіль має вигляд:

struct dialog

{

int color;

int kol_mach;

int marka;

int god;

int sost;

int probeg;

BOOL kond;

BOOL signal;

int val;

double grn;

double euro;

DWORD color_viv;

LOGFONT logFont;

};

У класі Cdlg зробимо змінну dial типу dialog. Майже у всіх функціях класу будемо звертатись до цієї змінної. Цей клас створено для редагування інформації (див. рис. 8.17). В ньому створені елементи керування та функції, які реагують на зміни в них.

Конструктор класу має такий вид:

Cdlg::Cdlg(dialog di, CDialDoc* pParent)

: CDialog(Cdlg::IDD,0)

{

dial = di;

par = pParent;

}

У ньому ми встановлюємо значення змінної dial відповідно до параметру di, який було передано із зовнішнього класу.

Одна із найважливіших функцій це DoDataExchange, вона викликається для зв’язування змінних діалогу із елементами керування:

void Cdlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(Cdlg)

DDX_Control(pDX, IDC_CHECK2, m_signal);

DDX_Control(pDX, IDC_CHECK1, m_kond);

DDX_Control(pDX, IDC_SLIDER1, m_slid1);

DDX_Control(pDX, IDC_LIST1, m_mark);

DDX_Control(pDX, IDC_COMBO1, m_tp);

DDX_Control(pDX, IDC_SLIDER2, m_slid2);

DDX_Text(pDX, IDC_EDIT1, m_mach);

DDX_Text(pDX, IDC_EDIT2, m_sost);

DDX_Text(pDX, IDC_EDIT3, m_probeg);

//}}AFX_DATA_MAP

}

Рис. 8.17. Вікно діалога з ідентифікаторами елементів (клас Cdlg)

Ця функція викликається класом автоматично, заповнюється майстром. В ній можна бачити, які елементи керування зв’язані з якими змінними. Вище було зазначено, що можна викликати функцію UpdateData, яка викличе DoDataExchange. Функція UpdateData приймає параметр BOOL bSaveAndValidate, якщо він має значення TRUE, то значення від елементів керування будуть перенесені до змінних, а коли значення FALSE, то навпаки в залежності від змінних будуть змінені елементи керування.

Також цікаво подивитись карту повідомлень:

BEGIN_MESSAGE_MAP(Cdlg, CDialog)

//{{AFX_MSG_MAP(Cdlg)

ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)

ON_EN_CHANGE(IDC_EDIT3, OnChangeEdit3)

ON_LBN_SELCHANGE(IDC_LIST1, OnSelchangeList1)

ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1)

ON_BN_CLICKED(IDC_CHECK1, OnCheck1)

ON_BN_CLICKED(IDC_CHECK2, OnCheck2)

ON_EN_CHANGE(IDC_EDIT5, OnChangeEdit5)

ON_EN_CHANGE(IDC_EDIT6, OnChangeEdit6)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

В карті повідомлень вказано які події операційної системи Windows пов’язуються з якими функціями. Так наприклад: ON_EN_CHANGE означає подію зміни тексту в текстовому полі (EEdit), ON_LBN_SELCHANGE означає подію зміни фокуса у елементі списку (LBListBox).

При створенні вікна діалогу, після функцій DoModal та DoDataExchange викликається функція OnInitDialog:

BOOL Cdlg::OnInitDialog()

{

CString str;

CDialog::OnInitDialog();

for(int i = 0; i < 11; i++)

{

m_mark.AddString(par->mas_mach[i]);

m_mark.SetItemData(i,par->mas_st[i]);

}

m_mark.SetCurSel(dial.marka);

m_marka = dial.marka;

m_tp.AddString("2008");

m_tp.AddString("2007");

m_tp.AddString("2006");

m_tp.AddString("2005");

m_tp.AddString("2004");

m_tp.AddString("2003");

m_tp.AddString("2002");

m_tp.AddString("2001");

m_tp.SetCurSel(dial.god);

str.Format("%.2f",dial.grn);

GetDlgItem(IDC_EDIT5)->SetWindowText(str);

str.Format("%.2f",dial.euro);

GetDlgItem(IDC_EDIT6)->SetWindowText(str);

if(dial.color == 0)

((CButton*)GetDlgItem(1008))->SetCheck(1);

if(dial.color == 1)

((CButton*)GetDlgItem(1009))->SetCheck(1);

if(dial.color == 2)

((CButton*)GetDlgItem(1010))->SetCheck(1);

if(dial.val == 0)

GetDlgItem(IDC_STATIC1)->SetWindowText("$");

if(dial.val == 1)

GetDlgItem(IDC_STATIC1)->SetWindowText("грн");

if(dial.val == 2)

GetDlgItem(IDC_STATIC1)->SetWindowText("€");

m_kond.SetCheck(dial.kond);

m_signal.SetCheck(dial.signal);

m_slid1.SetRange(0,3);

m_slid1.SetPos(dial.sost);

m_slid1.SetTicFreq( 1);

m_slid1.SetLineSize(1);

m_slid1.SetPageSize(3);

m_slid2.SetRange(0,500);

m_slid2.SetPos(dial.probeg);

m_slid2.SetTicFreq(50);

m_slid2.SetLineSize(1);

m_slid2.SetPageSize(50);

m_mach.Format("%d",dial.kol_mach);

m_probeg.Format("%d",dial.probeg);

return TRUE;

}

У даній функції ми заповнюємо такі елементи керування як списки і бігунки, тому що стандартна функція DodataExchange з цим завданням впоратись не зможе. Елемент керування список має декілька рядків тексту, один із яких є активним. Активність рядка списка (CListBox) задається функцією SetCurSel. Функція SetPos бігунка (CSliderCtrl) встановлює позицію повзунка. Функція SetRange задає мінімальне та максимальне значення для повзунка. Функція SetTicFreq бігунка встановлює відстань між діленнями. Функція SetLineSize задає значення на яке буде змінюватись позиція бігунка при натисненні курсорів на клавіатурі. Функція SetPageSize встановлює значення на яке буде змінюватись позиція бігунка при натисненні на клавіатурі кнопок [Page Up] та [Page Down].

Функція, яка викликається при зміні елемента IDC_EDIT1 має вигляд:

void Cdlg::OnChangeEdit1()

{

char buf[20];

CEdit* kol_mach_ed = (CEdit*)GetDlgItem(IDC_EDIT1);

kol_mach_ed->LimitText(3);

kol_mach_ed->GetWindowText(buf,20);

if ((!IsNumeric(buf,0) && buf[0]!=0)

|| buf[0]== '+' || buf[0]== '-')

{

kol_mach_ed->Undo();

kol_mach_ed->SetSel(65534, 65534);

kol_mach_ed->SetFocus();

return;

}

kol_mach_ed->EmptyUndoBuffer();

UpdateData(1);

dial.kol_mach = atoi(buf);

cena();

}

В текстовому полі IDC_EDIT1 вказується кількість автомобілів, а функція OnChangeEdit1 слідкує за правильним введенням даних. В функції ми робимо такі дії: виділяємо буфер buf[20] та створюємо вказівку на об’єкт класу CEdit. Функція GetDlgItem повертає дискриптор вікна HWND, який потрібно приводити до потрібного класу елементу керування. Далі зчитуємо текст із текстового поля в буфер (зчитування тексту робить функція GetWindowText) та перевіряємо чи не містить цей текст нечислові символи (цю перевірку робить функція IsNumeric, яку створили у класі Cdlg). Якщо інформація введена правильно викликаємо функцію EmptyUndoBuffer, якою фіксуємо зміни значення текстового поля, тобто функція Undo уже не буде діяти. Інакше, якщо введено не коректні дані (одразу після умови if) викликаємо функцію Undo, для повернення попереднього значення.

Функція, яка викликається при зміні елемента IDC_EDIT3 має вигляд:

void Cdlg::OnChangeEdit3()

{

char buf[20];

CEdit* rasgon_ed = (CEdit*)GetDlgItem(IDC_EDIT3);

rasgon_ed->GetWindowText(buf,20);

if ((!IsNumeric(buf,0) && buf[0]!=0)

|| buf[0]== '+' || buf[0]== '-')

{

rasgon_ed->Undo();

rasgon_ed->SetSel(65534, 65534);

rasgon_ed->SetFocus();

return;

}

rasgon_ed->EmptyUndoBuffer();

CSliderCtrl* m_slid2 = (CSliderCtrl*)

GetDlgItem(IDC_SLIDER2);

m_slid2->SetPos(atoi(buf));

UpdateData(1);

}

В цьому полі вказується пробіг автомобіля. Функція має аналогічний вигляд, як і розглянута вище, але відмінність полягає у тому, що до поля приєднується елемент керування CSliderCtrl. Функція SetPos встановлює позицію бігунка.

Елементи IDC_EDIT5 та IDC_EDIT6 слугують для введення курсів гривні та евро відносно долару. Логіка роботи така як і у IDC_EDIT1:

void Cdlg::OnChangeEdit5()

{

char buf[20];

CEdit* grn_ed = (CEdit*)GetDlgItem(IDC_EDIT5);

grn_ed->GetWindowText(buf,20);

grn_ed->LimitText(4);

if ((!IsNumeric(buf,2) && buf[0]!=0)

|| buf[0]== '+' || buf[0]== '-')

{

grn_ed->Undo();

grn_ed->SetSel(65534, 65534);

grn_ed->SetFocus();

return;

}

grn_ed->EmptyUndoBuffer();

UpdateData(1);

dial.grn = atof(buf);

cena();

}

void Cdlg::OnChangeEdit6()

{

char buf[20];

CEdit* euro_ed = (CEdit*)GetDlgItem(IDC_EDIT6);

euro_ed->GetWindowText(buf,20);

euro_ed->LimitText(4);

if ((!IsNumeric(buf,2) && buf[0]!=0)

|| buf[0]== '+' || buf[0]== '-')

{

euro_ed->Undo();

euro_ed->SetSel(65534, 65534);

euro_ed->SetFocus();

return;

}

euro_ed->EmptyUndoBuffer();

UpdateData(1);

dial.euro = atof(buf);

cena();

}

Функція Cdlg::cena слугує для розрахунку ціни автомобіля залежно від заданих параметрів. Розрахована ціна виводиться у поле IDC_EDIT4:

void Cdlg::cena()

{

double m_cena;

CString per;

m_cena = (m_mark.GetItemData(dial.marka)

+500*(dial.kond + dial.signal)

+dial.color*100 - dial.probeg*10)

*(1-0.2*dial.sost)*(1-0.03*dial.god)

*dial.kol_mach;

if (dial.val==1) m_cena*= dial.grn;

if (dial.val==2) m_cena*= dial.euro;

per.Format("%.2f",m_cena);

GetDlgItem(IDC_EDIT4)->SetWindowText(per);

}

Функція Format з класу CString дозволяє перевести значення змінної m_cena у рядковий формат. Функція SetWindowText з класу CEdit встановлює текст у поле елемента IDC_EDIT4.

Функція на зміну марки автомобіля має такий вид:

void Cdlg::OnSelchangeList1()

{

dial.marka = m_mark.GetCurSel();

cena();

}

Змінна m_mark має тип CListBox, пов’язана з елементом керування IDC_LIST1. Функція GetCurSel повертає номер вибраного рядка списку.

Рік випуску автомобіля задається функцією OnSelchangeCombo1:

void Cdlg::OnSelchangeCombo1()

{

dial.god = m_tp.GetCurSel();

cena();

}

Змінна m_tp має тип CComboBox, пов’язана з елементом керування IDC_COMBO1.

Розглянемо функцію OnNotify:

BOOL Cdlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)

{

if (wParam == IDC_SLIDER1)

{

dial.sost=m_slid1.GetPos();

if (dial.sost== 0)m_sost = "отличное";

if (dial.sost== 1)m_sost = "хорошее";

if (dial.sost== 2)m_sost = "среднее";

if (dial.sost== 3)m_sost = "ниже среднего";

}

if (wParam == IDC_SLIDER2)

{

m_probeg.Format("%d", m_slid2.GetPos());

dial.probeg = m_slid2.GetPos();

}

UpdateData(0);

cena();

return CDialog::OnNotify(wParam, lParam, pResult);

}

Ця функція викликається при отриманні повідомлення WM_NOTIFY, яке використовується для оповіщення батьківського вікна елемента керування про те, що у ньому відбулась подія. При зміні елементу керування IDC_SLIDER1 див. рис. 8.18 відбуваються такі події:

2) викликається функція OnNotify, у котрій відбуваються усі інші дії;

3) змінна dial.sost отримує нове значення у залежності від позиції елементу IDC_SLIDER1. Функція GetPos класу CSlider повертає позицію бігунка;

4) робляться зміни у текстовому полі IDC_EDIT2 через функцію UpdateData(0), яка викликає описану вище функцію DoDataExchange;

5) викликається функція cena для розрахунку нової ціни у текстовому полі IDC_EDIT4.

Рис. 8.18. Використання функції OnNotify у класі Cdlg

1 – зміни у елементі керування IDC_SLIDER1;

2 – виклик функції OnNotify.

При зміні позиції бігунка у елементі IDC_SLIDER2 змінюються інші параметри, але відбуваються дії аналогічні до зображених на рис. 8.18.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]