Out.close();//закрытие потока 8 глава




 

Создание окон.

Windows это программа написанная на языке С++. Причем обмен информацией системы с пользователем чаще всего осуществляется с помощью окон. Сразу возникает вопрос: как операционная система Windows в процессе работы создает окна к которым вынуждена сама обращаться? Ответ очень прост. Средствами языка С++. Существует базовый класс Frame от которого пораждаются объекты - окна. Только нужно иметь в виду, что имена этим объектам дает сама операционная система. Имена представляют собой целые числа. Использование таких имен вполне оправдано, т.к. следующий объект получает уникальное имя строящееся по простому правилу, к последнему имени нужно добавить единицу. И вообще большинство переменных в Windows это целые числа. Только нужно иметь в виду, что это не числа типа int. Такие имена объектов Windows называются дискрипторами.

В Win32 программах вместо стандартных для С и С++ типов данных (таких, как int или char) применяются типы данных, определенные в библиотечных файлах (например, в WINDOWS.Н). Часто используются следующие типы:

HANDLE — 32-разрядное целое предназначено для автоматического создания имен т.е. идентификатор какого-либо ресурса, например имя окна, диска и т.п;

HWND — 32- разрядное длинное целое для создания имен окон;

BYTE — 8-разрядное беззнаковое символьное значение;

WORD— 16-разрядное беззнаковое короткое целое;

DWORD, UINT — 32-разрядное беззнаковое длинное целое;

LONG — 32-разрядное длинное целое со знаком;

BOOL — целое, используется для обозначения истинности (1 — TRUE) или ложности (0 — FALSE);

LPSTR — 32-разрядный указатель на строку символов.

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

 

Функция WinMain

Все программы, написанные на языках С или C++, начинают свое выполнение с функции main(). Корпорации Microsoft была вынуждена здесь внести изменение в принятые стандарты, т.к. параметры стандартной функции main не подходят для приложений Windows. Теперь каждая Windows-программа на С или C++ начинает свое выполнение с вызова функции WinMain(), Объявление этой функции в рамках Win32 API следующее:

int WINAPI WinMain(HINSTANCE hlnstance,

HINSTANCE hPrevlnstance,

LPSTR LpCmdLine,

int nCmdShow);

Здесь

hlnstance — дескриптор текущего приложения;

hPrevlnstance — дескриптор предыдущей запущенной копии приложения;

LpCmdLine — указатель на командную строку;

nCmdShow — режим начального отображения главного окна приложения.

Вот пример простейшей программы для Windows:

/*******************************************************

Модуль APIMain

Copyright (с) 1997 Мешков А., Тихомиров Ю.

*******************************************************/

#include <windows.h>

int WINAPI WinMain(

HINSTANCE hlnstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow) {

return (FALSE);

}

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

Значение параметра hPrevInstance позволяет определить наличие уже запущенных копий программы. В большинстве случаев это нужно для исключения повторного запуска одной и той же профаммы. В Win32 API этот параметр всегда равен NULL. Связано это с тем, что каждое 32-разрядное приложение запускается в своем адресном пространстве, в котором, естественно, нет никаких его копий или других приложений.

В документации Microsoft предлагает несколько путей для определения наличия предыдущей копии. Один из них заключается в использовании функции FindWindow. Функция FindWindow в случае обнаружения искомого окна возвращает его дескриптор. Один из параметров может быть равен NULL, в этом случае поиск будет производиться при помощи второго параметра.

HWND FindWindow(

LPCTSTR IpClassName,

LPCTSTR IpWindowName

);

Здесь

lpClassName — указатель на строку, содержащую имя оконного класса или специального вида идентификатор этого класса; lpWindowName — указатель на строку, содержащую заголовок искомого окна

