C++. MFC. Создание меню

Меню программы — одна из важнейших частей, составляющих ее. С помощью MFC вполне реально реализовать его в своей программе, что сейчас мы и сделаем. Основное приложение не будет сложным, его задача подсчитать, сколько символов в веденной строке.

Создадим MFC — приложение на основе диалоговых окон, именованное Symbols. Уберем галку использовать библиотеки Юникода, в поле «Заголовок диалогового окна» впишем «Программа подсчета символов» и нажмем «Готово».

Сразу удалим все лишние элементы с диалогового окна, чтобы оно было пустым. В «Окне ресурсов» щелкнем по пустому месту правой кнопкой мыши:

MFC. C++. Меню программы

В открывшемся окне выбираем «Меню», нажимаем «Создать». Теперь в закладке «Окно ресурсов» мы имеем файл IDR_MENU1 отвечающий за меню (рис. — область 1) и собственно область для работы с ним (рис. — область 2).

Окно ресурсов в visual c++. MFC

Нажатие левой кнопкой мыши по этой области позволит задать название пункта меню. Первое название мы зададим «&Файл», где & подчеркивает имя пункта, и дает возможность обратится к нему при помощи сочетания клавиш ALT+F. Клавиша Enter подтверждает ваше действие. Как видите, прослеживается иерархия, которую мы можем продолжить, как на более низкие уровни, так и тождественные созданному. Добавим под меню «Файл» пункт «Посчитать», так как это показано на скриншоте.

В свойствах последнего, написан его ID (у меня это ID_32771), позже с его помощью мы свяжем пункт меню «Посчитать» с событием. А сейчас в ветке «Файл» задайте последний раздел «&Выход».

Рядом создадим меню «&Помощь», а под ним пункт «&О программе», нажав на который пользователь увидит сведения о приложении (их мы оставим по умолчанию).

Свяжем наше меню с основной панелью, для этого откроем «Свойства» диалогового окна и в поле «Меню» установим название нашего.

Связываем меню с диалоговой панелью

На этом визуальное проектирование меню программы законченно, пришло время планировать диалоговую панель. С помощью панели элементов поместите в главное окно «Static Text» и «Edit Control», изменив ID второго на IDC_SYMB_EDIT.

Окно с меню

Добавим переменную m_S типа CString для поля Edit Control. Она нужна для получения доступа к полю, в которое будет вводиться строка.

После каждого использования поля ввода, происходит событие EN_CHANGE, нужно добавить в его код оператор, обновляющий переменные элементов управления. Зайдите в «Мастер классов» (Верхние меню>Проект>Мастер классов) и найдите там сообщение EN_CHANGE.

Мастер классов

Нажмите «Добавить обработчик…» всплывет окно, в котором следует нажать OK, и наконец изменить код функции на следующий:

1
2
3
4
5
6
7
8
9
void CSymbolsDlg::OnChangeSymbEdit()
{
// TODO: Если это элемент управления RICHEDIT, то элемент управления не будет
// send this notification unless you override the CDialogEx::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
UpdateData(TRUE);
// TODO: Добавьте код элемента управления
}

После выполнения этого оператора переменной m_S будет присвоено значение содержимого окна редактирования.

Зададим пункту меню «Посчитать» действия, необходимые для работы нашей программы. Как помните его ID — ID_32771. Зайдем в «Мастер классов…» и добавим обработчик, выделив сообщение COMMAND идентификатора объектов ID_32771.

MFC Class Wizrad. Kvodo

Теперь нажмите «Изменить код» и впишите в тело функции следующие строки.

1
2
3
4
5
6
void CSymbolsDlg::On32771()
{
char str[1000];
itoa(strlen(m_S),str,10);
MessageBox(str, «Всего символов»);
}

Программа обрабатывает строку, введенную в поле ввода, после чего возвращает количество символов составляющих ее. Осталось назначить работу еще не задействованных пунктов меню: «Выход» и «О программе». Начнем с первого.

Для пункта «Посчитать» мы добавляли обработчик событий непосредственно через «Мастера классов». Альтернативный способ связывания кода с нужным событием заключается в следующем:

  • открываем окно для работы с меню;
  • щелкаем правой кнопкой мыши по пункту «Выход»;
  • выбираем «Добавить обработчик событий…»;
  • в появившемся окне в поле «Список классов» устанавливаем значение CSymbolsDlg, а в поле «Тип сообщения» COMMAND;
  • жмем «Добавить/править».

