Опубликован: 17.08.2010 | Доступ: свободный | Студентов: 999 / 59 | Оценка: 4.11 / 3.89 | Длительность: 29:38:00
Самостоятельная работа 6:

Диалоговые окна MFC

Подключение собственного диалога к приложению

Мы сконструировали собственный диалог, который теперь можно использовать точно также, как и стандартный диалог, а именно:

  1. Объявить экземпляр класса CMsgDlg
  2. Вызвать метод DoModal() экземпляра и сохранить возвращаемое им значение
  3. Прочитать значения введенных ранее переменных m_strMessage и m_iOption
  4. Огорчиться на себя за то, что мы нарушили главный принцип ООП (объектно-ориентированное программирование) - инкапсуляцию данных, и быстренько исправить этот огрех, переобъявив переменные как private и добавив функции доступа к этим переменным

Решим эту задачу в соответствии со следующими пошаговыми инструкциями

Подключение диалога с прямым доступом к данным-членам класса CMsgDlg из класса-клиента CDialogsMsg
  • Добавьте в объявление класса-клиента переменную-экземпляр созданного нами класса CMsgDlg в соответствии с настройкой мастера, приведенной ниже. Для этого выделите в панели Class View класс CDialogsDlg и через контекстное меню откройте мастер


    Мастер добавит код

    Объявление в классе CDialogsDlg переменной-экземпляра класса CMsgDlg
    class CDialogsDlg : public CDialog
    {
    ..............................................
    private:
    	// Экземпляр класса нашего диалогового окна
    	CMsgDlg m_dMsgDlg;
    };
  • Добавьте в класс-клиент CDialogsMsg директиву препроцессора (предварительного компилятора) для подключения к нему объявления класса-сервиса CMsgDlg. Для этого через панель Solution Explorer откройте на редактирование файл DialogsMsg.h и в самом начале файла, перед объявлением класса CDialogsDlg, подключите заголовочный файл с описанием класса CMsgDlg, как показано ниже

    Подключение файла с объявлением класса-сервиса CMsgDlg 
    перед объявлением класса-клиента CDialogsDlg в файле DialogsDlg.h
    // DialogsDlg.h : header file
    //
    	
    #pragma once // Страж включения
    #include "afxwin.h"
    	
    #include "MsgDlg.h"
    // CDialogsDlg dialog
    class CDialogsDlg : public CDialog
    {
    .....................................
    };

    Обратите внимание, что в каждом заголовочном файле, созданном оболочкой, она в самом начале файла размещает директиву препроцессора "#pragma once", которую называют стражем включения. Это связано с тем, что включение файла может быть размещено во многих местах приложения, а препроцессор должен включить в приложение только первый встретившийся экземпляр кода. Эта директива и поднимает флаг у препроцессора, заставляя его игнорировать повторные включения одного и того же кода. В реализациях других производителей компиляторов можно встретить иной прием

    #ifndef ИМЯ_ВКЛЮЧАЕМОГО_ФАЙЛА
      #define ИМЯ_ВКЛЮЧАЕМОГО_ФАЙЛА
      
      	код включаемого файла
      
      #endif
  • Добавьте обработчик к кнопке "Сконструированный диалог", запускающий на выполнение окно нашего диалога

    Обработчик кнопки "Сконструированный диалог" запуска диалога
    // Обработчик кнопки "Сконструированный диалог"
    void CDialogsDlg::OnBnClickedBCustomdialog()
    {
    	// Запросить информацию через диалог
    	if(m_dMsgDlg.DoModal() == IDOK){
    		m_strResult = m_dMsgDlg.m_strMessage;// Напрямую, т.к. public
    		// разблокировать кнопку "Какая опция?"
    		m_cWhichOption.EnableWindow(TRUE);
    	}
    	else
    		m_strResult = "Ввод информации отменен!";
    	
    	// Передать на экран новое значение поля редактирования
    	UpdateData(FALSE);
    }
  • Добавьте обработчик к кнопке "Какая опция?"
    Обработчик кнопки "Какая опция?"
    // Обработчик кнопки "Какая опция?"
    void CDialogsDlg::OnBnClickedBWhichoption()
    {
    	// Какая радиокнопка включена
    	switch(m_dMsgDlg.m_iOption){
    		case 0:
    			m_strResult = "Была выбрана первая опция";
    			break;
    		case 1:
    			m_strResult = "Была выбрана вторая опция";
    			break;
    		case 2:
    			m_strResult = "Была выбрана третья опция";
    			break;
    		case 3:
    			m_strResult = "Была выбрана четвертая опция";
    			break;
    		default:
    			m_strResult = "Опция не выбрана!";
    	}
    	
    	// Передать на экран новое значение поля редактирования
    	UpdateData(FALSE);
    }
  • Запустите приложение и убедитесь в его работоспособности
Подключение диалога с доступом к данным-членам класса CMsgDlg из класса-клиента CDialogsMsg через функции доступа
  • Измените в объявлении класса CMsgDlg данные-члены m_strMessage и m_iOption как private
  • Добавьте к классу CMsgDlg методы доступа public, возвращающие значения этих переменных:
    • CString GetMessage() {return m_strMessage;}
    • int GetOption() {return m_iOption;}
  • Замените в последних двух обработчиках класса CDialogsMsg прямые вызовы переменных m_strMessage и m_iOption через вызовы функций доступа

Изменение конфигурации проекта для его автономной работы

  • Постройте окончательный вариант приложения в режиме Release и убедитесь, что размер исполнимого файла составляет примерно 15K

Это малый размер для такой задачи и объясняется это тем, что при создании приложения мы настроили мастер на использование библиотек DLL

Таблица настройки мастера создания каркаса приложения
Use of MFC: Use MFC in a shared DLL

Такое приложение не будет работать на компьютере, где нет этих библиотек. Поэтому следует построить автономное приложение, включающее в себя весь необходимый код. Для этого:

  • Выполните опцию Project/Dialogs Properties для нашего проекта Dialogs


    Появится окно, в котором установите режим

    Изменение режима в таблице свойcтв приложения
    Use of MFC: Use MFC in a Static Library

  • Перестройте приложение и определите размер исполнимого файла

Исполнимый файл приложения увеличился примерно до 155K. Такой файл будет работать на любом компьютере с операционной системой Windows.


Александр Даниленко
Александр Даниленко
Стоит Windows 8 Pro, Visual Studio 2010 Express Edition .