Одно из требований Microsoft к приложениям для Windows состоит в исключении повторного запуска. Действительно, большинству программ это не нужно. Например, для многооконных редакторов повторный запуск вместо открытия дополнительного окна приведет только к лишней трате системных ресурсов. Для программ мониторинга или управления вообще бессмысленно держать две копии приложения в памяти, т. к. такие программы обычно работают с неразделяемыми ресурсами. Хорошей практикой является не только завершение повторной копии приложения сразу после загрузки, но и активизация этого приложения, ведь, скорее всего, повторный запуск был произведен из-за того, что оно понадобилось пользователю. Активизация в общем случае совершается в два этапа. Во-первых, главное окно искомого приложения восстанавливается в размере, если оно было свернуто в значок, и, во-вторых, происходит собственно активизация — перевод окна и, соответственно, приложения на передний план. На этом обычно повторная копия приложения должна быть завершена. Для этого используются функции IsIconic, ShowWindow, SetForegroundWindow.

hwnd = FindWindow (szClassName, szWindowTitle);

if (hwnd)

{ /* нашли копию приложения — восстановим его на экране и

активизируем его */

if (Islconic(hwnd))

ShowWindow(hwnd, SW_RESTORE);

SetForegroundWindow (hwnd);

/* данная копия должна быть завершена */ return (FALSE);

 

Программирование в среде Microsoft Visual C++ 6

Утилита Spy (в переводе шпион, или найти, обнаружить, разглядеть, увидеть) позволяет наблюдать за системными процессами в Windows. Запустить данную утилиту можно из главного меню Tools/Spy++. В результате Вы получите окно со списком всех окон в Windows. Примерно такое, как то, что мзображено ниже.

Окна представлены в виде дерева. Главным окном является DeskTop (рабочий стол), от него идут ветвления. В каждом окне есть еще окна, и так до элементов управления. Корень - рабочий стол. Ветви это запущенные программы или процессы, а более мелкие ветви это конечные окна или элементы управления. В ходе работы, как уже говорилось, между системой и окнами посылаются сообщения. Их можно просматривать. Для этого установите курсор на интересующее вас дискриптор окна, нажмите правую кнопку мыши и выберите Message.

Не будем больше задерживаться на сообщениях, а посмотрим как можно получить имя для окна к созданию окна. Сначала воспользуемся функцией GetDesktopWindow(), которая вернет HWND корневого окна, которым является рабочий стол. Далее двигаясь по ветвям дерева от текущего HWND можно получить HWND всех дочерних окон. Для этого воспользуемся функцией GetWindow(HWND hwnd, UINT ucmd).

Функция GetWindow() имеет два параметра. Первый это имя (дискриптор) окна, т.е.hwnd, второй определяет соотношение родства и может принимать только определенные значения. В частности, если в качестве второго параметра указать GW_CHILD, то это означает, что определяется имя дочернего окна. Дочерних окон может быть несколько, поэтому если в качестве второго параметра указать GW_HWNDNEXT то это значит, что нужно определить дискриптор следующего окна, находящегося на уровне дочернего.

 

Имея HWND окна можно получить его заголовок GetWindowText.

Вот код получения имен окон первого уровня. Пока программу, как и прежде выполним в консольном приложении.

/* GetWindow.cpp: Определение точки входа консольного приложенияDefines the entry point for the console application.*/// https://www.firststeps.ru#include "windows.h"#include "iostream.h" void main(){HWND hwnd; //создаем объект для определения имени окна char p[100]; /* массив для записи заголовков окон */ hwnd = GetDesktopWindow(); //определение имени корневого окна hwnd = GetWindow(hwnd, GW_CHILD); /*определение имени она следующего уровня*/ while (hwnd!=0){hwnd = GetWindow(hwnd, GW_HWNDNEXT); /*поиск окон первого уровня*/ GetWindowText(hwnd,p,100); /*записываем заголовоки окна */ if (strlen(p)>0) cout << p << endl; /*если заголовок найден – вывод на экран*/ }}

Результат работы на моем компьютере


Вот такой список окон первого уровня. Это не значит, что все перечисленные окна открыты. Они готовы к тому, чтобы быть открытыми.

Работа Windows-программ основана на обработке сообщений, которые поступают от пользователя, операционной системы и других программ. Структур приложений обязательно включает в себя главную функцию WinMain(), одинаково устроенную для всех приложений. С нее начинается выполнение всех программ. WinMain() должна выполнить следующие сновные действия:

1. Определить и зарегистрировать класс окна в Windows.

2. Создать и отобразить окно, определяемое данным классом.

3. Запустить цикл обработки сообщений.

При определении класса окна указывается специальная функция окна, которая должна реагировать на поступающие окну сообщения. В каждом приложение имеется своя очередь сообщений. Эту очередь создает Windows и помещает туда все сообщения, адресованные окну приложения. После создания и отображения окна запускается основной цикл обработки сообщений, в котором сообщения проходят предварительную обработку и возвращаются Windows-ом обратно. Затем Windows вызывает функцию окна программы с очередным сообщением в качестве аргумента. Анализируя сообщение, функция окна инициирует соответствующие операции. Сообщения, обработка которых не усмотрена функцией окна, передаются Windows, который выполняет обработку "по умолчанию".

 

 

Теперь попробуем создать окно с помощью библиотеки MFC. В простейшем случае такая программа должна использовать два класса этой библиотеки. Первый это CFrameWnd, второй CWinApp. Слово Frame в переводе с английского означает - рама, каркас, основа. Поэтому понятно, что класс CFrameWnd является основой для создания окна (Window или сокращенно Wnd). Сокращение App происходит от английского Application, что, как известно, означает приложение, а для операционной системы Windows так называются все программы, которые работают под ее управлением. Поэтому класс CwinApp позволяет создать приложение (программу) для операционной системы Windows. В MFC всеклассы начинаются с буквы С, а все переменные с буквы m. Мы так же будем придерживаться такого правила.

Итак, вот эта программа:

//Программа «Мое первое окно»

#include <afxwin.h> /*Описание библиотек MFC*/

// Создадим окно для чего используем родительский

// класс CFrameWnd

class CMainWin: public CFrameWnd

{

public:

CMainWin(); //Это конструктор

/*К окну будут поступать сообщения, поэтому нужно создать

* обработчик этих сообщений, который называется картой

* сообщений*/

DECLARE_MESSAGE_MAP() //Макрос объявления карты сообщений

};

 

/*Описание класса закончилось. Далее идет описание функций */

CMainWin::CMainWin(){

Create(NULL, "Мое первое окно"); /*Функция создания окна

* унаследованная от родительского класса CFrameWnd */

}

//Карта сообщений приложения

BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd) /*Начало обработки

* сообщений */

/*Здесь должны быть функции обработки сообщений,

* но т.к. их нет поступающие к окну сообщения

* не обрабатываются*/

END_MESSAGE_MAP() /*Конец обработки сообщений*/

//Начало выполнения приложения

 

//------------------------------------------------------

//Начинается описание второго класса

/*Создаем класс наследник от другого класса CWinApp */

class CApp: public CWinApp

{

public:

BOOL InitInstance();

};

/* В родительском классе CwinApp есть функция InitInstance

у которой возвращаемое значение отлично от нуля, если

инициализация успешна, иначе 0 */

BOOL CApp::InitInstance(){ //Перегрузка функции InitInstance

m_pMainWnd=new CMainWin;

m_pMainWnd->ShowWindow(m_nCmdShow);

return TRUE;

}

CApp theApp; //Создание объекта theApp

 

 

 

В данном примере пока многое непонятно. Кое-что можно пояснить сейчас. Так в начале подкючается файл afxwin.h,который содержит описание классов библиотеки MFC и подключает множество других файлов, втом числе WINDOWS.H.

 

Класс CFrameWnd обеспечивает функциональные возможности Windows на основе одиночного интерфейса документа (SDI) для всплывающих окон наряду с элементами для управления окном.

Чтобы создавать полезное рамочное окно для Вашей прикладной программы, получите класс из CFrameWnd. Добавьте поля к полученному классу, чтобы сохранить данные, специфические для Вашей прикладной программы. Примените сообщения и карту сообщения в полученном классе, чтобы определить то, что случается, когда сообщения полученные окном.

Имеются три способа создать рамочное окно:

Непосредственно создайте используя Create.

Непосредственно создайте используя LoadFrame.

Косвенно создайте используя шаблон документа.

Прежде, чем Вы вызываете Create или LoadFrame, Вы должны создать объект рамочного окна в "куче ", используя C++ new оператор. Прежде, чем вызывать Create, Вы можете также регистрировать класс окна глобальной функцией AfxRegisterWndClass, чтобы установить пиктограмму и стили класса для рамки.

