Лабораторная работа 4.1

Задание:

Написать программу, работающую с модальными и немодальными диалоговыми окнами. Программа должна предоставлять пользователю удобный интерфейс для ввода анкетных данных, а также информацию о нем в удобной форме.

Ход работы:

  1. Создание проекта. Создайте проект по той же схеме, что вы использовали на предыдущих занятиях. Дайте ему название L4_1.
  2. Создание меню. Измените предложенный ресурс “меню” так, чтобы он содержал следующие пункты: Файл->Выход, Диалог->Модальный, Диалог->Немодальный, О программе.
  3. Создание ресурса “диалоговое окно”. Для того чтобы добавить ресурс “диалоговое окно” необходимо выполнить команду Insert-> Resource (Ctrl+R). После этого в появившемся окне нужно выбрать пункт Dialog, и нажать клавишу New.
  4. Добавление элементов управления. Перейдите на вкладку Resource View, и выберете диалоговое окно с идентификационным номером IDD_DIALOG1. Добавьте элементы управление на ваше диалоговое окно, щелкая мышью сначала на панели элементов управления (controls), на нужном элементе, а затем в том месте вашего диалогового окна, куда бы вы хотели добавить этот элемент.
  5. Элементы управления:

    Вид диалогового окна:



  6. Придание свойств различным элементам управления. Для того, чтобы установить некоторые свойства какого-нибудь элемента управления необходимо щелкнуть на нем правой клавишей и в появившемся контекстном меню выбрать пункт Properties. При этом появиться окно следующего вида:
  7. Установите у всех элементов свойство Caption (Надпись) в соответствии с надписями показанными на рисунке 4.1.2. У элемента “Собак” установите свойство Group (это нужно для того, чтобы переключатели составляли группу, и нельзя было выбрать два элемента одновременно). У комбинированного списка на вкладке Data, введите элементы которые будут в нем отображаться (для перехода на следующую строку нажимайте Ctrl+Enter) (Рис. 4.1.4).

  8. Создание класса “диалогового окна”. Щелкните на вашем диалоговом окне правой клавишей мыши и в появившемся контекстном меню выберете пункт ClassWizard. После этого Class Wizard сообщит вам, что для вашего ресурса диалогового окна не создано класса и предложит его создать. Как только вы ответите утвердительно перед вами возникнет окно, где нужно будет ввести имя класса а также базовый класс (обычно это CDialog) (Рис.4.1.5) Стоит заметить, что имена классов в Visual C++ принято начинать с C.
  9. Добавление переменных-членов класса вашего диалогового окна. У каждого элемента управления есть свой идентификатор. И для того чтобы можно было работать с этим элементом управления, необходимо идентификатору сопоставить переменную-член класса диалогового окна. Сопоставляемые переменные-члены могут быть двух категорий: Value(Значение) – представляющие значения вырабатываемые конкретными элементами управления, и Control(Управление) – представляющие классы конкретных элементов управления. Для того чтобы добавить переменные-члены вашего класса необходимо запустить ClassWizard, и перейти на вкладку Member Variables, после чего нажать кнопку Add Variable(Рис. 4.1.6). Стоит заметить, что имена переменных-членов в Visual C++ принято начинать с m_.
  10.  

  11. Написание инициализирующего кода. Инициализацию элементов управления лучше всего производить в функции OnInitDialog. Эта функция является обработчиком сообщения WM_ INITDIALOG, поэтому запустите Class Wizard, и создайте ее. А затем добавьте в нее следующий код.

BOOL Ankets::OnInitDialog()

{

// Преобразуем идентификатор списка в указатель на этот список.

// Note: Нельзя пытаться обратиться к элементу управления,

// преобразовав его идентификатор, если у него есть переменная-

// член из категории Control.

CListBox* pList=(CListBox*) GetDlgItem(IDC_LIST1);

CSliderCtrl* pSlid=(CSliderCtrl*) GetDlgItem(IDC_SLIDER1);

// Инициализация списка

pList->InsertString(-1,"Окрошка");

// Добавляем новый элемент в список. -1 означает, что

// данный элемент добавляется в конец списка.

pList->InsertString(-1,"Пельмени");

pList->InsertString(-1,"Картошка");

pList->InsertString(-1,"Блинчики");

pList->InsertString(-1,"Пирожки");

///////////////////////////////////////////////////

//Инициализация ползунка. Установка максимального и

//минимального значений.

pSlid->SetRange(0,100);

return CDialog::OnInitDialog();

}

  1. Присваивание переменным начальных значений. Если нужно, то можно установить начальные значения переменных в функции, откуда происходит вызов диалогового окна. В нашем случае это обработчик сообщения поступающего от пункта меню. Поэтому при помощи ClassWizard создайте обработчик сообщения поступающего от пункта “модальный” и добавьте в него следующий код.
  2. void CMainFrame::OnMenuModal()

    {

    //Note: Не забудьте в начале данного класса подключить

    // описание класса Ankets, при помощи команды

    // #include "Ankets.h"

    //Создание переменной my_dialog

    Ankets my_dialog;

    //Пример присваивания начального значения списку

    my_dialog.m_eat="Блинчики";

    //Вызов модального диалогового окна

    my_dialog.DoModal();

    }

  3. Самостоятельная работа. Добавьте вывод введенной информации в окно приложения. Для до вызова DoModal получите указатель на текущий контекст устройства, и в нем выведите текст на экран.
  4. Добавление немодального диалогового окна. Добавьте ресурс “диалоговое окно”, и создайте для него класс CNemodal, производный от CDialog. Не забудьте в свойствах ресурса установить свойство Visible.
  5. Добавление нового конструктора. Так как AppWizard изначально генерирует модальный конструктор, то нам он не подходит. Поэтому мы должны создать новый немодальный конструктор и еще функцию создания немодального диалогового окна. Эти функции должны быть объявлены как Public. Также необходимо добавить закрытую переменную, в которой будет храниться указатель на объект CView.
  6. private:

    // Переменная указатель на объект Cview.

    CView* m_pView;

    ………………………………..

    //Немодальный конструктор

    CNemodal::CNemodal(CView *pView)

    {

    //Сохраняем указатель на переданный экземпляр класса CView

    m_pView=pView;

    }

    // Функция создания немодального окна

    BOOL CNemodal::Create()

    {

    // Создание немодального окна

    return CDialog::Create(CNemodal::IDD);

    }

    Чтобы при генерации модального окна не происходило ошибок, вставьте в модальный конструктор следующую строчку:

    m_pView=NULL;

  7. Добавление нового идентификатора сообщения. Добавьте в файл Nemodal.h следующее описание:
  8. #define WM_GOODBYE WM_USER+5

  9. Редактирование функций OnOK и OnCancel. Добавьте обработчики кнопок Ok и Cancel, и отредактируйте их следующим образом:

