Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
TPKS.docx
Скачиваний:
11
Добавлен:
16.03.2016
Размер:
51.33 Кб
Скачать

7. Створення головного меню програми (робота у редакторі ресурсів, варіанти підключення).

создать файл step6.rc

Далее на вкладку Resource. Там пусто. Мышку на папку, правую кнопку вниз, пункт меню Insert

В окне выбираем Menu и New. В результате в ресурсах появится меню. Создайте пункты меню. Пункт File и ниже Exit. Обязательно поменяйте идентификатор меню на IDR_MENU.

В списке файлов (WorkSpace -> FileView) вы не найдете resource.h, если необходимо добавьте его (Add File to Project). В этом файле будут находиться идентификаторы ресурсов. Добавляем в раздел описаний ссылку на файл с идентификаторами ресурсов.

......

#include "afxext.h" // MFC Расширения

#include "resource.h" // Идентификаторы ресурсов

#define IDC_MYBUTTON 100 // Идентификатор кнопки

......

Добавляем описание класса меню в класс рамки окна. Замечаете, на всё есть класс, это класс !!!

class CMainWnd : public CFrameWnd

{

public:

CMainWnd(); // Конструктор по умолчанию

afx_msg void OnLButtonDblClk(UINT, CPoint); // виртуальная процедура ответа на левую кнопку

afx_msg void OnRButtonDblClk(UINT, CPoint); // виртуальная процедура ответа на правую кнопку

afx_msg void OnKeyDown(UINT, UINT, UINT); // виртуальная процедура ответа на клавишу

int OnCreate(LPCREATESTRUCT lpCreateStruct); // эта функция вызывается при создании окна

~CMainWnd(); // Деструктор

private:

CStatic* MyStatic; // Указатель на объект надпись

CMyButton* MyButton; // Элемент управления кнопка

CEdit* MyEdit; // Указатель на объект поле редактирования

CStatusBar m_wndStatusBar; // класс панели состояния

CMenu m_wndMenu; // Это наш класс Меню

DECLARE_MESSAGE_MAP();// таблица откликов

};

Добавляем в процедуру создания окна команды создания меню:

int CMainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;

m_wndStatusBar.Create(this);

m_wndMenu.LoadMenu(IDR_MENU); // Загрузить меню из файла ресурса

SetMenu(&m_wndMenu); // Установить меню

return 0;

}

шпаргалка:

Объявить класс меню:

CMenu m_wndMenu;

Загрузить и установить меню:

m_wndMenu.LoadMenu(IDR_MENU);

SetMenu(&m_wndMenu);

Из конспекта:

MFC программа, зная id пунктов меню при помощи карты сообщений назначает обработчики пункта меню. а) изменения в карте сообщений BEGIN_MESSAGE_MAP (CMainWin, CFrameWnd) ON_COMMAND (ID_FILE_OPEN, OnOpen) ON_COMMAND(ID_FILE_EXIT, OnExit) END_MESSAGE_MAP б) добавление в классе главного окнаvoid OnOpen(); void OnExit(); в) реализовать обработчики void CMainWin::OnOpen() {MessageBox ("Item not defined", "Error", MB_ICON, STOP);} void CMainWin::OnExit(){SendMessage(WM_CLOSE);} г) #include <afxwin.h> #include "resource.h" д) подключить меню к окну: CMainWin::CMainWin(){Create(NULL, "Пример меню", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE (IDR_MENU1));}

8. Поняття контексту пристрою. Застосування контекстів пристрою. Обробка повідомлення wm_paint.

Контекст устройства

В программах Windows, прежде чем вывести что-либо на экран, необходимо получить контекст устройства, и весь вывод производить через него. Например, в Windows нет совершенно никакой возможности выводить точки прямо на экран, как это делалось в DOS. Контекст устройства - это достаточно условное название (даже для английского языка, device context), не отражающее сути понятия. На самом деле, это структура данных, обеспечивающая связь графических функций с драйвером конкретного устройства. Эта структура определяет состояние драйвера, и способ вывода графики. В MFC есть классы, инкапсулирующие контексты устройств, поэтому нам не придется работать с ними напрямую.

Например, в MFC можно получить контекст клиентской области окна, создав экземпляр класса CClientDС. Конструктор этого класса принимает один параметр - указатель на объект окна, обычно подставляется this. После создания этого объекта можно выводить графику в окно, используя функции-члены класса.

Сообщение WM_PAINT

Windows устроена таким образом, что за обновление содержимого окна отвечает программа. Например, если часть окна была перекрыта другим окном, а затем вновь открыта, или минимизированное окно было восстановлено, то окну посылается сообщение WM_PAINT. В ответ на него окно должно обновить свою клиентскую область.

Прототип обработчика WM_PAINT следующий:

afx_msg void OnPaint();

Макрокоманда называется ON_WM_PAINT(). Рассмотрим простой обработчик, который выводит строку "Привет" в клиентскую область по координатам x = 10, y = 20:

afx_msg void CMainWin::OnPaint()

{

CPaintDC paintDC(this);

paintDC.TextOut(10, 20, CString("Привет"));

}

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

Функция TextOut() предназначена для вывода текста в контекст устройства (в данном случае - в окно). При ее использовании по умолчанию первые два параметра определяют координаты верхнего левого угла текстовой строки. По умолчанию координаты представляют собой реальные пиксели, ось x направлена слева направо, ось y - сверху вниз. Эта функция перегруженная, наиболее удобный для нас вариант - когда третий параметр имеет тип CString. Этот класс входит в MFC и является очень удобной заменой для строк, завершаемых нулем. Он имеет много полезных функций - аналогов стандартных строковых функций, и поддерживает преобразования типов, в частности, из char* в CString (поэтому в примере можно было обойтись без явного создания объекта этого класса). Вы можете легко самостоятельно изучить этот класс и многие другие полезные классы общего назначения из состава MFC, пользуясь справочной системой Visual C++.

