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

8.9. Формування вхідного документа на основі діалогу

Приклад формування вхідного документа на основі діалогу знаходиться у папці DISK\dialog\dialog10.

Розглянемо динамічне формування вікна діалогу на основі вхідних параметрів. У програмі мають місце 2 вікна діалогу. Перше вікно призначене для введення кількості рядків (рис. 8.19), а друге в залежності від введеної цифри буде створювати таку ж кількість рядків із полів для введення значень кутів (рис. 8.20). Створимо простий SDI проект з назвою Vvod.

Створимо перший діалог на основі ресурсу IDD_DIALOG1 та класу з назвою Dialog1. У редакторі ресурсів створимо текстове поле та підпис до нього. Код ресурса діалога прийме такий вид:

IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 87

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION "Dialog"

FONT 8, "MS Sans Serif"

BEGIN

DEFPUSHBUTTON "OK",ID_OK,129,66,50,14,NOT WS_TABSTOP

PUSHBUTTON "Cancel",IDCANCEL,75,66,50,14,NOT WS_TABSTOP

EDITTEXT IDC_EDIT100,27,29,33,16,ES_AUTOHSCROLL

LTEXT "К-во строк",IDC_STATIC,26,15,50,15

END

Для контролю текстового поля додамо у клас діалогу вказівку на об'єкт типу CEdit:

class Dialog1 : public CDialog

{

// Construction

public:

.............................................................

CEdit* kol_p;

int kol_punk;

.............................................................

};

У функції OnInitDialog допишемо підключення вказівки kol_p до текстового поля, та змінимо настройки максимальної довжини поля до 1-го символа функцією SetLimitText:

BOOL Dialog1::OnInitDialog()

{

CDialog::OnInitDialog();

kol_p = (CEdit*)GetDlgItem(IDC_EDIT100);

kol_p->SetLimitText(1);

return TRUE;

}

Для реакції діалогового вікна на події операційної системи додамо функцію OnCommand:

BOOL Dialog1::OnCommand(WPARAM wParam, LPARAM lParam)

{

char buf[5];

bool log;

CString vr;

if (!IsWindowVisible()) return 0;

if((HIWORD(wParam) == 768 || HIWORD(wParam) == 256)

&& LOWORD(wParam) == IDC_EDIT100 )

{

kol_p->GetWindowText(vr);

strcpy(buf,vr.GetBuffer(1));

log = IsNumeric(buf);

if ((!log && buf[0]!=0) || buf[0]=='+' || buf[0]=='-' || buf[0]=='0')

{

kol_p->Undo();

kol_p->SetSel(65534, 65534);

kol_p->SetFocus();

return 0;

}

else kol_p->EmptyUndoBuffer();

SetWindowText("Диалог");

}

if (LOWORD(wParam) == ID_OK)

{

kol_p->GetWindowText(vr);

strcpy(buf,vr.GetBuffer(1));

if (buf[0]== 0)

{

kol_p->SetFocus();

SetWindowText("Внимание !!! Введите к-во строк");

return 0;

}

kol_punk = atoi(buf);

OnOK();

return CDialog::OnCommand(wParam, lParam);

}

if(wParam == 1) return 0;

return CDialog::OnCommand(wParam, lParam);

}

При натисненні кнопки OK у змінну діалогу kol_punk записується число введене у текстове поле. У випадку коли поле буде пустим буде виведено повідомлення про необхідність введення данних.

В класі документа додамо двомірний масив mas_zas:

class CVvodDoc : public CDocument

{

.............................................................

public:

int mas_zas[10][8];

.............................................................

};

У конструкторі класу документа обнуляємо усі значення крім 1-го стовпчика:

CVvodDoc::CVvodDoc()

{

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

{

mas_zas[i][0]=i+1;

for (int j = 1;j<8;j++)

mas_zas[i][j]=0;

}

}

Додамо пункт меню з назвою Vvod зробимо функцію для цього пункта меню з назвою OnVvod:

void CVvodDoc::OnVvod()

{

Dialog1 dlg1;

if(dlg1.DoModal() != IDOK) return;

Dialog2 dlg2;

dlg2.doc = this;

dlg2.kol_punk = dlg1.kol_punk;

dlg2.DoModal();

}

Тут створюється спочатку об'єкт класу Dialog1 а потім вікно Dialog2. Як видно з коду наведеної функції значення змінної kol_punk копіюється із першого діалога у другий.