// Вызывается когда пользователь нажимает

// кнопку Ok

void CNemodal::OnOK()

{

// Если созданное диалоговое окно создано

// при помощи немодального конструктора то отсылаем

// сообщение WM_GOODBYE

if (m_pView != NULL)

{

// Если немодальное окно, то тогда обновляем данные,

// и посылаем сообщение WM_GOODBYE от кнопки OK

UpdateData(TRUE);

m_pView->PostMessage(WM_GOODBYE,IDOK);

}

else

// Если же модальное окно, то пользуемся

// стандартной функцией.

CDialog::OnOK();

}

// Вызывается когда пользователь нажимает

// кнопку Cancel

void CNemodal::OnCancel()

{

// Если созданное диалоговое окно создано

// при помощи немодального конструктора то отсылаем

// сообщение WM_GOODBYE

if (m_pView != NULL)

{

// Если немодальное окно, то посылаем сообщение

// WM_GOODBYE от кнопки CANCEL

m_pView->PostMessage(WM_GOODBYE,IDCANCEL);

}

else

// Если же создано модальное окно,

// то пользуемся стандартной функцией.

CDialog::OnCancel();

}

  1. Редактирование класса CL4_1View. Для того чтобы Вы могли работать с немодальным диалоговым окном необходимо в классе CL4_1View создать указатель на экземпляр диалогового окна. Для этого добавьте в заголовочный файл следующие строки.
  2. #if _MSC_VER > 1000

    #pragma once

    #endif // _MSC_VER > 1000

    //Определение класса CNemodal

    //для того чтобы не надо было

    //подключать заголовочный файл

    // к каждому классу

    class CNemodal;

    // Создание переменной указывающей на

    // объекты класса CNemodal.

    private:

    CNemodal* m_pDlg;

  3. Создание обработчика сообщения WM_GOODBYE. Добавьте в класс CL4_1View обработчик сообщения WM_GOODBYE. Сделать это придется вручную, так как это нестандартное сообщение. Для этого сначала необходимо добавить макрос в таблицу сообщений, связывающий данное сообщение с конкретной функцией – обработчиком. А затем добавить саму функцию.

Добавление макроса

BEGIN_MESSAGE_MAP(CL4_1View, CView)

// Макрос связывающий сообщение с функцией-обработчиком

ON_MESSAGE(WM_GOODBYE,OnGoodbye)

//{{AFX_MSG_MAP(CL4_1View)

ON_WM_LBUTTONDOWN()

ON_COMMAND(ID_MENU_NEMODAL, OnMenuNemodal)

ON_WM_RBUTTONDOWN()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

Добавление прототипа

protected:

// Прототип функции-обработчика собщения WM_GOODBYE

afx_msg void CL4_1View::OnGoodbye(UINT wParam, LONG lParam);

//{{AFX_MSG(CL4_1View)

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg void OnMenuNemodal();

afx_msg void OnRButtonDown(UINT nFlags, CPoint point);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

Добавление функции

// Функция - обработчик сообщения WM_GOODBYE

void CL4_1View::OnGoodbye(UINT wParam, LONG lParam)

{

// Уничтожаем немодальное окно

m_pDlg->DestroyWindow();

}

  1. Вызов немодального окна. Для того чтобы добавить в Вашу программу возможность вызова немодального окна необходимо создать в классе CL4_1View обработчик сообщения ON_COMMAND, которое посылается пунктом меню “Немодальное”.
  2. // Обработчик пункта "Немодальное"

    void CL4_1View::OnMenuNemodal()

    {

    //Если указатель на окно равен 0

    //(Если окно не создано)

    if (m_pDlg->GetSafeHwnd()==0)

    {

    //Создаем окно

    m_pDlg->Create();

    }

    }

  3. Домашнее задание. Добавьте в немодальное окно различные элементы управления и напишите код для вывода данных в основное окно программы.