Большинство реальных окон (за исключением диалогов, которые мы рассмотрим позднее) должны обрабатывать сообщение WM_PAINT. Более того, если Вы хотите написать корректную программу, то весь вывод в окно должен осуществляться только в обработчике WM_PAINT, и никак иначе. Например, крайне нежелательно получать контекст устройства в обработчике сообщения мыши и пытаться там что-то выводить. Это будет работать в большинстве случаев, но далеко не всегда. Дело в том, что Windows может предоставить одновременно всем программам лишь очень небольшое число контекстов устройств (Windows 95 - всего пять). Поэтому при запросе контекста не из обработчика WM_PAINT создание класса контекста может потерпеть провал, если другие приложения уже заняли все контексты. Тогда выводить информацию будет вообще невозможно. Это может вылиться в непредсказуемое поведение программы. В случае же получения контекста из обработчика WM_PAINT, обязательно с помощью класса CPaintDC, Windows гарантирует наличие свободного контекста. На самом деле, Windows не пошлет программе это сообщение до тех пор, пока в системе не будет свободного контекста. К сожалению, эта проблема не так широко известна, и во многих книгах сплошь и рядом правило вывода информации только по сообщению WM_PAINT не соблюдается. Это вызвано тем, что описанная проблема не проявляется до тех пор, пока в системе не будет запущено несколько задач, постоянно что-то рисующих (кроме отображения видео). Но так одна из наших целей - научиться создавать надежные программы, то в методических указаниях мы будем придерживаться данной рекомендации. Также Вам рекомендуется делать это и в дальнейшем. Нужно отметить, что все среды визуального программирования действуют согласно этой рекомендации.

Генерация сообщения WM_PAINT

Так как мы решили весь вывод в окно организовать через сообщение WM_PAINT, то необходим способ принудительной отправки этого сообщения, если необходимо что-то вывести в окно. Это осуществляется с помощью функции со следующим прототипом:

void CWnd::InvalidateRect(LPRECT pRegion,

BOOL EraseBackground = TRUE);

Параметр pRegion задает область, которую нужно перерисовать. В большинстве программ эта область вообще не анализируется, поэтому этот параметр почти всегда равен 0. Параметр EraseBackground определяет, нужно ли перед отправкой сообщения закрасить окно фоном (по умолчанию белым). Мы будем почти всегда использовать параметр по умолчанию, так как это очень удобно для учебных примеров.

9. Обробка повідомлень таймера. Приклади реалізації. /**из конспекта/ Используется при синхронизации действия программы со временем. Чтобы работать с таймером, нужно его создать UINT CWnd::SetTimer(UINT nID, UINT nEllapse, void (CALLBACK*lpfuTimer)(HWND, UINT,UINT,DWORD)); указатель на функцию обработчик или NULL -> OnTimer(UINT); SetTimer(1,500,NULL); SetTimer(2,300,NULL); UINT CWnd::KillTimer (UINT nID); KillTimer(1);KillTimer (2); /**/

Сообщение WM_TIMER

В Windows существуют специальные объекты, называемые таймерами. Программа (точнее, окно) может запросить один или несколько таких объектов. После этого каждый таймер через регулярные заранее указанные промежутки времени будет посылать сообщение WM_TIMER. Они будут помещаться в очередь сообщений окна. Таким образом, в функции-обработчике этого сообщения можно выполнять некоторые действия через регулярные промежутки времени. Если создано несколько таймеров, то их можно различать по номерам, присвоенным им при запросе.

Для запроса таймера у системы используется следующая функция:

UINT CWnd::SetTimer(UINT Id, UINT Interval,

void (CALLBACK EXPORT *TFunc)(HWND, UINT, UINT, DWORD));

Третьим параметром пользуются очень редко, и обычно он равен 0. Мы не будем его использовать. Параметр Id задает уникальный идентификационный номер таймера. По этим номерам обычно различаются несколько созданных таймеров. Параметр Interval задает интервал между двумя посылками сообщений (интервал таймера) в миллисекундах. Разрешающая способность таймеров 55 мс, поэтому интервалы измеряются с такой точностью. Если даже задать значение интервала равным 1, то все равно будет использовано значение 55. Если задать 0, то таймер приостановит свою работу.

Сообщения таймера обрабатываются функцией:

afx_msg void OnTimer(UINT Id);

Все таймеры вызывают один и тот же обработчик. Узнать, какой таймер послал сообщение, можно с помощью параметра Id, в котором передается номер таймера.

(пример часов http://www.codenet.ru/progr/visualc/mfc/mfc3.php)

10. Вікна повідомлень, їх реалізація та використання.

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

Это простейшие диалоговые окна, предопределенные в системе. Для создания окна сообщения используется функция с прототипом:

int CWnd::MessageBox(LPCSTR MessageText,

LPCSTR WindowTitle = 0,

UINT MessageBoxType = MB_OK);

Параметр MessageText определяет само сообщение. Параметр WindowTitle - заголовок окна сообщения. И параметр MessageBoxType задает стиль окна, иконку, отображаемую слева от сообщения, и одну или несколько кнопок. Этот параметр задается комбинацией констант с помощью операции "|", начинающихся на префикс MB_. Все наборы кнопок заранее определены. Функция возвращает идентификатор нажатой кнопки: IDABORT, IDRETRY, IDIGNORE, IDCANCEL, IDNO, IDYES, или IDOK.

Функция MessageBox() выполняет все действия по созданию, отображению и удалению окна, а также обработку сообщений. Программист не должен об этом заботиться.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]