Практикум прикладного программирования на MFC и C++ в среде VS.NET

Использование элементов управления MFC

Разбить на страницы
Показывать лекцию целиком
Файлы к данной лабораторной работе, Вы можете скачать здесь.

Оболочка содержит большинство управляющих элементов управления в готовом виде. Визуальный способ проектирования диалоговых панелей обеспечивает удобство и скорость для разработчика. Компоненты управляющих элементов содержатся в виде пиктограмм на панели Toolbox, вызываемой через главное меню оболочки View. Панель имеет три вкладки, нас интересует вкладка Dialog Editor. Если пиктограммы компонентов не помещаются в панели, то вверху и внизу по правой стороне существуют кнопки прокрутки.

Перенести компоненты управляющих элементов можно тремя способами:

  • Двойной щелчок на пиктограмме компонента.
  • Перетаскивание мышью.
  • Выделение компонента на пиктограмме, затем выделение его места размещения на форме диалогового окна щелчком.
  • Выделение компонента на пиктограмме, затем растягивание контура компонента на форме.
  • Каждому элементу управления, представленному на визуальной панели компонентов, соответствует класс библиотеки MFC. Любой из этих классов является потомком базового класса CWnd, поэтому представляет собой окно Windows.

    Ресурс каждого элемента управления должен иметь внутри формы диалогового окна уникальный идентификатор. Его можно назначать самому через панель свойств Properties, задавая в поле ID элемента мнемоническое значение или вибирая из раскрывающегося списка того же поля заготовленные имена. В любом случае рекомендуется соблюдать соглашения о префиксах: идентификаторы диалоговых окон имеют префикс $$IDD_$$, а идентификаторы элементов управления - префикс $$IDC_$$ .

    Цель работы

  • Изучить основные элементы управления диалоговых приложений.
  • Научиться объявлять переменные для компонентов и связывать их с самими компонентами.
  • Научиться синхронизировать значения между самими элементами управления и представляющими их в программе переменными.
  • Научиться задавать порядок получения фокуса ввода между элементами управления.
  • Научиться инициировать действия с помощью элементов управления.
  • Научиться задавать внешний вид элементов управления и изменять его во время выполнения приложения.
  • Изучаемые элементы управления

    Рассмотрим некоторый элементы управления, а именно:

  • Static Text - статический текст
  • Edit Control - поле редактирования
  • Button - кнопка
  • Check Box - флажок
  • Radio Button - радиокнопка
  • Combo Box - поле ввода со списком
  • Static Text - статический текст

    Этот элемент служит для отображения текста и не обеспечивает интерактивность (взаимодействие с пользователем), поэтому список событий у него пустой. Но можно заменять текст в процессе выполнения приложения, воздействуя на его свойство Caption.

    Основные свойства элемента управления Static Text
    Свойство Описание
    ID Идентифицирует элемент управления. Значение по умолчанию всегда IDC_STATIC
    Caption Определяет текст в элементе управления
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Надпись заблокированного элемента отображается серым текстом
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab
    Client Edge Включает рамку элемента управления
    Align Text Задает выравнивание текста внутри окна элемента
    Border Показывает рамку вокруг элемента
    Transparent Включает прозрачный фон окна компонента
    CStatic - класс поддержки в MFC

    Edit Control - поле редактирования

    Этот элемент управления позволяет получить от пользователя текстовую информацию. Окно воспринимает только простой текст с минимальными возможностями редактирования.

    Основные свойства элемента управления Edit Control
    Свойство Описание
    ID Идентифицирует элемент управления
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Надпись заблокированного элемента отображается серым текстом.
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления
    Align Text Задает выравнивание текста внутри окна элемента
    Border Показывает рамку вокруг элемента
    Transparent Включает прозрачный фон окна компонента
    Number Задает фильтр ввода "только для чисел"
    Password Эхо ввода заменяет символом *
    Multiline Включает возможность ввода нескольких строк
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    OEM Convert Включает автоматическую конвертацию кодировки CharToOem
    Uppercase Включает автоматическое преобразование в заглавные буквы (работает совместно с Lowercase как радиокнопка)
    Lowercase Включает автоматическое преобразование в строчные буквы (работает совместно с Uppercase как радиокнопка)
    Read Only Только для чтения - блокирует ввод
    CEdit - класс поддержки в MFC

    Button - кнопка

    Основные свойства элемента управления Button
    Свойство Описание
    ID Идентифицирует элемент управления
    Caption Определяет текст в элементе управления.
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Надпись заблокированного элемента отображается серым текстом.
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления.
    Horizontal Alignment Задает выравнивание текста внутри окна элемента по горизонтали.
    Vertical Alignment Задает выравнивание текста внутри окна элемента по вертикали
    Transparent Включает прозрачный фон окна компонента
    Multiline Включает возможность ввода нескольких строк
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    Static Edge Включает рамку элемента управления без выпуклого представления
    Default Button Задает фокус ввода при первом запуске приложения. Отмечает, что эта кнопка будет выполнена при нажатии клавиши Enter.
    CButton - класс поддержки в MFC

    Check Box - флажок

    Дает возможность пользователю включить или выключить некую возможность (опцию). Возможны флажки с промежуточным - третьим - состоянием.

    Основные свойства элемента управления Check Box
    Свойство Описание
    ID Идентифицирует элемент управления
    Caption Определяет поясняющий текст на элементе управления
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Изображение заблокированного элемента отображается серым
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления
    Horizontal Alignment Задает выравнивание текста внутри окна элемента по горизонтали.
    Vertical Alignment Задает выравнивание текста внутри окна элемента по вертикали
    Tri-state Включает третье состояние disabled (заблокирован). В этом состоянии значение элемента не рассматривается ни как true, ни как false.
    Transparent Включает прозрачный фон окна компонента
    Multiline Включает возможность ввода нескольких строк
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    Static Edge Включает рамку элемента управления без выпуклого представления
    Left Text Располагает надписи слева от флажка. При значении false надписи располагаются справа от флажка

    Radio Button - радиокнопка

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

    Основные свойства элемента управления Radio Button
    Свойство Описание
    ID Идентифицирует элемент управления.
    Caption Определяет поясняющий текст на элементе управления.
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Изображение заблокированного элемента отображается серым.
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления
    Horizontal Alignment Задает выравнивание текста внутри окна элемента по горизонтали
    Vertical Alignment Задает выравнивание текста внутри окна элемента по вертикали
    Transparent Включает прозрачный фон окна компонента
    Multiline Включает возможность ввода нескольких строк
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    Static Edge Включает рамку элемента управления без выпуклого представления
    Group Определяет первый из элементов управления в группе. Только у первого элемента в группе это свойство должно иметь значение true
    Auto По умолчанию задано значение true, что позволяет переключателю автоматически изменять свое состояние при его выборе пользователем
    Left Text Располагает надписи слева от переключателя. При значении false надписи располагаются справа от переключателя.

    Combo Box - поле ввода со списком

    Предоставляет раскрывающийся список выбора.

    Основные свойства элемента управления Combo Box
    Свойство Описание
    ID Идентифицирует элемент управления
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Изображение заблокированного элемента отображается серым.
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления.
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    Static Edge Включает рамку элемента управления без выпуклого представления
    Group Определяет первый из элементов управления в группе. Только у первого элемента в группе это свойство должно иметь значение true
    Auto По умолчанию задано значение true, что позволяет переключателю автоматически изменять свое состояние при его выборе пользователем
    Sort Определяет, будут ли отсортированы элементы в раскрывающемся списке
    Type Задает тип списка: " Dropdown - раскрывающийся при получении фокуса ввода " Simple - раскрыт все время Drop List - раскрывающийся с изображением текущего элемента списка.
    CComboBox - класс поддержки в MFC

    Класс CComboBox является производным от класса CWnd, но в свою очередь служит базовым классом для класса CComboBoxEx, который предоставляет функции для включения изображений в выбираемые элементы раскрывающегося списка.

    Класс CComboBox предоставляет функции для программного взаимодействия со списком:

  • GetCurSel() - определяет номер текущего пункта списка
  • SetCurSel() - устанавливает текущим элемент с заданным номером
  • SelectString() - выделяет строку
  • FindString() - ищет строку
  • AddString() - добавляет строку в конец списка
  • InsertString() - вставляет строку перед текущей
  • DeleteString() - удаляет текущую строку
  • ResetString() - устанавливает список в исходное состояние
  • Создание заготовки диалогового приложения и визуальная разработка интерфейса

  • Создайте новый проект MFC Application под названием Controls. Задайте именно такое название, чтобы дальше нам разговаривать на одном языке, поскольку мастер приложений при создании заготовки кода использует имя проекта в именах файлов и классов.
  • Выберите настройки мастера MFC Application Wizard как указано в таблице, остальные настройки в указанных вкладках должны быть сброшены. В неуказанных вкладках оставьте настройки по умолчанию.
    Таблица настройки мастера создания каркаса приложения
    Свойство проекта Значение
    Вкладка Application Type
    Application Type Dialog Based
    Resource language: Английский (США)
    Project style: MFC standard
    Use of MFC: Use MFC in a shared DLL
    Вкладка Advanced Features
    Все сбросить!
    Вкладка User Interface Features
    Main frame styles: System menu
    About box
    Dialog title: Controls
  • Создав заготовку приложения с помощью мастера, русифицируйте прежде всего ресурсы узлов
  • Спроектируйте диалоговую форму в соответствии с таблицей свойств.
    Таблица свойств главной диалоговой формы Controls
    Элемент управления Свойство Значение
    --------------------------------------------- 0 --------------------------------------------------
    Главная форма Caption Диалоговое приложение - элементы управления
    Font(Size) MS Sans Serif(10)
    Ширина 240
    Высота 180
    Static Text ID IDC_HEAD
    Caption Это пример приложения на C++ Visual Studio .NET, в котором используется множество разных элементов управления
    Ширина 200
    Высота 16
    --------------------------------------------- 1 --------------------------------------------------
    Static Text ID IDC_STATIC_MSG
    Caption Ввести сообщение
    Right Align Text True
    Ширина 70
    Высота 8
    Edit Control ID IDC_MSG
    Ширина 60
    Высота 14
    Button ID IDC_SHOW_MSG
    Caption Отобразить сообщение
    Ширина 85
    Высота 14
    --------------------------------------------- 2 --------------------------------------------------
    Button ID IDC_DEFAULT_MSG
    Caption Сообщение по умолчанию
    Ширина 90
    Высота 14
    Button ID IDC_CLEAR_MSG
    Caption Очистить сообщение
    Ширина 90
    Высота 14
    --------------------------------------------- 3 --------------------------------------------------
    Static Text ID IDC_STATIC_PROGRAM
    Caption Запустить программу
    Right Align Text True
    Ширина 75
    Высота 8
    Combo Box ID IDC_COMBO_RUN
    Ширина 90
    Высота 12
    Button ID IDC_RUN
    Caption Выполнить
    Ширина 50
    Высота 14
    --------------------------------------------- 4 --------------------------------------------------
    Group Box Caption Действия
    Ширина 110
    Высота 40
    Check Box ID IDC_ENABLE_MSG
    Caption Разрешить сообщения
    Check Box ID IDC_ENABLE_PROGRAM
    Caption Разрешить выполнение
    --------------------------------------------- 5 --------------------------------------------------
    Group Box Caption Отображать
    Ширина 110
    Высота 40
    Check Box ID IDC_SHOWS_MSG
    Caption Отображать сообщения
    Check Box ID IDC_SHOWS_PROGRAM
    Caption Отображать выполнение
    --------------------------------------------- 6 --------------------------------------------------
    Button ID IDC_EXIT
    Caption Выход
  • Задавая размеры элементов, пользуйтесь строкой состояния оболочки. Для выравнивания элементов управления используйте панель инструментов
  • В панели свойств Properties в верхней части раскройте выпадающий список и выделите элемент IDC_COMBO_RUN. Найдите свойство Data (Данные) и введите имена вызываемых программ, разделяя их точкой с запятой
    Notepad;msPaint;Sol
  • Найдите свойство Sort и установите его в состояние True. Такой режим обеспечит автоматическую сортировку элементов списка.
  • Щелкните на стрелке раскрывающегося списка, появится максимальный контур списка в раскрытом состоянии. Переместите нижнюю границу вниз с запасом, чтобы список в раскрытом состоянии имел нужный размер и чтобы точно поместились все его элементы без прокрутки. Отметьте, что если определить высоту, большую чем необходимо, то при выполнении высота раскрытого списка подравнивается под фактическую.
  • Определение последовательности перехода по клавиши табуляции

  • Установите последовательность перехода к элементам окна при нажатии клавиши Tab. Для этого в меню Format оболочки установите опцию Tab Order. На проекте диалогового окна появятся маркеры порядка перехода. Щелкая мышью по элементам, можно установить порядок получения ими фокуса ввода по клавише Tab. Отметьте для себя, что надписи Static Text в своих свойствах имеют отключенное значение Tabstop, поэтому хоть и маркируются в этом режиме, но реально в получении фокуса ввода не участвуют. После проведенных действий снимите опцию Format/Tab Order через меню или просто щелкните по незанятому месту формы.
  • Установка и проверка мнемоники

  • Задайте мнемонику на основных элементах проектируемого окна

    Мнемоника - это механизм назначения комбинаций клавиш быстрого доступа к выполнению элементов управления, включая и пункты меню. Мнемоника означает подчеркнутый символ в надписи элемента. Для определения мнемоники в свойстве Caption управляющего элемента помещают перед символом, который нужно сделать мнемоникой. Важно соблюдать, чтобы каждая мнемоника была уникальна, то есть не использовалась бы более одного раза в одном и том же диалоговом окне или меню.

  • Для проверки непротиворечивости мнемоники выполните действие Check Mnemonics через контекстное меню формы или главное меню Format/Check Mnemonics. Если имееются конфликты символов мнемоники, то оболочка выдаст предупреждение.
  • Добавление кода в приложение

    Мы выполнили этап визуального проектирования интерфейса пользователя для нашего приложения. Все, что мы делали, дизайнер вносил в виде кода в файл ресурсов. Пришла пора дабавить код в файлы самого приложения на языке C++. Именно этот код обеспечит функциональные возможности элементов управления в соответствии с нашим замыслом.

    Связывание переменных и элементов управления

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

    Для объявления ассоциированных переменных и связи их с элементами управления лучше использовать мастер Add Member Variable Wizard, но можно добавить переменные и вручную в объявлении класса CControlsDlg заголовочного файла ControlsDlg.h.

  • Выделить элемент управления, с которым нужно связать переменную. Это можно сделать щелчком на элементе или в меню Properties через раскрывающийся список, если помнить значение идентификатора ID элемента управления.
  • Через главное меню оболочки выбрать опцию
  • Выделяя последовательно элементы
  • IDC_MSG (Edit Control)
  • IDC_COMBO_RUN (Combo Box)
  • IDC_ENABLE_MSG (Check Box)
  • IDC_ENABLE_PROGRAM (Check Box)
  • IDC_SHOWS_MSG (Check Box)
  • IDC_SHOWS_PROGRAM (Check Box) для каждого из них заполните поля мастера как указано в таблице
  • При этом флажок Control variable мастера должен быть включен для всех элементов. Имена переменным присваиваются в соответствии с венгерской нотацией.

    Переменные для элементов управления
    Control ID: Идентификатор Variable name: Имя переменной Category: Категория Variable type: Тип переменной Access: Доступ Comment: Комментарии
    IDC_MSG m_strMessage Value CString public Простое поле редактирования для ввода сообщений
    IDC_COMBO_RUN m_strRun Value CString public Список программ запуска
    IDC_ENABLE_MSG m_bEnableMsg Value BOOL public Поле ввода сообщений доступно
    IDC_ENABLE_PROGRAM m_bEnableProgram Value BOOL public Список выполнения программ доступен
    IDC_SHOWS_MSG m_bShowsMsg Value BOOL public Поле ввода сообщений видно
    IDC_SHOWS_PROGRAM m_bShowsProgram Value BOOL public Список выполнения программ виден
  • Убедитесь, что фактически через мастер мы добавили код в объявление класса, его функцию-конструктор и функцию обмена данными между элементами и переменными.
    Изменения в объявлении класса CControlsDlg файла ControlsDlg.h
    // CControlsDlg dialog
    class CControlsDlg : public CDialog
    {
    // Construction
    public:
      CControlsDlg(CWnd* pParent = NULL);  // standard constructor
    
    // Dialog Data
      enum { IDD = IDD_CONTROLS_DIALOG };
    
      protected:
      virtual void DoDataExchange(CDataExchange* pDX);  // DDX/DDV support
    
    
    // Implementation
    protected:
      HICON m_hIcon;
    
      // Generated message map functions
      virtual BOOL OnInitDialog();
      afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
      afx_msg void OnPaint();
      afx_msg HCURSOR OnQueryDragIcon();
      DECLARE_MESSAGE_MAP()
    public:
      // Простое поле редактирования для ввода сообщений
      CString m_strMessage;
      // Список программ запуска
      CString m_strRun;
      // Поле ввода сообщений доступно
      BOOL m_bEnableMsg;
      // Список выполнения программ доступен
      BOOL m_bEnableProgram;
      // Поле ввода сообщений видно
      BOOL m_bShowsMsg;
      // Список выполнения программ виден
      BOOL m_bShowsProgram;
    };
    Инициализация переменных через заголовок конструктора класса CControlsDlg в файле ControlsDlg.cpp
    CControlsDlg::CControlsDlg(CWnd* pParent /*=NULL*/)
      : CDialog(CControlsDlg::IDD, pParent)
      , m_strMessage(_T(""))
      , m_strRun(_T(""))
      , m_bEnableMsg(FALSE)
      , m_bEnableProgram(FALSE)
      , m_bShowsMsg(FALSE)
      , m_bShowsProgram(FALSE)
    {
      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    Связывание элементов управления диалогового окна приложения 
    с введенными переменными в функции обмена данными класса CControlsDlg 
    в файле ControlsDlg.cppvoid CControlsDlg::DoDataExchange(CDataExchange* pDX)
    {
      CDialog::DoDataExchange(pDX);
      DDX_Text(pDX, IDC_MSG, m_strMessage);
      DDX_CBString(pDX, IDC_COMBO_RUN, m_strRun);
      DDX_Check(pDX, IDC_ENABLE_MSG, m_bEnableMsg);
      DDX_Check(pDX, IDC_ENABLE_PROGRAM, m_bEnableProgram);
      DDX_Check(pDX, IDC_SHOWS_MSG, m_bShowsMsg);
      DDX_Check(pDX, IDC_SHOWS_PROGRAM, m_bShowsProgram);
    }
  • Инициализация элементов управления

  • Выполните установку начальных состояний элементов управления

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

  • Через панель Solution Explorer откройте файл ControlsDlg.cpp
  • Вверху появившегося окна редактирования в левом раскрывающемся списке выберите класс CControlsDlg, а в правом списке - функцию OnInitDialog()
  • Эта функция автоматически выполняется сразу же после создания диалогового окна, ассоциированного с классом CControlsDlg. Раскрывающиеся списки редактора кода позволяют быстро позиционироваться к месту описания нужной функции-члена класса в открытом файле.

  • Внесите код инициализации в функцию как показано ниже Код инициализации переменных, ассоциированных с элементами управления, в функции
    CControlsDlg::OnInitDialog() файла ControlsDlg.cpp
    BOOL CControlsDlg::OnInitDialog()
    {
      CDialog::OnInitDialog();
    
      // Add "About..." menu item to system menu.
    
      // IDM_ABOUTBOX must be in the system command range.
      ASSERT((IDM_ABOUTBOX  0xFFF0) == IDM_ABOUTBOX);
      ASSERT(IDM_ABOUTBOX < 0xF000);
    
      CMenu* pSysMenu = GetSystemMenu(FALSE);
      if (pSysMenu != NULL)
      {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
          pSysMenu->AppendMenu(MF_SEPARATOR);
          pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
      }
    
      // Set the icon for this dialog.  The framework does this automatically
      //  when the application's main window is not a dialog
      SetIcon(m_hIcon, TRUE);      // Set big icon
      SetIcon(m_hIcon, FALSE);    // Set small icon
    
      // TODO: Add extra initialization here
      
      // Поместить заданное по умолчанию значение
      // в поле редактирования Edit Control
      m_strMessage = "Привет студентам!!!";
      
      // Установить все флажки
      m_bEnableMsg = TRUE;
      m_bEnableProgram = TRUE;
      m_bShowsMsg = TRUE;
      m_bShowsProgram = TRUE;
      
      // FALSE - передать значения из переменных в элементы управления
      // TRUE - передать значения из элементов управления в переменные
      UpdateData(FALSE);
      
      return TRUE;  // return TRUE  unless you set the focus to a control
    }
  • Закрытие приложения

  • Добавьте обработчик события кнопки "Выход" (идентификатор элемента управления IDC_EXIT )
  • Это можно сделать двумя способами:

  • Выделить кнопку "Выход", открыть панель Properties и в ее панели инструментов, расположенной в верхней части, выбрать пиктограмму Control Events. Выбрать событие BN_CLICKED и в раскрывающемся списке поля добавить функцию-обработчик OnBnClickedExit() или дважды щелкнуть на имени события.
  • Дважды щелкнуть по кнопке "Выход".
  • Введите код в функцию-обработчик
    Обработчик события BN_CLICKED файла ControlsDlg.cpp
    void CControlsDlg::OnBnClickedExit()
    {
      // TODO: Add your control notification handler code here
      
      OnOK(); // Вызов функции закрытия окна
          // базового класса CDialog
    }
  • Поскольку проектируемое диалоговое окно - главное окно приложения, то его закрытие приведет к закрытию всего приложения.

    Обратите внимание, что при создании обработчика событий в таблице сообщений класса CControlsDlg появилась связка

    Связка элемента управления IDC_EXIT с обработчиком в таблице сообщений файла ControlsDlg.cpp 
    BEGIN_MESSAGE_MAP(CControlsDlg, CDialog)
      ON_WM_SYSCOMMAND()
      ON_WM_PAINT()
      ON_WM_QUERYDRAGICON()
      //}}AFX_MSG_MAP
      ON_BN_CLICKED(IDC_EXIT, OnBnClickedExit)
    END_MESSAGE_MAP()

    В раскрывающемся списке методов класса добавилась новая функция-обработчик OnBnClickedExit(), а в объявлении класса появился ее прототип

    Прототип функции-обработчика, добавленный в объявление класса CControlsDlg файла ControlsDlg.h
    // CControlsDlg dialog
    class CControlsDlg : public CDialog
    {
      ....
      afx_msg void OnBnClickedExit();
    };

    Отображение пользовательского сообщения

  • Добавьте обработчик события кнопки "Отобразить сообщение" (идентификатор элемента управления IDC_SHOW_MSG )
  • Для создания обработчика дважды щелкните на кнопке и наполните обработчик следующим кодом
    Обработчик кнопки "Отобразить сообщение" файла ControlsDlg.cpp
    void CControlsDlg::OnBnClickedShowMsg()
    {
      // TODO: Add your control notification handler code here
      
      // Передать видимое на экране значение поля ввода в переменную
      UpdateData(TRUE);
      
      // Отобразить сообщение для пользователя
      MessageBox(m_strMessage);
    }
  • Очистка поля ввода пользовательского сообщения

  • Обработайте кнопку "Очистить сообщение"
    Обработчик кнопки "Очистить сообщение" файла ControlsDlg.cpp
    void CControlsDlg::OnBnClickedClearMsg()
    {
      // TODO: Add your control notification handler code here
      
      // Очистить сообщение
      m_strMessage = "";
    
      // Обновить экран
      UpdateData(FALSE);
    }
  • Фактически в обработчике мы присвоим переменной m_strMessage пустую строку.

    Восстановление сообщения

  • Обработайте кнопку "Сообщение по умолчанию"
    Обработчик кнопки "Сообщение по умолчанию" файла ControlsDlg.cpp
    void CControlsDlg::OnBnClickedClearMsg()
    {
      // TODO: Add your control notification handler code here
      
      // Задать сообщение по умолчанию
      m_strMessage = "Привет студентам от Снеткова!";
    
      // Обновить экран
      UpdateData(FALSE);
    }
  • Управление доступностью и видимостью инструментов приложения

    Закрепим за флажками возможность блокировать или скрывать закрепленные за ними инструменты. Для этого воспользуемся методами базового класса CWnd. Будем иметь в виду, что любой элемент управления на этапе проектирования приложения является ресурсом, а после компиляции представляет собой обычное окно Windows, созданное на базе MFC -класса CWnd. Это позволяет управлять элементами управления программно через методы базового класса CWnd, в частности

  • GetDlgItem() - возвращает указатель на дочернее окно, коим является элемент управления. Данному методу передается идентификатор дочернего окна.
  • EnableWindow() - включает или отключает возможность взаимодействовать с окном. Передается ненулевой или нулевой аргумент.
  • ShowWindow() - позволяет отобразить или скрыть окно. Передается ненулевой или нулевой аргумент.
  • Создайте для каждого флажка обработчики событий BN_CLICKED и наполните их кодом, как показано в листингах ниже
    Обработчик флажка "Разрешить сообщения" файла ControlsDlg.cpp
    // Доступность блока сообщений
    void CControlsDlg::OnBnClickedEnableMsg()
    {
      // Получить текущие значения от экрана
      UpdateData(TRUE);
        
      if(m_bEnableMsg == TRUE){ // Флажок "Разрешить сообщение" установлен
        // Включить все элементы управления,
        // имеющие отношение к отображению сообщений
        GetDlgItem(IDC_STATIC_MSG)->EnableWindow(TRUE);  // надпись "Ввести сообщение"
        GetDlgItem(IDC_MSG)->EnableWindow(TRUE);    // поле ввода
        GetDlgItem(IDC_SHOW_MSG)->EnableWindow(TRUE);  // кнопка "Отобразить сообщение"
        GetDlgItem(IDC_DEFAULT_MSG)->EnableWindow(TRUE);// кнопка "Сообщение по умолчанию"
        GetDlgItem(IDC_CLEAR_MSG)->EnableWindow(TRUE);  // кнопка "Очистить сообщение"
      }
      else{
        // Выключить все элементы управления,
        // имеющие отношение к отображению сообщений
        CWnd *pWnd;  // Указатель на оконный базовый класс MFC
            // Переменная-указатель локальный внутри блока кода else
      
        pWnd = GetDlgItem(IDC_STATIC_MSG);
        pWnd->EnableWindow(FALSE);  // надпись "Ввести сообщение"
      
        pWnd = GetDlgItem(IDC_MSG);
        pWnd->EnableWindow(FALSE);  // поле ввода
        
        pWnd = GetDlgItem(IDC_SHOW_MSG);
        pWnd->EnableWindow(FALSE);  // кнопка "Отобразить сообщение"
      
        pWnd = GetDlgItem(IDC_DEFAULT_MSG);
        pWnd->EnableWindow(FALSE);  // кнопка "Сообщение по умолчанию"
      
        pWnd = GetDlgItem(IDC_CLEAR_MSG);
        pWnd->EnableWindow(FALSE);  // кнопка "Очистить сообщение"
      }
    }
    Обработчик флажка "Разрешить выполнение" файла ControlsDlg.cpp
    // Доступность блока выполнения
    void CControlsDlg::OnBnClickedEnableProgram()
    {
      // Получить текущие значения от экрана
      UpdateData(TRUE);
      CWnd *pWnd;  // Указатель на оконный базовый класс MFC
          // Переменная-указатель локальный внутри функции
      
      if(m_bEnableProgram == TRUE){ // Флажок "Разрешить выполнение" установлен
        // Включить все элементы управления,
        // имеющие отношение к отображению выполнений
        pWnd = GetDlgItem(IDC_STATIC_PROGRAM);
        pWnd->EnableWindow(TRUE);  // надпись "Запустить программу"
      
        pWnd = GetDlgItem(IDC_COMBO_RUN);
        pWnd->EnableWindow(TRUE);  // раскрывающийся список
      
        pWnd = GetDlgItem(IDC_RUN);
        pWnd->EnableWindow(TRUE);  // кнопка "Выполнить"
      }
      else{
        // Выключить все элементы управления,
        // имеющие отношение к отображению выполнений
        GetDlgItem(IDC_STATIC_PROGRAM)->EnableWindow(0);// надпись "Запустить программу"
        GetDlgItem(IDC_COMBO_RUN)->EnableWindow(0);  // раскрывающийся список
        GetDlgItem(IDC_RUN)->EnableWindow(0);    // кнопка "Выполнить"
      }
    }
    Обработчик флажка "Отображать сообщения" файла ControlsDlg.cpp
    // Отобразить - скрыть блок сообщений
    void CControlsDlg::OnBnClickedShowsMsg()
    {
      // Получить текущие значения от экрана
      UpdateData(TRUE);  
      
      if(m_bShowsMsg == TRUE){ // Флажок "Отображать сообщения" установлен
        // Нарисовать все элементы управления,
        // имеющие отношение к отображению сообщений
        GetDlgItem(IDC_STATIC_MSG)->ShowWindow(TRUE);  // надпись "Ввести сообщение"
        GetDlgItem(IDC_MSG)->ShowWindow(TRUE);    // поле ввода
        GetDlgItem(IDC_SHOW_MSG)->ShowWindow(TRUE);  // кнопка "Отобразить сообщение"
        GetDlgItem(IDC_DEFAULT_MSG)->ShowWindow(TRUE);  // кнопка "Сообщение по умолчанию"
        GetDlgItem(IDC_CLEAR_MSG)->ShowWindow(TRUE);  // кнопка "Очистить сообщение"
      }
      else{
        // Скрыть все элементы управления,
        // имеющие отношение к отображению сообщений
        GetDlgItem(IDC_STATIC_MSG)->ShowWindow(FALSE);  // надпись "Ввести сообщение"
        GetDlgItem(IDC_MSG)->ShowWindow(FALSE);    // поле ввода
        GetDlgItem(IDC_SHOW_MSG)->ShowWindow(FALSE);  // кнопка "Отобразить сообщение"
        GetDlgItem(IDC_DEFAULT_MSG)->ShowWindow(FALSE);  // кнопка "Сообщение по умолчанию"
        GetDlgItem(IDC_CLEAR_MSG)->ShowWindow(FALSE);  // кнопка "Очистить сообщение"
      }
    }
    Обработчик флажка "Отображать выполнение" файла ControlsDlg.cpp
    // Отобразить - скрыть блок выполнения
    void CControlsDlg::OnBnClickedShowsProgram()
    {
      // Получить текущие значения от экрана
      UpdateData(TRUE);
        
      if(m_bShowsProgram == TRUE){ // Флажок "Отображать выполнение" установлен
        // Нарисовать все элементы управления,
        // имеющие отношение к отображению выполнений
        GetDlgItem(IDC_STATIC_PROGRAM)->ShowWindow(TRUE);  // надпись "Запустить программу"
        GetDlgItem(IDC_COMBO_RUN)->ShowWindow(TRUE);    // раскрывающийся список
        GetDlgItem(IDC_RUN)->ShowWindow(TRUE);      // кнопка "Выполнить"
      }
      else{
        // Скрыть все элементы управления,
        // имеющие отношение к отображению выполнений
        GetDlgItem(IDC_STATIC_PROGRAM)->ShowWindow(FALSE);  // надпись "Запустить программу"
        GetDlgItem(IDC_COMBO_RUN)->ShowWindow(FALSE);    // раскрывающийся список
        GetDlgItem(IDC_RUN)->ShowWindow(FALSE);      // кнопка "Выполнить"
      }
    }
  • Постройте приложение и убедитесь, что флажки работают как и было задумано
  • Управление раскрывающимся списком

    На этапе проектирования мы внесли в список имена трех программ. Обратите внимание, что при запуске нашего приложения поле списка пустое до тех пор, пока его не раскрыть и не сделать выбор. Исправим это:

  • Выделите на форме элемент управления Combo Box, который имеет идентификатор IDC_COMBO_RUN
  • В контекстном меню вызовите мастер добавления переменной и настройте его как показано на рисунке
  • Мастер добавит в описание класса CControlsDlg файла ControlsDlg.h код

    Изменения в объявлении класса CControlsDlg файла ControlsDlg.h, 
    добавленные мастером при создании переменной для управления списком
    // CControlsDlg dialog
    class CControlsDlg : public CDialog
    {
      ...............
      afx_msg void OnBnClickedExit();
      afx_msg void OnBnClickedShowMsg();
      afx_msg void OnBnClickedClearMsg();
      afx_msg void OnBnClickedDefaultMsg();
      afx_msg void OnBnClickedEnableMsg();
      afx_msg void OnBnClickedEnableProgram();
      afx_msg void OnBnClickedShowsMsg();
      afx_msg void OnBnClickedShowsProgram();
      // Переменная для управления раскрывающимся списком
      CComboBox m_lstCombo;
    };

    В файл ControlsDlg.cpp мастер добавит код для обеспечения механизма обмена данными между программой и экраном

    Изменения в файле ControlsDlg.cpp, добавленные мастером для обмена данными кода и списка
    void CControlsDlg::DoDataExchange(CDataExchange* pDX)
    {
      CDialog::DoDataExchange(pDX);
      DDX_Text(pDX, IDC_MSG, m_strMessage);
      DDX_CBString(pDX, IDC_COMBO_RUN, m_strRun);
      DDX_Check(pDX, IDC_ENABLE_MSG, m_bEnableMsg);
      DDX_Check(pDX, IDC_ENABLE_PROGRAM, m_bEnableProgram);
      DDX_Check(pDX, IDC_SHOWS_MSG, m_bShowsMsg);
      DDX_Check(pDX, IDC_SHOWS_PROGRAM, m_bShowsProgram);
      DDX_Control(pDX, IDC_COMBO_RUN, m_lstCombo);
    }

    Мы хотим, чтобы при запуске приложения список устанавливался в первую позицию (нумерация элементов списка начинается с нуля), поэтому

  • Добавьте код в функцию инициализации
    Код установки начальной позиции раскрывающегося списка
    BOOL CControlsDlg::OnInitDialog()
    {
      .............
      // TODO: Add extra initialization here
      
      // Установить список в начало
      m_lstCombo.SetCurSel(0);
      UpdateData(TRUE);  // скачать из списка в переменную m_strRun
      
      // Поместить заданное по умолчанию значение
      // в поле редактирования Edit Control
      m_strMessage = "Привет студентам!!!";
        
      // Установить все флажки
      m_bEnableMsg = TRUE;
      m_bEnableProgram = TRUE;
      m_bShowsMsg = TRUE;
      m_bShowsProgram = TRUE;
      
      // FALSE - передать значения из переменных в элементы управления
      // TRUE - передать значения из элементов управления в переменные
      UpdateData(FALSE);
      
      return TRUE;  // return TRUE  unless you set the focus to a control
    }
  • Постройте проект и убедитесь, что код работает
  • Запуск внешних приложений

    Обработаем кнопку "Выполнить", которая позволит запускать на выполнение внешние программы. При нажатии кнопки код обработчика должен извлечь имя внешней программы из поля раскрывающегося списка и с помощью соответствующей API-функции запустить процесс выполнения.

    Для запуска внешних приложений существуют функции

  • WinExec()
  • ShellExecute()
  • CreateProcess()
  • execlp()
  • spawnlp()
  • Ознакомимся только с функцией WinExec(). Эта функция может работать в любых версиях Windows и выполнять любые файлы. Функция работает асинхронно, т.е. после запуска внешнего приложения не ждет его закрытия. Функции, которые ждут завершения запущенного ими процесса, работают синхронно.

    Заголовок функции WinExec()
    UINT WinExec(
      LPCSTR lpCmdLine,
      UINT uCmdShow
    );

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

  • Каталог, из которого загружено вызывающее приложение
  • Текущий каталог
  • Системный каталог Windows, возвращаемый API -функцией GetSystemDirectory()
  • Каталог Windows, возвращаемый API -функцией GetWindowsDirectory()
  • Список каталогов из переменной окружения PATH
  • Параметр uCmdShow определяет форму представления окна запускаемого приложения и может иметь значения

    Значение uCmdShow Описание
    SW_HIDE Окно делается невидимым и фокус передается другому окну
    SW_MAXIMIZE Развертывает окно
    SW_MINIMIZE Свертывает окно, активизируя следующее в Z -последовательности окно верхнего уровня в списке системы
    SW_RESTORE Активизирует и отображает окно с первоначальными параметрами
    SW_SHOW Активизирует и отображает окно с текущими параметрами
    SW_SHOWDEFAULT Устанавливает состояние окна в соответствии с флагом SW_ в структуре STARTUPINFO
    SW_SHOWMAXIMIZED Активизирует и отображает окно в развернутом виде
    SW_SHOWMINIMIZED Активизирует и отображает окно в виде пиктограммы в панели задач
    SW_SHOWMINNOACTIVE Отображает окно в свернутом виде, оставляя активным предыдущее окно
    SW_SHOWNA Отображает окно в его текущей позиции и текущими размерами, не передавая фокус. Активным остается то окно, которое было активным до этого
    SW_SHOWNOACTIVATE Отображает окно в его последней позиции и с последними размерами. Активным остается то окно, которое было активным до этого
    SW_SHOWNORMAL Активизирует и отображает окно, восстанавливая его до первоначальных размеров и в первоначальной позиции

    Функция WinExec() возвращает беззнаковое целое, свидетельствующее об успехе или ошибке. Если возвращаемое значение меньше или равно 31, то это указывает на ошибку.

    Именованная константа Значение Описание
    0 0 Системе не хватает памяти, выполняемый файл испорчен или произошло ошибочное перераспределение памяти
    ERROR_BAD_FORMAT 11 Плохой исполняемый файл. Или это не приложение Windows, или ошибка в .exe файле
    ERROR_FILE_NOT_FOUND 2 Файл не найден
    ERROR_PATH_NOT_FOUND 3 Путь не найден
  • Обработайте кнопку "Выполнить" следующим кодом
    Обработчик нажатия на кнопку "Выполнить"
    void CControlsDlg::OnBnClickedRun()
    {
      // Передать текущие значения элементов управления в переменные
      UpdateData(TRUE);
      // Объявить локальную переменную для хранения названия программы
      CString strName;
      // Копировать текущее поле списка в локальную переменную
      strName = m_strRun;
      // Перевести название программы в верхний регистр
      strName.MakeUpper();
      int error = WinExec(strName, SW_RESTORE);
      switch(error){
        case 0:
          MessageBox( "Не хватает памяти или ресурсов!",
                "Ошибка!", MB_OK | MB_ICONINFORMATION );
          break;
    
        case ERROR_BAD_FORMAT:
          MessageBox( "Ошибочный файл!",
                "Ошибка!", MB_OK | MB_ICONINFORMATION );
          break;
    
        case ERROR_FILE_NOT_FOUND:
          MessageBox( "Файл не найден!",
                "Ошибка!", MB_OK | MB_ICONINFORMATION );
          break;
    
        case ERROR_PATH_NOT_FOUND:
          MessageBox( "Путь не найден!",
                "Ошибка!", MB_OK | MB_ICONINFORMATION );
      }
    }
  • Постройте приложение и убедитесь в его работоспособности
  • Страницы:
    Файлы к данной лабораторной работе, Вы можете скачать здесь.

    Оболочка содержит большинство управляющих элементов управления в готовом виде. Визуальный способ проектирования диалоговых панелей обеспечивает удобство и скорость для разработчика. Компоненты управляющих элементов содержатся в виде пиктограмм на панели Toolbox, вызываемой через главное меню оболочки View. Панель имеет три вкладки, нас интересует вкладка Dialog Editor. Если пиктограммы компонентов не помещаются в панели, то вверху и внизу по правой стороне существуют кнопки прокрутки.

    Перенести компоненты управляющих элементов можно тремя способами:

  • Двойной щелчок на пиктограмме компонента.
  • Перетаскивание мышью.
  • Выделение компонента на пиктограмме, затем выделение его места размещения на форме диалогового окна щелчком.
  • Выделение компонента на пиктограмме, затем растягивание контура компонента на форме.
  • Каждому элементу управления, представленному на визуальной панели компонентов, соответствует класс библиотеки MFC. Любой из этих классов является потомком базового класса CWnd, поэтому представляет собой окно Windows.

    Ресурс каждого элемента управления должен иметь внутри формы диалогового окна уникальный идентификатор. Его можно назначать самому через панель свойств Properties, задавая в поле ID элемента мнемоническое значение или вибирая из раскрывающегося списка того же поля заготовленные имена. В любом случае рекомендуется соблюдать соглашения о префиксах: идентификаторы диалоговых окон имеют префикс $$IDD_$$, а идентификаторы элементов управления - префикс $$IDC_$$ .

    Цель работы

  • Изучить основные элементы управления диалоговых приложений.
  • Научиться объявлять переменные для компонентов и связывать их с самими компонентами.
  • Научиться синхронизировать значения между самими элементами управления и представляющими их в программе переменными.
  • Научиться задавать порядок получения фокуса ввода между элементами управления.
  • Научиться инициировать действия с помощью элементов управления.
  • Научиться задавать внешний вид элементов управления и изменять его во время выполнения приложения.
  • Изучаемые элементы управления

    Рассмотрим некоторый элементы управления, а именно:

  • Static Text - статический текст
  • Edit Control - поле редактирования
  • Button - кнопка
  • Check Box - флажок
  • Radio Button - радиокнопка
  • Combo Box - поле ввода со списком
  • Static Text - статический текст

    Этот элемент служит для отображения текста и не обеспечивает интерактивность (взаимодействие с пользователем), поэтому список событий у него пустой. Но можно заменять текст в процессе выполнения приложения, воздействуя на его свойство Caption.

    Основные свойства элемента управления Static Text
    Свойство Описание
    ID Идентифицирует элемент управления. Значение по умолчанию всегда IDC_STATIC
    Caption Определяет текст в элементе управления
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Надпись заблокированного элемента отображается серым текстом
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab
    Client Edge Включает рамку элемента управления
    Align Text Задает выравнивание текста внутри окна элемента
    Border Показывает рамку вокруг элемента
    Transparent Включает прозрачный фон окна компонента
    CStatic - класс поддержки в MFC

    Edit Control - поле редактирования

    Этот элемент управления позволяет получить от пользователя текстовую информацию. Окно воспринимает только простой текст с минимальными возможностями редактирования.

    Основные свойства элемента управления Edit Control
    Свойство Описание
    ID Идентифицирует элемент управления
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Надпись заблокированного элемента отображается серым текстом.
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления
    Align Text Задает выравнивание текста внутри окна элемента
    Border Показывает рамку вокруг элемента
    Transparent Включает прозрачный фон окна компонента
    Number Задает фильтр ввода "только для чисел"
    Password Эхо ввода заменяет символом *
    Multiline Включает возможность ввода нескольких строк
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    OEM Convert Включает автоматическую конвертацию кодировки CharToOem
    Uppercase Включает автоматическое преобразование в заглавные буквы (работает совместно с Lowercase как радиокнопка)
    Lowercase Включает автоматическое преобразование в строчные буквы (работает совместно с Uppercase как радиокнопка)
    Read Only Только для чтения - блокирует ввод
    CEdit - класс поддержки в MFC

    Button - кнопка

    Основные свойства элемента управления Button
    Свойство Описание
    ID Идентифицирует элемент управления
    Caption Определяет текст в элементе управления.
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Надпись заблокированного элемента отображается серым текстом.
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления.
    Horizontal Alignment Задает выравнивание текста внутри окна элемента по горизонтали.
    Vertical Alignment Задает выравнивание текста внутри окна элемента по вертикали
    Transparent Включает прозрачный фон окна компонента
    Multiline Включает возможность ввода нескольких строк
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    Static Edge Включает рамку элемента управления без выпуклого представления
    Default Button Задает фокус ввода при первом запуске приложения. Отмечает, что эта кнопка будет выполнена при нажатии клавиши Enter.
    CButton - класс поддержки в MFC

    Check Box - флажок

    Дает возможность пользователю включить или выключить некую возможность (опцию). Возможны флажки с промежуточным - третьим - состоянием.

    Основные свойства элемента управления Check Box
    Свойство Описание
    ID Идентифицирует элемент управления
    Caption Определяет поясняющий текст на элементе управления
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Изображение заблокированного элемента отображается серым
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления
    Horizontal Alignment Задает выравнивание текста внутри окна элемента по горизонтали.
    Vertical Alignment Задает выравнивание текста внутри окна элемента по вертикали
    Tri-state Включает третье состояние disabled (заблокирован). В этом состоянии значение элемента не рассматривается ни как true, ни как false.
    Transparent Включает прозрачный фон окна компонента
    Multiline Включает возможность ввода нескольких строк
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    Static Edge Включает рамку элемента управления без выпуклого представления
    Left Text Располагает надписи слева от флажка. При значении false надписи располагаются справа от флажка

    Radio Button - радиокнопка

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

    Основные свойства элемента управления Radio Button
    Свойство Описание
    ID Идентифицирует элемент управления.
    Caption Определяет поясняющий текст на элементе управления.
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Изображение заблокированного элемента отображается серым.
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления
    Horizontal Alignment Задает выравнивание текста внутри окна элемента по горизонтали
    Vertical Alignment Задает выравнивание текста внутри окна элемента по вертикали
    Transparent Включает прозрачный фон окна компонента
    Multiline Включает возможность ввода нескольких строк
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    Static Edge Включает рамку элемента управления без выпуклого представления
    Group Определяет первый из элементов управления в группе. Только у первого элемента в группе это свойство должно иметь значение true
    Auto По умолчанию задано значение true, что позволяет переключателю автоматически изменять свое состояние при его выборе пользователем
    Left Text Располагает надписи слева от переключателя. При значении false надписи располагаются справа от переключателя.

    Combo Box - поле ввода со списком

    Предоставляет раскрывающийся список выбора.

    Основные свойства элемента управления Combo Box
    Свойство Описание
    ID Идентифицирует элемент управления
    Visible Включает - выключает видимость элемента во время выполнения ( true - видимый, false - невидимый).
    Disabled Управляет представлением элемента как заблокированного или нет ( false - незаблокированный, true - заблокированный). Изображение заблокированного элемента отображается серым.
    Tabstop Определяет, участвует ли элемент управления в процессе переноса фокуса ввода с помощью клавиши Tab.
    Client Edge Включает рамку элемента управления.
    Modal Frame Включает выпуклое обрамление рамки окна компонента
    Static Edge Включает рамку элемента управления без выпуклого представления
    Group Определяет первый из элементов управления в группе. Только у первого элемента в группе это свойство должно иметь значение true
    Auto По умолчанию задано значение true, что позволяет переключателю автоматически изменять свое состояние при его выборе пользователем
    Sort Определяет, будут ли отсортированы элементы в раскрывающемся списке
    Type Задает тип списка: " Dropdown - раскрывающийся при получении фокуса ввода " Simple - раскрыт все время Drop List - раскрывающийся с изображением текущего элемента списка.
    CComboBox - класс поддержки в MFC

    Класс CComboBox является производным от класса CWnd, но в свою очередь служит базовым классом для класса CComboBoxEx, который предоставляет функции для включения изображений в выбираемые элементы раскрывающегося списка.

    Класс CComboBox предоставляет функции для программного взаимодействия со списком:

  • GetCurSel() - определяет номер текущего пункта списка
  • SetCurSel() - устанавливает текущим элемент с заданным номером
  • SelectString() - выделяет строку
  • FindString() - ищет строку
  • AddString() - добавляет строку в конец списка
  • InsertString() - вставляет строку перед текущей
  • DeleteString() - удаляет текущую строку
  • ResetString() - устанавливает список в исходное состояние
  • Создание заготовки диалогового приложения и визуальная разработка интерфейса

  • Создайте новый проект MFC Application под названием Controls. Задайте именно такое название, чтобы дальше нам разговаривать на одном языке, поскольку мастер приложений при создании заготовки кода использует имя проекта в именах файлов и классов.
  • Выберите настройки мастера MFC Application Wizard как указано в таблице, остальные настройки в указанных вкладках должны быть сброшены. В неуказанных вкладках оставьте настройки по умолчанию.
    Таблица настройки мастера создания каркаса приложения
    Свойство проекта Значение
    Вкладка Application Type
    Application Type Dialog Based
    Resource language: Английский (США)
    Project style: MFC standard
    Use of MFC: Use MFC in a shared DLL
    Вкладка Advanced Features
    Все сбросить!
    Вкладка User Interface Features
    Main frame styles: System menu
    About box
    Dialog title: Controls
  • Создав заготовку приложения с помощью мастера, русифицируйте прежде всего ресурсы узлов
  • Спроектируйте диалоговую форму в соответствии с таблицей свойств.
    Таблица свойств главной диалоговой формы Controls
    Элемент управления Свойство Значение
    --------------------------------------------- 0 --------------------------------------------------
    Главная форма Caption Диалоговое приложение - элементы управления
    Font(Size) MS Sans Serif(10)
    Ширина 240
    Высота 180
    Static Text ID IDC_HEAD
    Caption Это пример приложения на C++ Visual Studio .NET, в котором используется множество разных элементов управления
    Ширина 200
    Высота 16
    --------------------------------------------- 1 --------------------------------------------------
    Static Text ID IDC_STATIC_MSG
    Caption Ввести сообщение
    Right Align Text True
    Ширина 70
    Высота 8
    Edit Control ID IDC_MSG
    Ширина 60
    Высота 14
    Button ID IDC_SHOW_MSG
    Caption Отобразить сообщение
    Ширина 85
    Высота 14
    --------------------------------------------- 2 --------------------------------------------------
    Button ID IDC_DEFAULT_MSG
    Caption Сообщение по умолчанию
    Ширина 90
    Высота 14
    Button ID IDC_CLEAR_MSG
    Caption Очистить сообщение
    Ширина 90
    Высота 14
    --------------------------------------------- 3 --------------------------------------------------
    Static Text ID IDC_STATIC_PROGRAM
    Caption Запустить программу
    Right Align Text True
    Ширина 75
    Высота 8
    Combo Box ID IDC_COMBO_RUN
    Ширина 90
    Высота 12
    Button ID IDC_RUN
    Caption Выполнить
    Ширина 50
    Высота 14
    --------------------------------------------- 4 --------------------------------------------------
    Group Box Caption Действия
    Ширина 110
    Высота 40
    Check Box ID IDC_ENABLE_MSG
    Caption Разрешить сообщения
    Check Box ID IDC_ENABLE_PROGRAM
    Caption Разрешить выполнение
    --------------------------------------------- 5 --------------------------------------------------
    Group Box Caption Отображать
    Ширина 110
    Высота 40
    Check Box ID IDC_SHOWS_MSG
    Caption Отображать сообщения
    Check Box ID IDC_SHOWS_PROGRAM
    Caption Отображать выполнение
    --------------------------------------------- 6 --------------------------------------------------
    Button ID IDC_EXIT
    Caption Выход
  • Задавая размеры элементов, пользуйтесь строкой состояния оболочки. Для выравнивания элементов управления используйте панель инструментов
  • В панели свойств Properties в верхней части раскройте выпадающий список и выделите элемент IDC_COMBO_RUN. Найдите свойство Data (Данные) и введите имена вызываемых программ, разделяя их точкой с запятой
    Notepad;msPaint;Sol
  • Найдите свойство Sort и установите его в состояние True. Такой режим обеспечит автоматическую сортировку элементов списка.
  • Щелкните на стрелке раскрывающегося списка, появится максимальный контур списка в раскрытом состоянии. Переместите нижнюю границу вниз с запасом, чтобы список в раскрытом состоянии имел нужный размер и чтобы точно поместились все его элементы без прокрутки. Отметьте, что если определить высоту, большую чем необходимо, то при выполнении высота раскрытого списка подравнивается под фактическую.
  • Определение последовательности перехода по клавиши табуляции

  • Установите последовательность перехода к элементам окна при нажатии клавиши Tab. Для этого в меню Format оболочки установите опцию Tab Order. На проекте диалогового окна появятся маркеры порядка перехода. Щелкая мышью по элементам, можно установить порядок получения ими фокуса ввода по клавише Tab. Отметьте для себя, что надписи Static Text в своих свойствах имеют отключенное значение Tabstop, поэтому хоть и маркируются в этом режиме, но реально в получении фокуса ввода не участвуют. После проведенных действий снимите опцию Format/Tab Order через меню или просто щелкните по незанятому месту формы.
  • Установка и проверка мнемоники

  • Задайте мнемонику на основных элементах проектируемого окна

    Мнемоника - это механизм назначения комбинаций клавиш быстрого доступа к выполнению элементов управления, включая и пункты меню. Мнемоника означает подчеркнутый символ в надписи элемента. Для определения мнемоники в свойстве Caption управляющего элемента помещают перед символом, который нужно сделать мнемоникой. Важно соблюдать, чтобы каждая мнемоника была уникальна, то есть не использовалась бы более одного раза в одном и том же диалоговом окне или меню.

  • Для проверки непротиворечивости мнемоники выполните действие Check Mnemonics через контекстное меню формы или главное меню Format/Check Mnemonics. Если имееются конфликты символов мнемоники, то оболочка выдаст предупреждение.
  • Добавление кода в приложение

    Мы выполнили этап визуального проектирования интерфейса пользователя для нашего приложения. Все, что мы делали, дизайнер вносил в виде кода в файл ресурсов. Пришла пора дабавить код в файлы самого приложения на языке C++. Именно этот код обеспечит функциональные возможности элементов управления в соответствии с нашим замыслом.

    Связывание переменных и элементов управления

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

    Для объявления ассоциированных переменных и связи их с элементами управления лучше использовать мастер Add Member Variable Wizard, но можно добавить переменные и вручную в объявлении класса CControlsDlg заголовочного файла ControlsDlg.h.

  • Выделить элемент управления, с которым нужно связать переменную. Это можно сделать щелчком на элементе или в меню Properties через раскрывающийся список, если помнить значение идентификатора ID элемента управления.
  • Через главное меню оболочки выбрать опцию
  • Выделяя последовательно элементы
  • IDC_MSG (Edit Control)
  • IDC_COMBO_RUN (Combo Box)
  • IDC_ENABLE_MSG (Check Box)
  • IDC_ENABLE_PROGRAM (Check Box)
  • IDC_SHOWS_MSG (Check Box)
  • IDC_SHOWS_PROGRAM (Check Box) для каждого из них заполните поля мастера как указано в таблице
  • При этом флажок Control variable мастера должен быть включен для всех элементов. Имена переменным присваиваются в соответствии с венгерской нотацией.

    Переменные для элементов управления
    Control ID: Идентификатор Variable name: Имя переменной Category: Категория Variable type: Тип переменной Access: Доступ Comment: Комментарии
    IDC_MSG m_strMessage Value CString public Простое поле редактирования для ввода сообщений
    IDC_COMBO_RUN m_strRun Value CString public Список программ запуска
    IDC_ENABLE_MSG m_bEnableMsg Value BOOL public Поле ввода сообщений доступно
    IDC_ENABLE_PROGRAM m_bEnableProgram Value BOOL public Список выполнения программ доступен
    IDC_SHOWS_MSG m_bShowsMsg Value BOOL public Поле ввода сообщений видно
    IDC_SHOWS_PROGRAM m_bShowsProgram Value BOOL public Список выполнения программ виден
  • Убедитесь, что фактически через мастер мы добавили код в объявление класса, его функцию-конструктор и функцию обмена данными между элементами и переменными.
    Изменения в объявлении класса CControlsDlg файла ControlsDlg.h
    // CControlsDlg dialog
    class CControlsDlg : public CDialog
    {
    // Construction
    public:
      CControlsDlg(CWnd* pParent = NULL);  // standard constructor
    
    // Dialog Data
      enum { IDD = IDD_CONTROLS_DIALOG };
    
      protected:
      virtual void DoDataExchange(CDataExchange* pDX);  // DDX/DDV support
    
    
    // Implementation
    protected:
      HICON m_hIcon;
    
      // Generated message map functions
      virtual BOOL OnInitDialog();
      afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
      afx_msg void OnPaint();
      afx_msg HCURSOR OnQueryDragIcon();
      DECLARE_MESSAGE_MAP()
    public:
      // Простое поле редактирования для ввода сообщений
      CString m_strMessage;
      // Список программ запуска
      CString m_strRun;
      // Поле ввода сообщений доступно
      BOOL m_bEnableMsg;
      // Список выполнения программ доступен
      BOOL m_bEnableProgram;
      // Поле ввода сообщений видно
      BOOL m_bShowsMsg;
      // Список выполнения программ виден
      BOOL m_bShowsProgram;
    };
    Инициализация переменных через заголовок конструктора класса CControlsDlg в файле ControlsDlg.cpp
    CControlsDlg::CControlsDlg(CWnd* pParent /*=NULL*/)
      : CDialog(CControlsDlg::IDD, pParent)
      , m_strMessage(_T(""))
      , m_strRun(_T(""))
      , m_bEnableMsg(FALSE)
      , m_bEnableProgram(FALSE)
      , m_bShowsMsg(FALSE)
      , m_bShowsProgram(FALSE)
    {
      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    Связывание элементов управления диалогового окна приложения 
    с введенными переменными в функции обмена данными класса CControlsDlg 
    в файле ControlsDlg.cppvoid CControlsDlg::DoDataExchange(CDataExchange* pDX)
    {
      CDialog::DoDataExchange(pDX);
      DDX_Text(pDX, IDC_MSG, m_strMessage);
      DDX_CBString(pDX, IDC_COMBO_RUN, m_strRun);
      DDX_Check(pDX, IDC_ENABLE_MSG, m_bEnableMsg);
      DDX_Check(pDX, IDC_ENABLE_PROGRAM, m_bEnableProgram);
      DDX_Check(pDX, IDC_SHOWS_MSG, m_bShowsMsg);
      DDX_Check(pDX, IDC_SHOWS_PROGRAM, m_bShowsProgram);
    }
  • Инициализация элементов управления

  • Выполните установку начальных состояний элементов управления

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

  • Через панель Solution Explorer откройте файл ControlsDlg.cpp
  • Вверху появившегося окна редактирования в левом раскрывающемся списке выберите класс CControlsDlg, а в правом списке - функцию OnInitDialog()
  • Эта функция автоматически выполняется сразу же после создания диалогового окна, ассоциированного с классом CControlsDlg. Раскрывающиеся списки редактора кода позволяют быстро позиционироваться к месту описания нужной функции-члена класса в открытом файле.

  • Внесите код инициализации в функцию как показано ниже Код инициализации переменных, ассоциированных с элементами управления, в функции
    CControlsDlg::OnInitDialog() файла ControlsDlg.cpp
    BOOL CControlsDlg::OnInitDialog()
    {
      CDialog::OnInitDialog();
    
      // Add "About..." menu item to system menu.
    
      // IDM_ABOUTBOX must be in the system command range.
      ASSERT((IDM_ABOUTBOX  0xFFF0) == IDM_ABOUTBOX);
      ASSERT(IDM_ABOUTBOX < 0xF000);
    
      CMenu* pSysMenu = GetSystemMenu(FALSE);
      if (pSysMenu != NULL)
      {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
          pSysMenu->AppendMenu(MF_SEPARATOR);
          pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
      }
    
      // Set the icon for this dialog.  The framework does this automatically
      //  when the application's main window is not a dialog
      SetIcon(m_hIcon, TRUE);      // Set big icon
      SetIcon(m_hIcon, FALSE);    // Set small icon
    
      // TODO: Add extra initialization here
      
      // Поместить заданное по умолчанию значение
      // в поле редактирования Edit Control
      m_strMessage = "Привет студентам!!!";
      
      // Установить все флажки
      m_bEnableMsg = TRUE;
      m_bEnableProgram = TRUE;
      m_bShowsMsg = TRUE;
      m_bShowsProgram = TRUE;
      
      // FALSE - передать значения из переменных в элементы управления
      // TRUE - передать значения из элементов управления в переменные
      UpdateData(FALSE);
      
      return TRUE;  // return TRUE  unless you set the focus to a control
    }
  • Закрытие приложения

  • Добавьте обработчик события кнопки "Выход" (идентификатор элемента управления IDC_EXIT )
  • Это можно сделать двумя способами:

  • Выделить кнопку "Выход", открыть панель Properties и в ее панели инструментов, расположенной в верхней части, выбрать пиктограмму Control Events. Выбрать событие BN_CLICKED и в раскрывающемся списке поля добавить функцию-обработчик OnBnClickedExit() или дважды щелкнуть на имени события.
  • Дважды щелкнуть по кнопке "Выход".
  • Введите код в функцию-обработчик
    Обработчик события BN_CLICKED файла ControlsDlg.cpp
    void CControlsDlg::OnBnClickedExit()
    {
      // TODO: Add your control notification handler code here
      
      OnOK(); // Вызов функции закрытия окна
          // базового класса CDialog
    }
  • Поскольку проектируемое диалоговое окно - главное окно приложения, то его закрытие приведет к закрытию всего приложения.

    Обратите внимание, что при создании обработчика событий в таблице сообщений класса CControlsDlg появилась связка

    Связка элемента управления IDC_EXIT с обработчиком в таблице сообщений файла ControlsDlg.cpp 
    BEGIN_MESSAGE_MAP(CControlsDlg, CDialog)
      ON_WM_SYSCOMMAND()
      ON_WM_PAINT()
      ON_WM_QUERYDRAGICON()
      //}}AFX_MSG_MAP
      ON_BN_CLICKED(IDC_EXIT, OnBnClickedExit)
    END_MESSAGE_MAP()

    В раскрывающемся списке методов класса добавилась новая функция-обработчик OnBnClickedExit(), а в объявлении класса появился ее прототип

    Прототип функции-обработчика, добавленный в объявление класса CControlsDlg файла ControlsDlg.h
    // CControlsDlg dialog
    class CControlsDlg : public CDialog
    {
      ....
      afx_msg void OnBnClickedExit();
    };

    Отображение пользовательского сообщения

  • Добавьте обработчик события кнопки "Отобразить сообщение" (идентификатор элемента управления IDC_SHOW_MSG )
  • Для создания обработчика дважды щелкните на кнопке и наполните обработчик следующим кодом
    Обработчик кнопки "Отобразить сообщение" файла ControlsDlg.cpp
    void CControlsDlg::OnBnClickedShowMsg()
    {
      // TODO: Add your control notification handler code here
      
      // Передать видимое на экране значение поля ввода в переменную
      UpdateData(TRUE);
      
      // Отобразить сообщение для пользователя
      MessageBox(m_strMessage);
    }
  • Очистка поля ввода пользовательского сообщения

  • Обработайте кнопку "Очистить сообщение"
    Обработчик кнопки "Очистить сообщение" файла ControlsDlg.cpp
    void CControlsDlg::OnBnClickedClearMsg()
    {
      // TODO: Add your control notification handler code here
      
      // Очистить сообщение
      m_strMessage = "";
    
      // Обновить экран
      UpdateData(FALSE);
    }
  • Фактически в обработчике мы присвоим переменной m_strMessage пустую строку.

    Восстановление сообщения

  • Обработайте кнопку "Сообщение по умолчанию"
    Обработчик кнопки "Сообщение по умолчанию" файла ControlsDlg.cpp
    void CControlsDlg::OnBnClickedClearMsg()
    {
      // TODO: Add your control notification handler code here
      
      // Задать сообщение по умолчанию
      m_strMessage = "Привет студентам от Снеткова!";
    
      // Обновить экран
      UpdateData(FALSE);
    }
  • Управление доступностью и видимостью инструментов приложения

    Закрепим за флажками возможность блокировать или скрывать закрепленные за ними инструменты. Для этого воспользуемся методами базового класса CWnd. Будем иметь в виду, что любой элемент управления на этапе проектирования приложения является ресурсом, а после компиляции представляет собой обычное окно Windows, созданное на базе MFC -класса CWnd. Это позволяет управлять элементами управления программно через методы базового класса CWnd, в частности

  • GetDlgItem() - возвращает указатель на дочернее окно, коим является элемент управления. Данному методу передается идентификатор дочернего окна.
  • EnableWindow() - включает или отключает возможность взаимодействовать с окном. Передается ненулевой или нулевой аргумент.
  • ShowWindow() - позволяет отобразить или скрыть окно. Передается ненулевой или нулевой аргумент.
  • Создайте для каждого флажка обработчики событий BN_CLICKED и наполните их кодом, как показано в листингах ниже
    Обработчик флажка "Разрешить сообщения" файла ControlsDlg.cpp
    // Доступность блока сообщений
    void CControlsDlg::OnBnClickedEnableMsg()
    {
      // Получить текущие значения от экрана
      UpdateData(TRUE);
        
      if(m_bEnableMsg == TRUE){ // Флажок "Разрешить сообщение" установлен
        // Включить все элементы управления,
        // имеющие отношение к отображению сообщений
        GetDlgItem(IDC_STATIC_MSG)->EnableWindow(TRUE);  // надпись "Ввести сообщение"
        GetDlgItem(IDC_MSG)->EnableWindow(TRUE);    // поле ввода
        GetDlgItem(IDC_SHOW_MSG)->EnableWindow(TRUE);  // кнопка "Отобразить сообщение"
        GetDlgItem(IDC_DEFAULT_MSG)->EnableWindow(TRUE);// кнопка "Сообщение по умолчанию"
        GetDlgItem(IDC_CLEAR_MSG)->EnableWindow(TRUE);  // кнопка "Очистить сообщение"
      }
      else{
        // Выключить все элементы управления,
        // имеющие отношение к отображению сообщений
        CWnd *pWnd;  // Указатель на оконный базовый класс MFC
            // Переменная-указатель локальный внутри блока кода else
      
        pWnd = GetDlgItem(IDC_STATIC_MSG);
        pWnd->EnableWindow(FALSE);  // надпись "Ввести сообщение"
      
        pWnd = GetDlgItem(IDC_MSG);
        pWnd->EnableWindow(FALSE);  // поле ввода
        
        pWnd = GetDlgItem(IDC_SHOW_MSG);
        pWnd->EnableWindow(FALSE);  // кнопка "Отобразить сообщение"
      
        pWnd = GetDlgItem(IDC_DEFAULT_MSG);
        pWnd->EnableWindow(FALSE);  // кнопка "Сообщение по умолчанию"
      
        pWnd = GetDlgItem(IDC_CLEAR_MSG);
        pWnd->EnableWindow(FALSE);  // кнопка "Очистить сообщение"
      }
    }
    Обработчик флажка "Разрешить выполнение" файла ControlsDlg.cpp
    // Доступность блока выполнения
    void CControlsDlg::OnBnClickedEnableProgram()
    {
      // Получить текущие значения от экрана
      UpdateData(TRUE);
      CWnd *pWnd;  // Указатель на оконный базовый класс MFC
          // Переменная-указатель локальный внутри функции
      
      if(m_bEnableProgram == TRUE){ // Флажок "Разрешить выполнение" установлен
        // Включить все элементы управления,
        // имеющие отношение к отображению выполнений
        pWnd = GetDlgItem(IDC_STATIC_PROGRAM);
        pWnd->EnableWindow(TRUE);  // надпись "Запустить программу"
      
        pWnd = GetDlgItem(IDC_COMBO_RUN);
        pWnd->EnableWindow(TRUE);  // раскрывающийся список
      
        pWnd = GetDlgItem(IDC_RUN);
        pWnd->EnableWindow(TRUE);  // кнопка "Выполнить"
      }
      else{
        // Выключить все элементы управления,
        // имеющие отношение к отображению выполнений
        GetDlgItem(IDC_STATIC_PROGRAM)->EnableWindow(0);// надпись "Запустить программу"
        GetDlgItem(IDC_COMBO_RUN)->EnableWindow(0);  // раскрывающийся список
        GetDlgItem(IDC_RUN)->EnableWindow(0);    // кнопка "Выполнить"
      }
    }
    Обработчик флажка "Отображать сообщения" файла ControlsDlg.cpp
    // Отобразить - скрыть блок сообщений
    void CControlsDlg::OnBnClickedShowsMsg()
    {
      // Получить текущие значения от экрана
      UpdateData(TRUE);  
      
      if(m_bShowsMsg == TRUE){ // Флажок "Отображать сообщения" установлен
        // Нарисовать все элементы управления,
        // имеющие отношение к отображению сообщений
        GetDlgItem(IDC_STATIC_MSG)->ShowWindow(TRUE);  // надпись "Ввести сообщение"
        GetDlgItem(IDC_MSG)->ShowWindow(TRUE);    // поле ввода
        GetDlgItem(IDC_SHOW_MSG)->ShowWindow(TRUE);  // кнопка "Отобразить сообщение"
        GetDlgItem(IDC_DEFAULT_MSG)->ShowWindow(TRUE);  // кнопка "Сообщение по умолчанию"
        GetDlgItem(IDC_CLEAR_MSG)->ShowWindow(TRUE);  // кнопка "Очистить сообщение"
      }
      else{
        // Скрыть все элементы управления,
        // имеющие отношение к отображению сообщений
        GetDlgItem(IDC_STATIC_MSG)->ShowWindow(FALSE);  // надпись "Ввести сообщение"
        GetDlgItem(IDC_MSG)->ShowWindow(FALSE);    // поле ввода
        GetDlgItem(IDC_SHOW_MSG)->ShowWindow(FALSE);  // кнопка "Отобразить сообщение"
        GetDlgItem(IDC_DEFAULT_MSG)->ShowWindow(FALSE);  // кнопка "Сообщение по умолчанию"
        GetDlgItem(IDC_CLEAR_MSG)->ShowWindow(FALSE);  // кнопка "Очистить сообщение"
      }
    }
    Обработчик флажка "Отображать выполнение" файла ControlsDlg.cpp
    // Отобразить - скрыть блок выполнения
    void CControlsDlg::OnBnClickedShowsProgram()
    {
      // Получить текущие значения от экрана
      UpdateData(TRUE);
        
      if(m_bShowsProgram == TRUE){ // Флажок "Отображать выполнение" установлен
        // Нарисовать все элементы управления,
        // имеющие отношение к отображению выполнений
        GetDlgItem(IDC_STATIC_PROGRAM)->ShowWindow(TRUE);  // надпись "Запустить программу"
        GetDlgItem(IDC_COMBO_RUN)->ShowWindow(TRUE);    // раскрывающийся список
        GetDlgItem(IDC_RUN)->ShowWindow(TRUE);      // кнопка "Выполнить"
      }
      else{
        // Скрыть все элементы управления,
        // имеющие отношение к отображению выполнений
        GetDlgItem(IDC_STATIC_PROGRAM)->ShowWindow(FALSE);  // надпись "Запустить программу"
        GetDlgItem(IDC_COMBO_RUN)->ShowWindow(FALSE);    // раскрывающийся список
        GetDlgItem(IDC_RUN)->ShowWindow(FALSE);      // кнопка "Выполнить"
      }
    }
  • Постройте приложение и убедитесь, что флажки работают как и было задумано
  • Управление раскрывающимся списком

    На этапе проектирования мы внесли в список имена трех программ. Обратите внимание, что при запуске нашего приложения поле списка пустое до тех пор, пока его не раскрыть и не сделать выбор. Исправим это:

  • Выделите на форме элемент управления Combo Box, который имеет идентификатор IDC_COMBO_RUN
  • В контекстном меню вызовите мастер добавления переменной и настройте его как показано на рисунке
  • Мастер добавит в описание класса CControlsDlg файла ControlsDlg.h код

    Изменения в объявлении класса CControlsDlg файла ControlsDlg.h, 
    добавленные мастером при создании переменной для управления списком
    // CControlsDlg dialog
    class CControlsDlg : public CDialog
    {
      ...............
      afx_msg void OnBnClickedExit();
      afx_msg void OnBnClickedShowMsg();
      afx_msg void OnBnClickedClearMsg();
      afx_msg void OnBnClickedDefaultMsg();
      afx_msg void OnBnClickedEnableMsg();
      afx_msg void OnBnClickedEnableProgram();
      afx_msg void OnBnClickedShowsMsg();
      afx_msg void OnBnClickedShowsProgram();
      // Переменная для управления раскрывающимся списком
      CComboBox m_lstCombo;
    };

    В файл ControlsDlg.cpp мастер добавит код для обеспечения механизма обмена данными между программой и экраном

    Изменения в файле ControlsDlg.cpp, добавленные мастером для обмена данными кода и списка
    void CControlsDlg::DoDataExchange(CDataExchange* pDX)
    {
      CDialog::DoDataExchange(pDX);
      DDX_Text(pDX, IDC_MSG, m_strMessage);
      DDX_CBString(pDX, IDC_COMBO_RUN, m_strRun);
      DDX_Check(pDX, IDC_ENABLE_MSG, m_bEnableMsg);
      DDX_Check(pDX, IDC_ENABLE_PROGRAM, m_bEnableProgram);
      DDX_Check(pDX, IDC_SHOWS_MSG, m_bShowsMsg);
      DDX_Check(pDX, IDC_SHOWS_PROGRAM, m_bShowsProgram);
      DDX_Control(pDX, IDC_COMBO_RUN, m_lstCombo);
    }

    Мы хотим, чтобы при запуске приложения список устанавливался в первую позицию (нумерация элементов списка начинается с нуля), поэтому

  • Добавьте код в функцию инициализации
    Код установки начальной позиции раскрывающегося списка
    BOOL CControlsDlg::OnInitDialog()
    {
      .............
      // TODO: Add extra initialization here
      
      // Установить список в начало
      m_lstCombo.SetCurSel(0);
      UpdateData(TRUE);  // скачать из списка в переменную m_strRun
      
      // Поместить заданное по умолчанию значение
      // в поле редактирования Edit Control
      m_strMessage = "Привет студентам!!!";
        
      // Установить все флажки
      m_bEnableMsg = TRUE;
      m_bEnableProgram = TRUE;
      m_bShowsMsg = TRUE;
      m_bShowsProgram = TRUE;
      
      // FALSE - передать значения из переменных в элементы управления
      // TRUE - передать значения из элементов управления в переменные
      UpdateData(FALSE);
      
      return TRUE;  // return TRUE  unless you set the focus to a control
    }
  • Постройте проект и убедитесь, что код работает
  • Запуск внешних приложений

    Обработаем кнопку "Выполнить", которая позволит запускать на выполнение внешние программы. При нажатии кнопки код обработчика должен извлечь имя внешней программы из поля раскрывающегося списка и с помощью соответствующей API-функции запустить процесс выполнения.

    Для запуска внешних приложений существуют функции

  • WinExec()
  • ShellExecute()
  • CreateProcess()
  • execlp()
  • spawnlp()
  • Ознакомимся только с функцией WinExec(). Эта функция может работать в любых версиях Windows и выполнять любые файлы. Функция работает асинхронно, т.е. после запуска внешнего приложения не ждет его закрытия. Функции, которые ждут завершения запущенного ими процесса, работают синхронно.

    Заголовок функции WinExec()
    UINT WinExec(
      LPCSTR lpCmdLine,
      UINT uCmdShow
    );

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

  • Каталог, из которого загружено вызывающее приложение
  • Текущий каталог
  • Системный каталог Windows, возвращаемый API -функцией GetSystemDirectory()
  • Каталог Windows, возвращаемый API -функцией GetWindowsDirectory()
  • Список каталогов из переменной окружения PATH
  • Параметр uCmdShow определяет форму представления окна запускаемого приложения и может иметь значения

    Значение uCmdShow Описание
    SW_HIDE Окно делается невидимым и фокус передается другому окну
    SW_MAXIMIZE Развертывает окно
    SW_MINIMIZE Свертывает окно, активизируя следующее в Z -последовательности окно верхнего уровня в списке системы
    SW_RESTORE Активизирует и отображает окно с первоначальными параметрами
    SW_SHOW Активизирует и отображает окно с текущими параметрами
    SW_SHOWDEFAULT Устанавливает состояние окна в соответствии с флагом SW_ в структуре STARTUPINFO
    SW_SHOWMAXIMIZED Активизирует и отображает окно в развернутом виде
    SW_SHOWMINIMIZED Активизирует и отображает окно в виде пиктограммы в панели задач
    SW_SHOWMINNOACTIVE Отображает окно в свернутом виде, оставляя активным предыдущее окно
    SW_SHOWNA Отображает окно в его текущей позиции и текущими размерами, не передавая фокус. Активным остается то окно, которое было активным до этого
    SW_SHOWNOACTIVATE Отображает окно в его последней позиции и с последними размерами. Активным остается то окно, которое было активным до этого
    SW_SHOWNORMAL Активизирует и отображает окно, восстанавливая его до первоначальных размеров и в первоначальной позиции

    Функция WinExec() возвращает беззнаковое целое, свидетельствующее об успехе или ошибке. Если возвращаемое значение меньше или равно 31, то это указывает на ошибку.

    Именованная константа Значение Описание
    0 0 Системе не хватает памяти, выполняемый файл испорчен или произошло ошибочное перераспределение памяти
    ERROR_BAD_FORMAT 11 Плохой исполняемый файл. Или это не приложение Windows, или ошибка в .exe файле
    ERROR_FILE_NOT_FOUND 2 Файл не найден
    ERROR_PATH_NOT_FOUND 3 Путь не найден
  • Обработайте кнопку "Выполнить" следующим кодом
    Обработчик нажатия на кнопку "Выполнить"
    void CControlsDlg::OnBnClickedRun()
    {
      // Передать текущие значения элементов управления в переменные
      UpdateData(TRUE);
      // Объявить локальную переменную для хранения названия программы
      CString strName;
      // Копировать текущее поле списка в локальную переменную
      strName = m_strRun;
      // Перевести название программы в верхний регистр
      strName.MakeUpper();
      int error = WinExec(strName, SW_RESTORE);
      switch(error){
        case 0:
          MessageBox( "Не хватает памяти или ресурсов!",
                "Ошибка!", MB_OK | MB_ICONINFORMATION );
          break;
    
        case ERROR_BAD_FORMAT:
          MessageBox( "Ошибочный файл!",
                "Ошибка!", MB_OK | MB_ICONINFORMATION );
          break;
    
        case ERROR_FILE_NOT_FOUND:
          MessageBox( "Файл не найден!",
                "Ошибка!", MB_OK | MB_ICONINFORMATION );
          break;
    
        case ERROR_PATH_NOT_FOUND:
          MessageBox( "Путь не найден!",
                "Ошибка!", MB_OK | MB_ICONINFORMATION );
      }
    }
  • Постройте приложение и убедитесь в его работоспособности
  • Вернуться к учебному плану