Рис. 8.19. Діалог для введення кількості рядків

Створимо другий діалог на основі ресурсу IDD_DIALOG2 та класу з назвою Dialog2. Додамо у клас діалогу масиви вказівок на елементи керування:

class Dialog2 : public CDialog

{

.............................................................

CEdit* Ugl[9][7];

CButton* Zn_nak[9];

.............................................................

int kol_punk;

.............................................................

};

Використання змінної kol_punk у діалозі Dialog2 можна побачити у функції ShowDlgElement:

void Dialog2::ShowDlgElement() // Показ елементів

{

int i,j;

CString vr;

for(i=0; i<9; i++)

{

if(i < kol_punk)

{

Zn_nak[i]->ShowWindow(SW_SHOW);

if(doc->mas_zas[i][4]>0)

Zn_nak[i]->SetWindowText("+");

else Zn_nak[i]->SetWindowText("--");

}

else Zn_nak[i]->ShowWindow(SW_HIDE);

for(j=0; j<7; j++)

{

if(i < kol_punk)

{

Ugl[i][j]->ShowWindow(SW_SHOW);

vr.Format("%d",

abs(doc->mas_zas[i][j]));

Ugl[i][j]->SetWindowText(vr);

}

else Ugl[i][j]->ShowWindow(SW_HIDE);

} // for j

} // for i

}

Як видно із коду елементи керування Ugl (текстові поля) і Zn_nak (кнопки) завдяки викликам функції ShowWindow будуть показані або сховані на вікні діалогу. Кількість показаних елементів буде залежати від значення змінної kol_punk. На елементах Zn_nak завдяки функції SetWindowText встановлюється підпис, що означає додатнє або від'ємне значення кута. Функція ShowDlgElement викликається у програмі тільки при створенні вікна діалогу із функції OnInitDialog:

BOOL Dialog2::OnInitDialog()

{

CDialog::OnInitDialog();

int i,j;

for(i=0; i<9; i++)

{

Zn_nak[i] = (CButton*)GetDlgItem(IDC_BUTTON1 + i);

for(j = 0; j < 7; j++)

Ugl[i][j] = (CEdit*)GetDlgItem(IDC_EDIT1 + i*7 + j);

Ugl[i][0]->SetReadOnly();

}

ShowDlgElement();

SetWindowText("Ввод данных");

MoveDlg(); //подтягивание снизу

hb = ::CreateSolidBrush(RGB(200,0,0));

return TRUE;

}

Оскільки кожен раз при відкритті діалогу Dialog2 кількість рядків для введення буде різною то і його розміри доцільно робити відповідними кількості полів. Функція MoveDlg створена для розрахунку розмірів вікна діалогу:

void Dialog2::MoveDlg() //Подтягивание окна и елементов

{

CRect vr_top,vr_bott,vr_st;

CWnd* elem;

int i,delta=0;

int mas_elem[5]={ID_OK,IDCANCEL,IDC_STATIC120,

IDC_STATIC_B1,IDC_STATIC_B2};

Ugl[kol_punk-1][0]->GetWindowRect(vr_top);

Ugl[8][0]->GetWindowRect(vr_bott);

delta = vr_bott.bottom - vr_top.bottom;

for(i=0;i<5;i++)

{

elem=GetDlgItem(mas_elem[i]);

elem->GetWindowRect(vr_st);

ScreenToClient(vr_st);

if (i<3) vr_st.OffsetRect(0,-delta);

else vr_st.bottom-=delta;

elem->MoveWindow(vr_st);

}

GetWindowRect(vr_st);

vr_st.bottom-=delta;

MoveWindow(vr_st);

}

У змінній delta розраховується відстань між нижніми границям останнього поля у масиві та останього використовуємого поля для введення. Отже у delta отримаємо саме те значення, на яке потрібно підняти кнопки OK і Cancel а також зменшити висоту вікна. Функція MoveWindow змінює розміри вікна та його розташування. Переміщення елементів керування відбувається відносно батьківського вікна а переміщення самостійних вікон відбувається відносно екрану. Саме тому перед переміщенням елементів керування ми використали функцію ScreenToClient, котра перераховує екранні координати у координати відносно батьківського вікна.

Рис. 8.20. Діалог для введення значень кутів

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