Модификация обработчиков сообщений в ходе работы над проектом
Рассмотрим простой пример, в котором был создан каркас AppWizard-а (exe) и ресурс в виде окна диалога:
Для работы с окном с помощью ClassWizard (который вызывается из меню View/ClassWizard) были внесены следующие изменения.
Так, по нажатию на кнопке «Результат» должно выводиться окно с результатом сложения, по нажатию на кнопке «Сброс» - в текстовых окнах отображаются 0, по нажатию на кнопке «Завершить» - окно закрывается и приложение завершает работу. Для работы используется вкладка Message Maps (Карта сообщений), в окне ClassWizard-а на этой вкладке 3 текстовых области:
- Object IDs: содержит список идентификаторов, связанных с данным классом и соответствующих тем элементам, которые могут генерировать сообщения. В примере это: IDC_BUTTON2, IDC_EDI1, … , IDOK, IDCANCEL.
- Messages: если выбрать в 1-й области идентификатор, то в этой текстовой области отобразится список сообщений, которые может обрабатывать выбраный объект или имена виртуальных функций. Жирным выделены имена, для которых уже декларированы функции обработки в классе , а обычным шрифтом те функции-обработчики, которые можно переопределить.
- Member functions: содержит список переопределеных виртуальных функций, или функций обработчиков сообщений, определённых пользователем.
V – отмечены виртуальные функции
W – отмечены обработчики событий
Кнопки диалогового окна ClassWizard:
AddClass,…, AddFunction, DeleteFunction, EditCOde – позволяют соответственно добавить новый класс, добавить лили удалить определение виртуальной функции в выбранном классе.
Вкладка “Member Variables” позволяет назначить для органов управления (кнопок, текстовых полей), располагающихся в окне, выбрав их идентификаторы на текстовой области Control IDs, переменные, куда будет передаваться информация от органов управление или откуда они её будут получать.
Определение диалогового класса в нашем проекте выглядит следующим образом
// CEasyDialogDlg dialog
class CEasyDialogDlg : public CDialog
{
// Construction
public:
CEasyDialogDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum { IDD = IDD_EASYDIALOG_DIALOG };
//{{AFX_VIRTUAL(CEasyDialogDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_ VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
DECLARE_MESSAGE_MAP()
public:
//{{AFX_DATA(CEasyDialogDlg)
CString m_first;
CString m_second;
//}}AFX_DATA
//{{AFX_MSG(CEasyDialogDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnOk();
afx_msg void OnCancel();
afx_msg void OnButton2();
//}}AFX_MSG
private:
char strArr[30];
double m_acdValue;
double m_fstValue;
};
Здесь //{{AFX_VIRTUAL(CEasyDialogDlg)
//{{AFX_MSG(CEasyDialogDlg)
//{{AFX_DATA(CEasyDialogDlg) - комментарии визардов
- DECLARE_MESSAGE_MAP() – макрос указателей, то для касса будут декларированы с помощью макрокоманд функции обработки сообщений.
- m_first, m_second - переменные, которые мы добавили с помощью ClassWizarda, чтобы туда передавать информацию из текстовых полой редактирования. Для них ClassWizard сгенерирует функции DDX_...(), DDV_...().
- m_fstValue, m_scdValue, strArr[] - переменные, которые мы добавили, чтобы разместить результат перевода из типа CString в тип double и для представления в виде строки результата сложения чисел; эти переменные должны быть добавлены вручную, либо WizardBar.
Дальше вносим изменения в функции обработчика OnInitDialog(), OnCancel(), OnButton2().
С помощью ClassWizard выделяем имена и переходим к редактированию с помощью EditCode. Если обработчик уже есть, то его редактирование можно начать 2-жды щелкнув на нём из вкладки Class View в левом окне DevStudio. |
OnInitDialog всегда автоматически определяется для диалогового окни и получает управление в результате посылки сообщения от окна, раскрывающегося на экране. 2-й и 3-й обработчики, из перечисленных выше, получают управление при щелчках на кнопках с идентификаторами IDCANCEL и IDC_BUTTON2 (имеется сходство имеён функций и идентификаторов, назначеных для соответствующих окон).
1-й обработчик можно дополнить кодом для инициализации какого-либо из своих объектов, если необходимо. В примере – обнуляем переменные.
2-й обработчик надо дополнить кодом, обнуляющим переменные и пересыпающим 0-е значение в тексте окна.
3-й обработчик – дополнить кодом для вычисления суммы и отображения в окне результата. Мы также дополнили конструктор класса. Определение функций размещается в файле EasyDialogDlg.cpp. Приведём весь текст:
CEasyDialogDlg::CEasyDialogDlg(CWnd* pParent /*=NULL*/)
: CDialog(CEasyDialogDlg::IDD, pParent)
, m_first(_T("0.0"))
, m_second(_T("0.0"))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_fstValue = 0.0;
m_scdValue = 0.0;
}
void CEasyDialogDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_first);
DDV_MaxChars(pDX,m_first,12);
DDX_Text(pDX, IDC_EDIT2, m_second);
DDV_MaxChars(pDX,m_second,12);
|
BEGIN_MESSAGE_MAP(CEasyDialogDlg, CDialog)
ON_WM_SYSCOMMAND()
....
END_MESSAGE_MAP()
// CEasyDialogDlg message handlers
BOOL CEasyDialogDlg::OnInitDialog()
{
|
...
// TODO: Add extra initialization here
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
m_fstValue = 0.0;
m_scdValue = 0.0;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CEasyDialogDlg::OnCancel()
{
m_first=_T("0.0");
m_second=_T("0.0");
m_fstValue = 0.0;
m_scdValue = 0.0;
UpdateData(FALSE);
}
void CEasyDialogDlg::OnButton2()
{
UpdateData(TRUE);
sscanf((LPCTSTR)m_first,"%lf",&m_fstValue);
sscanf((LPCTSTR)m_second,"%lf",&m_scdValue);
sprintf(strArr,"%lf",m_scdValue+m_fstValue);
AfxMessageBox(strArr);
}
_T() – выполняет преобразование из типа char* в CString, обратное преобразование пришлось сделать с помошью префикс ной операции (LPCTSTR).
AfxMessageBox() – глобальная функция, выводящая окно сообщения, указанного параметром (содержится в определении глобальных функций MFC).
Вопросы для самоконтроля
· Перечислите типы проектов, которые могут создаваться визардами проектов в Dev Studio?
· Что выполняют визард класса и редактор ресурсов?
· Для чего применяются Class wizard и Wizard Bar?
· Как выполняется модификация обработчиков сообщений в ходе работы над проектом?
· Как добавить новые свои переменные и методы в проектируемый класс?
· В результате каких действий формируются DDV- и DDX-функции?
Вопросы для самостоятельного изучения
· Как выглядят параметры функции AfxMessageBox()? – какие типы окон можно отображать с помощью этой функции?
· Выяснить последовательность действий при выполнении вызовов UpdateData(False), UpdateData(True), а также назначение метода DoDataExchange() и класса CDataExchange!
Дата добавления: 2016-05-26; просмотров: 1466;