MFC. Добавление обработчика событий

Изменим код функции, добавив следующий оператор:

1
2
3
4
void CSymbolsDlg::On32772()
{
OnOK();
}

Приступим к последнему этапу: свяжем код с пунктом «О программе». Аналогично предыдущему шагу добавим к нему обработчик COMMAND, изменим функцию таким образом:

1
2
3
4
5
void CSymbolsDlg::On32773()
{
CAboutDlg dlg;
dlg.DoModal();
}

Оператор CAboutDlg dlg создает объект класса CAboutDlg именованный dlg, а dlg.DoModal() выводит диалоговую панель.

Программа создана! Файлы ее исходного кода Вы можете скачать по ссылке.

Понравилась статья? Поделиться с друзьями:
Kvodo.ru
Комментарии: 4
  1. Дмитрий

    Сплошные ошибки. Использую Visual Studio 2013.

    Совершенно очевидно, что переменная m_S типа «CString» не может неявно конвертироваться в тип «const char *». Но вот неудача! Похоже, именно на это рассчитана строка вашего кода:

    itoa(strlen(m_S),str,10);

    Дальше ещё более неприятная неожиданность:

    MessageBox(str, «Number of symbols»);

    Тут целых две ошибки. По одной на аргумент. Ожидаются аргументы типа «LPCTSTR», а не «char *».

    Даже если не брать непонятные ошибки(всё было сделано именно как у вас), вроде:

    1IntelliSense: identifier «IDC_SYMB_EDIT» is undefined d:\Code\C++\ MFCApp1\MFCApp1 \MFCApp1Dlg.cpp 66 2 MFCApp1

    про которые, к слову, тоже ничего не сказано в статье, то лично мне осталось непонятным, куда именно нужно было добавить «переменную m_S типа CString для поля Edit Control».

    То, что я читаю эту статью, само по себе говорит о том, что я новичёк в MFC и для старта мне нужны простые работающие примеры, с подробным пояснением «что, куды, зачем». К сожалению, тут я нашёл неработающий код и неясные инструкции(вроде добавления m_S). Хотя начиналось всё хорошо)

  2. Vitaliy

    Дружище Дмитрий, не судите строго. Всякое бывает.

    У меня косяк тоже возник (хотя в 9-й сверху картинке функция On32771() процессируется верно), но, согласитесь, это даёт нам великолепную возможность пошевелить сереньким в черепушке.

    Я, как и Вы,— новичок и решил заняться программированием на С++, потому что я достиг значительных высот в биотеке, но высококлассный спец со степенью и свободным английским уже 4-й год не может найти работу. Печальные реалии.

    Итак, как я пофиксил косяк (я юзаю VS2012). Один из моих коньков — внимание и наблюдательность.

    m_S в теле функции On32771() подчёркнуто. Значит её объявление в class CSymbolsDlg в хэдере CSymbolsDlg.h не видится самой функцией.

    Вопрос — почему?

    Проверяю: void CAboutDlg::On32771(). Ага! Вот он и косяк! Класс совсем другой — CAboutDlg!
    Через Class wizard (Мастер классов) сносим функцию On32771(), ассоциированную с CAboutDlg, и создаём по образу и подобию такую же функцию с классом CSymbolsDlg в файле SymbolsDlg.cpp.

    Должно получиться:
    void CSymbolsDlg::On32771()
    {
    char str[1000];
    _itoa_s(strlen(m_S),str,10);
    MessageBox(str, «Total number of symbols»);
    }
    Корректирую функцию itao.
    Компилирую. Бинго!

    Чему научился? 1) Стал очень внимательно обращать внимание на архитектонику: Иерархия, состав классов, и т. д. 2) Конвертирование int в String (конвертация, вообще, интересная тема; много косяков именно там).

    Спасибо автору.
    Live long and prosper, folks!

  3. Vitaliy

    Поправка: 1) Стал больше обращать вниманиена архитектонику.
    А то как Кличко написал.

  4. Сергей

    CString df = L»Всего символов»;
    CString sdf;
    sdf.Format(_T(«%s : %d»), df, m_S.GetLength());
    MessageBox(sdf);

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: