Меню программы — одна из важнейших частей, составляющих ее. С помощью MFC вполне реально реализовать его в своей программе, что сейчас мы и сделаем. Основное приложение не будет сложным, его задача подсчитать, сколько символов в веденной строке.
Создадим MFC — приложение на основе диалоговых окон, именованное Symbols. Уберем галку использовать библиотеки Юникода, в поле «Заголовок диалогового окна» впишем «Программа подсчета символов» и нажмем «Готово».
Сразу удалим все лишние элементы с диалогового окна, чтобы оно было пустым. В «Окне ресурсов» щелкнем по пустому месту правой кнопкой мыши:
В открывшемся окне выбираем «Меню», нажимаем «Создать». Теперь в закладке «Окно ресурсов» мы имеем файл IDR_MENU1 отвечающий за меню (рис. — область 1) и собственно область для работы с ним (рис. — область 2).
Нажатие левой кнопкой мыши по этой области позволит задать название пункта меню. Первое название мы зададим «&Файл», где & подчеркивает имя пункта, и дает возможность обратится к нему при помощи сочетания клавиш 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.
Теперь нажмите «Изменить код» и впишите в тело функции следующие строки.
1
2 3 4 5 6 |
void CSymbolsDlg::On32771()
{ char str[1000]; itoa(strlen(m_S),str,10); MessageBox(str, «Всего символов»); } |
Программа обрабатывает строку, введенную в поле ввода, после чего возвращает количество символов составляющих ее. Осталось назначить работу еще не задействованных пунктов меню: «Выход» и «О программе». Начнем с первого.
Для пункта «Посчитать» мы добавляли обработчик событий непосредственно через «Мастера классов». Альтернативный способ связывания кода с нужным событием заключается в следующем:
- открываем окно для работы с меню;
- щелкаем правой кнопкой мыши по пункту «Выход»;
- выбираем «Добавить обработчик событий…»;
- в появившемся окне в поле «Список классов» устанавливаем значение CSymbolsDlg, а в поле «Тип сообщения» COMMAND;
- жмем «Добавить/править».
Изменим код функции, добавив следующий оператор:
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() выводит диалоговую панель.
Программа создана! Файлы ее исходного кода Вы можете скачать по ссылке.
Сплошные ошибки. Использую 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). Хотя начиналось всё хорошо)
Дружище Дмитрий, не судите строго. Всякое бывает.
У меня косяк тоже возник (хотя в 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!
Поправка: 1) Стал больше обращать вниманиена архитектонику.
А то как Кличко написал.
CString df = L»Всего символов»;
CString sdf;
sdf.Format(_T(«%s : %d»), df, m_S.GetLength());
MessageBox(sdf);