Используйте Create функцию, чтобы передать параметры создания рамки как непосредственные параметры.

LoadFrame требует, меньшее количество параметров чем Create, и взамен восстанавливает большинство значений по умолчанию из ресурсов, включая заголовок рамки, пиктограмму, таблицу акселератора, и меню. Чтобы быть доступным LoadFrame, все эти ресурсы должны иметь тот же самый ресурс ID (например IDR_MAINFRAME).

Когда объект CFrameWnd содержит виды и документы, они созданы косвенно рамкой вместо непосредственного создания программистом. Объект CDocTemplate обеспечивает создание рамки, создание вида, и подключение видов к соответствующему документу. Параметры CDocTemplate конструктора определяют CRuntimeClass из трех включаемых классов (документ, рамка, вид). Объект CRuntimeClass используется рамкой, чтобы динамически создать новые рамки когда это определено пользователем (например, используя команду File New или в многодокументной среде (MDI) командой Window New).

Класс рамочного окна, полученный из CFrameWnd должен быть объявлен с DECLARE_DYNCREATE для вышеупомянутого RUNTIME_CLASS механизма, чтобы работать правильно.

CFrameWnd содержит заданные по умолчанию реализации чтобы выполнить следующие функции основного окна в типичной прикладной программе для Windows:

1. CFrameWnd рамочное окно следит за активным просмотром, который не зависит от активного окна Windows или текущего фокуса ввода. Когда рамка повторно активизирована, активному просмотру сообщается путем вызова вызывая CView::OnActivateView.

2. Сообщения команды и много общих уведомительных сообщений рамки, включая обработанный OnSetFocus, OnHScroll, и OnVScroll CWnd, делегированы CFrameWnd рамочным окном к активному настоящее время просмотру.

3. Активный просмотр (или в настоящее время активное MDI порожденное рамочное окно в случае MDI рамки) может определять заголовок рамочного окна. Это свойство может быть заблокировано, выключением FWS_ADDTOTITLE бита стиля рамочного окна.

4. CFrameWnd рамочное окно управляет позиционированием областей управления, видов и других дочерних окон внутри клиентской области окна рамки. Рамочное окно также делает модифицирование времени простоя инструментальной панели и других кнопок области управления. CFrameWnd рамочное окно также переключает заданные по умолчанию реализации команд для переключения вкл. и выкл. инструментальной панелью и строкой состояния.

5. CFrameWnd рамочное окно управляет областью главного меню. Когда всплывабщее отображается, рамочное окно использует UPDATE_COMMAND_UI механизм, чтобы определить, которые пункты меню нужно допустить, заблокировать, или проверить. Когда пользователь выбирает пункт меню, рамочное окно модифицирует строку состояния со строкой сообщения для той команды.

6. CFrameWnd рамочное окно имеет факультативную таблицу акселератора, которая автоматически транслирует ускорители клавиатуры.

7. CFrameWnd рамочное окно имеет факультативную справку ID установленную LoadFrame, который используется для контекстно-зависимой справки. Рамочное окно - обеспечивает полумодальное состояние типа контекстно-зависимой справки (SHIFT+F1) и режимы предварительного просмотра печати.

8. CFrameWnd рамочное окно откроет файл, перемещаемый из диспетчера файлов и отпущенный на рамочном окне. Если расширение файла зарегистрировано и связано с прикладной программой, рамочное окно отвечает на динамический обмен данными (DDE), который происходит, когда пользователь открывает файл данных в диспетчере файлов или когда функция ShellExecute Windows вызвана.

9. Если рамочное окно - основное окно прикладной программы (то есть CWinThread::m_pMainWnd), когда пользователь закрывает прикладную программу, рамочное окно запрашивает пользователя сохранять любые изменяемые документы (OnClose и OnQueryEndSession).

10. Если рамочное окно - основное окно прикладной программы, рамочное окно - контекст для выполнения WinHelp. Закрытие рамочного окна закрыло бы WINHELP.EXE, если справки запущено из этой прикладной программы.

Не используйте C++ delete оператор чтобы уничтожить рамочное окно. Используйте CWnd::DestroyWindow вместо этого. CFrameWnd реализация PostNcDestroy удалит объект C++, когда окно разрушено. Когда пользователь закрывает рамочное окно, значение по умолчанию OnClose вызовет DestroyWindow.

 

virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);

Возвращаемое значение
Отличное от нуля, если успешно, иначе 0.

Параметры

lpszClassName
Указатель на символьную строку с нулевым символом в конце с именем классa Windows (структура WNDCLASS). Имя класса может быть любое имя, зарегистрированное с глобальной функцией AfxRegisterWndClass или любым из предопределенных имен класса. Если NULL использует значение по умолчанию CWnd.
lpszWindowName
Указатель на символьную строку с нулевым символом в конце, которая содержит имя окна. dwStyle
Определяет атрибуты стиля окна. WS_POPUP не может использоваться. Если Вы желаете создать всплывающее окно, используйте CWnd:: CreateEx вместо этой функции.
rect
Размер и позиция окна, в клиентских координатах pParentWnd.
pParentWnd
Родительское окно.
nID
ID дочернего окна.
pContext
Создающийся контекст окна.

Замечания
Создает дочернее окно Windows и присоединяет его к объекту CWnd. Вы создаете дочернее окно в двух шагах. Сначала, вызовите конструктор, который создает объект CWnd. Затем обращаетесь к Create которая создает дочернее окно Windows и присоединяет его к CWnd. Create инициализирует имя класса окна и имя окна и регистрирует значения стиля, родителя, и ID.

Пример

// Динамически создаем статический элемент управления, // используя CWnd::Create, вместо CStatic::Create, который не // нуждается в "STATIC" имени класса.void CMyDlg::OnCreateStatic() { CWnd* pWnd = new CWnd; pWnd->Create(_T("STATIC"), "Hi", WS_CHILD | WS_VISIBLE, CRect(0, 0, 20, 20), this, 1234);}

 

 

afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);

Параметры
nFlags
Указывает различные нажатые виртуальные клавиши. Этот параметр может быть любой комбинацией следующих значений:

MK_CONTROL Установлен если клавиша CTRL нажата.

MK_LBUTTON Установлен если левая кнопка мыши нажата.

MK_MBUTTON Установлен если средняя кнопка мыши нажата.

MK_RBUTTON Установлен если правая кнопка мыши нажата.

MK_SHIFT Установлен если SHIFT нажата.

point
Определяет x и y координату курсора. Эти координаты - всегда относительно левого верхнего угла окна.

Замечания
Рамка вызывает эту функцию, когда пользователь дважды щелкает левую кнопку мыши.>br> Только окна которые имеют CS_DBLCLKS стиль в WNDCLASS получат обращения OnLButtonDblClk. Это - значение по умолчанию для окон MFC. Windows вызывает OnLButtonDblClk, когда пользователь нажимает, отпускает, и затем нажимает левую кнопку мыши снова в промежуток срока двойного щелчка системы. Двойное нажатие левой кнопки мыши фактически генерирует четыре события: WM_LBUTTONDOWN, WM_LBUTTONUP сообщения, обращение WM_LBUTTONDBLCLK, и другое WM_LBUTTONUP сообщение, когда кнопка отпущена.

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

 

virtual BOOL InitInstance();

Возвращаемое значение
Отлично от нуля, если инициализация успешна, иначе 0.

Замечания
Windows позволяет нескольким копиям той же самой программы выполняться в то же самое время. Инициализация Приложения концептуально разделена на два раздела: одноразовая инициализация приложения, которая выполнена первый раз, когда программа выполняется, и инициализация образца, которая выполняет каждый раз при запуске каждой копия программы включая первый раз. Реализация каркаса WinMain вызывает эту функцию.
Переопределите InitInstance, чтобы инициализировать каждый новый образец вашего приложения, выполняющегося под Windows. Обычно, Вы отменяете InitInstance, чтобы создать ваш основной объект окна и устанавливаете CWinThread::m_pMainWnd элемент данных, чтобы указать на окно приложения.

Пример.

// AppWizard осуществляет переопределение функции InitInstance// согласно опциям, которые Вы выбираете. Например, опция одиночный документ // (SDI) интерфейса была выбрана для AppWizard создаваемого кода// Вы можете добавлять другие инициализации к коду // созданному AppWizard.BOOL CMyApp::InitInstance() { // Стандартная инициализация, если Вы не используете эти // возможности и желаете уменьшить размер вашей заключительной программы, // то Вы должны удалить из него специфические подпрограммы инициализации, // которые не нужны. SetDialogBkColor(); // Установите цвет фона диалога к серому LoadStdProfileSettings(); // Загрузите стандартные опции из INI файла (включая MRU) // Регистрировать шаблоны документа приложения. Шаблоны Документа // служать как соединение между документами, рамочными окнами и просмотрами. CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMainFrame), // SDI окно RUNTIME_CLASS(CMyView)); AddDocTemplate(pDocTemplate); // создаем новый пустой документ OnFileNew(); if (m_lpCmdLine[0]!= '\0') { // TODO: добавьте сюда обработку командной строки } return TRUE; }

 

 

Обработка сообщений

 

Сообщение это уникальный код, которым пользуется операционная система. Например, WM_BUTTONUP соответствует целой фразе, которая на английском выглядит так NO WIN MESSAGES BUTTON UP, а по русски, - запретить сообщение о поднятии кнопки мыши. На самом деле сообщения это целые числа из некоторого списка, просто каждое число имеет свое имя. Вместе с сообщениями часто передаются параметры, например, координаты курсора, код нажатой клавиши, и т.п. На все сообщения операционная системы реагирует соответствующим образом (хотя некоторые из них игнорирует), или как говорят, обрабатывает поступающие сообщения. Некоторые сообщения системы можно использовать в созаваемых программах. Для этого нужно их перехватить, т.е. сделать так, чтобы они поступали не к операционной системой, а программе, и в дальнейшем в ней обрабатывались. Следует еще раз подчеркнуть, что перехватывать нужно только необходимые сообщения.

Для организации обработки сообщений создается катра сообщений для каждого окна. Карта сообщений – это программа MFC, которая связывает сообщение с соответствующим обработчиком. Как любой объект карта сообщений должна быть объявлена. Но в данном случае это делается с помощью макроса DECLARE_MESSAGE_MAP(). Такой способ объявления объясняется тем, что карта сообщений это не объект С++.

Объявить какрту сообщений не значит получить к ней доступ. Для подключения карты сообщений имеется специальный макрос BEGIN_MESSAGE_MAP(). Внутри круглых скобок записывается имена классов окна-владельца сообщения и базовый класс. Например, для рассмотенной выше программы это выглядит так

BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd)

Точка с запятой в конце не ставится, т.к. это только имя макроса, а не оператор.

Теперь нужно указать какое сообщение мы ждем, чтобы его обработать. Пусть это будет нажатие левой кнопки мыши, его имя ON_WM_LBUTTONDOWN(). Сообщение к программе посткпит тогда, когда в пределах созданного окна будет нажата левая кнопка мыши. Ведь именно имя этого окна указано в качестве параметра карты сообщений.

Наконец, следует указать, что описание карты сообщения закончено. Для этого записывается

END_MESSAGE_MAP()

Итак, в вкарте сообщений мы указали какое сообщение мы собираемся обрабатывать. Возникает вопрос: а кто, или точнее какакой код будет вести обработку. Ответ таков. Обработчик должен быть создан программистом по определенным правилам. До объявления карты, т.е. перед макросом DECLARE_MESSAGE_MAP()должен быть указан прототип функции обработчика. Как обычно, сначала указывается возвращаемый тип, в данном случае его имя afx_msg. Далее указывается имя функции. Имя прототипа строится по следующему правилу: имя начинается с префикса On, далее идет имя сообщения без WM_. Для рассотренного примера это выглядит так

afx_msg OnLButtonDown(UINT nFlags, Cpoint point);

Сама функция обработчика, как всегда описывается в любом месте после описания класса.

void CMainWin::OnButtonDown(UINT nFlags, CPoint point){

/* Cstring класс MFC упрощающий работу со строками.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: