Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Проблемно-ориентированные вычислительные системы.-2

.pdf
Скачиваний:
5
Добавлен:
05.02.2023
Размер:
1.02 Mб
Скачать

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

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

Модальная диалоговая панель, тем не менее, позволяет пользователю переключиться на работу с другими приложениями. Если требуется запретить такую возможность переключения, это достигается использованием системных модальных диалоговых панелей, однако использовать это средство нужно с чрезвычайной осторожностью.

Итак, для создания модального диалога наиболее часто используется функция

int DialogBox(HINSTANCE hInst, LPCTSTR pTemplate, HWND hWndParent, DLGPROC pDlgFunc)

Эта функция создает диалоговое окно, используя ресурс шаблона pTemplate, и отображает эту панель как модальное диалоговое окно. Функция DialogBox() не возвращает управления до тех пор, пока диалоговое окно не будет закрыто пользователем. В точке вызова DialogBox() происходит блокировка окна, владеющего диалогом. Дескриптор этого окна передается через параметр hWndParent.

Не рекомендуется создавать модальные окна без владельца. Windows не разрушает и не скрывает таких диалоговых окон.

Закрытие модального диалога Поскольку окно-владелец заблокировано во время работы модального диалога,

единственно корректным способом уничтожения диалогового окна является саморазрушение в диалоговой процедуре, что достигается вызовом функции EndDialog().

if (nID == IDCANCEL) { EndDialog(hDlg, nID); return TRUE;

}

Эта функция не только закрывает диалоговую панель, но и разблокирует вызывающую функцию DialogBox(), которая передает в приложение, в качестве возвращаемого значения, параметр nID функции EndDialog(). Как правило, диалог завершает работу при нажатии кнопки. Ее идентификатор nID и возвращается в представленном выше фрагменте кода. Следовательно, приложение может знать, при нажатии какой кнопки произошло закрытие модального диалога.

Заметим, что идентификаторы IDOK и IDCANCEL, которые определены в заголовочном файле windows.h, занимают особое место для модальных диалогов. Дело в том, что все диалоги снабжается кнопкой “Cancel” для того, чтобы пользователь смог отменить внесенные изменения. Итак, при нажатии на кнопку “Cancel” генерируется сообщение WM_COMMAND с идентификатором IDCANCEL, которое и поступает в функцию диалога. Эта же ситуация возникает тогда, когда пользователь нажмет клавишу Esc.

Все диалоги снабжается также кнопкой “Ok” для того, чтобы пользователь смог принять внесенные изменения. При нажатии на эту кнопку генерируется сообщение WM_COMMAND с идентификатором IDOK, которое поступает в функцию диалога. Обработчик этого сообщения должен иметь вид:

if (nID == IDOK) {

// получить значения из элементов управления

EndDialog(hDlg, nID); return TRUE;

}

Кроме того, сообщение WM_COMMAND с идентификатором IDOK поступает и в том случае, если пользователь нажимает клавишу Enter в тот момент, когда выполняются

21

одновременно два условия: 1) ни одна из кнопок, расположенных в диалоговой панели, не имеет фокус ввода; 2) ни одна из кнопок не имеет стиль WS_DEFPUSHBUTTON.

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

Окно сообщения, с заголовком szCaption и выводимым текстом szText, создается с помощью функции MessageBox().

int MessageBox(HWND hWnd, LPCTSTR szText, LPCTSTR szCaption, UINT uType)

Как правило, параметром hWnd является дескриптор того окна –обычного или диалогового – которое создает окно сообщения. Если окно сообщения закрывается, то фокус ввода передается окну hWnd. Если дескриптор окна недоступен, или если приложению не нужно, чтобы фокус ввода получило одно из окон приложения, вместо этого дескриптора можно использовать значение NULL.

Четвертый параметр uType функции MessageBox() представляет собой набор битовых флагов.

Первая группа флагов указывает, какие кнопки будут отображены в окне сообщения, например, MB_OK, MB_OKCANCEL, MB_YESNO. Заметим, что окно сообщения может использовать максимум четыре кнопки.

Вторая группа флагов задает то, какая из этих четырех кнопок получит по умолчанию фокус ввода, например, MB_DEFBUTTONх, где х = 1..4.

Третья группа задает пиктограмму, которая появится в окне сообщения, например,

MB_ICONINFIRMATION – информационный значок, MB_ICONWARNING – значок напо-

минания, MB_ICONSTOP – значок критической ошибки, MB_ICONQUESTION – значок запроса. Пиктограмма по умолчанию не задается.

В зависимости от нажатой кнопки, приводящей к удалению панели, окно сообщений возвращает один из следующих идентификаторов: IDOK, IDCANCEL, IDYES, IDNO,

IDRETRY, IDIGNORE, IDABORT.

2.8. Технология сетевой обработки данных средствами MFC

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

Пояснения и указания.

Win32 API поддерживает два принципиально разных подхода при обмене информацией с файловой системой:

-потоковый ввод/вывод, пришедший из MS DOS;

-функции ядра Win32.

Потоковый ввод/вывод

22

Большинство программ на языке С, разработанных для MS DOS, использовало потоковый ввод/вывод, который базируется на структуре FILE и семействе функций с ней связанных. Напомним общую схему работы с файлом при использовании потокового ввода/вывода.

1.Файл открывается вызовом функции fopen(), которая возвращает указатель на структуру FILE либо в текстовом, либо в двоичном режиме. Если возникли ошибки при открытии файла, то этот указатель будет равен NULL.

2.Допустимы следующие операции с текстовым файлом: fgets() - чтение строки (до “\r\n”); fputs() - запись строки; fprintf() - форматированный вывод. Для бинар-

ного файла допустимы функции fread(), fwrite(), fseek() и ftell().

3.Файл обязательно нужно закрыть функцией fclose().

Эти функции обновлены для 32-х разрядной версии Windows. Это означает, что можно читать и записывать файл большими блоками информации за один прием, используя однократный вызов функций fread() и fwrite(). Таким образом, отпадает необходимость в использовании циклов при работе с файлами большого размера.

Однако имеются три ограничения:

1)потоковые функции работают только для файлов длиной менее 2 Гб;

2)эти функции не поддерживают разделенный доступ к файлу;

3)работа с файлом должна проводиться в одном обработчике Windows сообщения, т.е. указатель FILE на открытый файл не может передаваться как статическая переменная от одного участка кода к другому.

23

3. Рекомендации по выполнению практических работ 3.1. Объектный подход к разработке программных средств

Задание. Создать приложение, позволяющее при получении сообщения от таймера выводить символ * в случайном месте рабочей области окна с использованием случайного цвета. Необходимо вести обработку сообщений WM_CREATE, WM_DESTROY,

WM_PAINT, WM_TIMER.

Пояснения и указания.

Отображение содержимого окна WM_PAINT

Обработка сообщения WM_PAINT крайне важна для Windows программирования. Нужно помнить, что в мультипрограммной операционной системе в любой момент может потребоваться перерисовка любого, даже неактивного окна. Проще всего это можно сделать, сосредоточив всю работу по отрисовке в одном месте, которым и является обработчик сообщения WM_PAINT. Это сообщение сигнализирует окну, что вся его рабочая область или некоторая ее часть становится недействительной (invalid), и ее следует перерисовать.

Здесь нужно пояснить, что окно разделяется на неклиентскую и рабочую (клиентскую) области. К неклиентской части относится заголовок окна и его обрамление. Перерисовка этой области – забота Windows, поскольку операционная система “знает” о стилях каждого окна, а они то и определяют, что нужно нарисовать в неклиентской части. Вся внутренняя часть окна относится к клиентской области, вот ее то перерисовку вы и должны запрограммировать в обработчике WM_PAINT, поскольку Windows не может знать, чего хочет каждый программист.

Случаи генерации сообщения WM_PAINT

Перечислим основные ситуации, когда клиентская область становится недействительной.

При создании окна недействительна вся его рабочая область. Сообщение WM_PAINT помещается в очередь сообщений, когда приложение вызывает функцию

UpdateWindow().

Увеличение (но не уменьшение!) размеров окна, в стиле класса которого заданы флаги CS_HREDRAW и CS_VREDRAW, приводит к тому, что вся рабочая область также становится недействительной. Операционная система вслед за этим посылает в очередь сообщение WM_PAINT.

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

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

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

Функция InvalidateRect() объявлена следующим образом:

24

void InvalidateRect(HWND hwnd, const RECT* lprc, BOOL fErase)

Первый параметр – дескриптор окна, для которого выполняется операция. Второй

– указатель на структуру типа RECT, определяющую прямоугольную область, подлежащую обновлению. Если указатель равен NULL, вся клиентская область объявляется недействительной. Третий параметр указывает на необходимость стирания фона окна, если он задан как TRUE, фон окна подлежит стиранию.

Особенность сообщения WM_PAINT

Первая особенность сообщения WM_PAINT состоит в том, что оно является низкоприоритетным. Операционная система помещает его в очередь сообщений только тогда, когда там нет других необработанных сообщений.

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

Правила обработки WM_PAINT

Обработка сообщения WM_PAINT всегда начинается с вызова функции BeginPaint(), а заканчивается – вызовом функции EndPaint().

Функция BeginPaint() имеет прототип:

HDC BeginPaint (HWND hwnd, PAINTSTRUCT* lpPaint)

Первый параметр – дескриптор окна, а второй – указатель на структуру PAINTSTRUCT, поля которой содержат информацию, полезную для проведения профессиональной отрисовки в рабочей области окна. Так, поле RECT rcPaint представляет прямоугольник, охватывающий все области окна, требующие перерисовки. Ограничив свои действия по рисованию только этой прямоугольной областью, приложение, несомненно, ускоряет процесс перерисовки.

При обработке вызова BeginPaint(), Windows обновляет [или не обновляет, это зависит от последнего параметра, с которым была вызвана функция InvalidateRect() перед этим] фон рабочей области с помощью кисти, которая указывалась при регистрации класса окна. Поле fErase структуры PAINTSTRUCT указывает произведено ли перекрашивание фона клиентской области или нет. Знание этого может быть полезным, чтобы не делать повторной закраски в обработчике.

Возвращаемым значением BeginPaint() является дескриптор контекста устройства. Этот дескриптор необходим для вывода в рабочую область текста и графики. Заметим, что при использовании данного дескриптора контекста устройства приложение не может рисовать вне клиентской области.

Функция EndPaint(), принимающая те же параметры, что и BeginPaint(), выполняет обязательное освобождение дескриптора контекста устройства. Обработчик WM_PAINT заканчивается вызовом этой функции.

Отрисовка вне WM_PAINT

Функции BeginPaint() и EndPaint() используются только в обработчике WM_PAINT. Нужно воспользоваться другими функциями Win32 API, если вашему приложению требуется получить контекст устройства клиентской области окна вне WM_PAINT. Примерный фрагмент такого кода должен выглядеть следующим образом:

//Получить контекст

HDC hDC = GetDC(hWnd);

//операции с дескриптором контекста

//и его освобождение

ReleaseDC(hWnd, hDC);

25

После получения контекста и выполнения каких-либо операций, его обязательно нужно освободить посредством функции ReleaseDC().

3.2. Основы программирования для Windows

Задание. Создать приложение, в рабочей области окна которого выводится изображение переплетенных полосок. Ширина полосок и расстояние между полосками должно быть равно h.

Пояснения и указания.

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

Но какого окна? Ответ – окна, имеющего фокус ввода. Смысл этого двухступенчатого процесса – сохранение сообщений в системной очереди сообщений и дальнейшая их передача в очередь сообщений приложения – в синхронизации. Если пользователь нажимает клавиши клавиатуры быстрее, чем приложение может обрабатывать поступающую информацию, Windows сохраняет информацию о дополнительных нажатиях клавиш в системной очереди сообщений.

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

Именно таким образом операционная система корректно синхронизирует события клавиатуры.

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

Фокус ввода и активное окно Клавиатура должна разделяться между всеми приложениями, работающими под

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

Концепция фокуса ввода тесно связана с концепцией активного окна. Окно, имеющее фокус ввода – это либо активное окно, либо дочернее окно активного окна.

Определить активное окно достаточно просто:

Windows выделяет заголовок активного окна;

если у активного окна вместо заголовка имеется рамка диалога, то Windows выделяет ее;

если активное окно минимизировано, то Windows выделяет текст заголовка в панели задач.

Если активное окно минимизировано, то окна с фокусом ввода нет. Windows про-

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

Можно обрабатывать сообщения WM_SETFOCUS и WM_KILLFOCUS, чтобы определить какое окно имеет фокус ввода, однако эти сообщения носят чисто информирую-

26

щий характер. Программный интерфейс Windows содержит две функции, позволяющие узнать или изменить окно, владеющее фокусом ввода, GetFocus() и SetFocus().

Генерация клавиатурных сообщений

Сообщения, которые приложение получает от Windows о событиях, относящихся к клавиатуре, различаются на аппаратные (keystrokes) и символьные (characters). Такое положение соответствует двум представлениям о клавиатуре. Во-первых, клавиатуру можно считать набором клавиш. В клавиатуре имеется только одна клавиша <A>. Нажатие и отпускание этой клавиши представляют собой аппаратные события. Во-вторых, клавиатура также является устройством ввода, генерирующим отображаемые символы. Клавиша <A>, в зависимости от состояния клавиш <Ctrl>, <Shift> и <CapsLock>, может стать источником нескольких символов. Обычно, этим символом является строчная, латинская ‘a’. Если же нажата клавиша <Shift> или установлен режим <CapsLock>, то этим символом является прописная ‘A’. Если же нажата клавиша <Ctrl>, этим символом будет <Ctrl+A>.

Для сочетаний двух аппаратных событий, которые генерируют отображаемые символы, Windows посылает программе и аппаратные, и символьные сообщения. Некоторые клавиши не генерируют символов. Это такие клавиши, как клавиши переключения, функциональные клавиши, клавиши управления курсором и специальные клавиши, например, <Insert> и <Delete>. Для таких клавиш Windows вырабатывает только аппаратные сообщения.

Аппаратные сообщения

Когда пользователь нажимает клавишу, Windows помещает в очередь окна, имеющего фокус ввода, либо сообщение WM_KEYDOWN, либо сообщение WM_SYSKEYDOWN. Когда же клавиша отпускается, Windows посылает в очередь либо сообщение WM_KEYUP, либо сообщение WM_SYSKEYUP. Сообщения WM_SYS... вырабатываются при нажатии клавиш в сочетании с клавишей <Alt>.

Итак, WM_KEYDOWN и WM_KEYUP это несистемные аппаратные сообщения , а сис-

темные – WM_SYSKEYDOWN и WM_SYSKEYUP.

Обычно сообщения о нажатии и отпускании появляются парами. Однако, если пользователь оставит клавишу нажатой так, чтобы включился автоповтор, то Windows посылает оконной процедуре серию сообщений WM_KEYDOWN или WM_SYSKEYDOWN и только одно сообщение WM_KEYUP или WM_SYSKEYUP, когда в конце концов клавиша будет отпущена. Аппаратные сообщения клавиатуры являются асинхронными сообщениями, и становятся в очередь сообщений окна.

Системные аппаратные сообщения

WM_SYSKEYDOWN и WM_SYSKEYUP – системные аппаратные сообщения более важны для Windows, чем для приложений. Эти сообщения генерируются при нажатии клавиш в сочетании с клавишей <Alt>. Они вызывают опции меню программы или системного меню, или используются для системных функций, таких как смена активного приложения по <Alt+Tab>.

Программы обычно игнорируют системные аппаратные сообщения и передают их в функцию DefWindowProc(). Оконная процедура в конце концов получает другие сообщения, являющиеся результатом этих аппаратных сообщений клавиатуры, например, выбор меню.

Если приложение проводит обработку системных аппаратных сообщений, после этого обязательно передавайте их в DefWindowProc(), чтобы Windows могла использовать эти сообщения в своих целях. Если этого не сделать, то происходит полная блоки-

ровка всех операций с клавишей <Alt>.

27

Несистемные аппаратные сообщения

Для клавиш, которые нажимаются и отпускаются без участия клавиши <Alt>, генерируются несистемные сообщения WM_KEYDOWN и WM_KEYUP. Приложение может использовать или не использовать эти сообщения клавиатуры. Это не влияет на работу операционной системы, поскольку Windows их полностью игнорирует.

Битовые поля параметра lParam

Для всех – системных и несистемных – аппаратных сообщений клавиатуры 32-х разрядная переменная lParam, передаваемая в оконную процедуру, состоит из следующих полей:

Биты

Значение

00-15

счетчик повторений (repeat count);

 

равен числу нажатий клавиши. В большинстве случаев 1. Однако, если клави-

 

ша остается нажатой, а оконная процедура недостаточно быстра, чтобы обра-

 

батывать эти сообщения в темпе автоповтора, то Windows объединяет несколь-

 

ко аппаратных сообщений о нажатии клавиши в одно сообщение и соответст-

 

венно увеличивает счетчик повторений. При отпускании клавиши счетчик все-

 

гда 1.

16-23

скан-код OEM (Original Equipment Manufacturer scan code);

 

код клавиатуры, генерируемым аппаратурой компьютера.

 

Приложения Windows обычно игнорируют скан-код ОЕМ.

24флаг расширенной клавиатуры (extended key flag);

устанавливается в 1, если сообщение клавиатуры появилось при работе с дополнительными клавишами расширенной клавиатуры IBM. Расширенная клавиатура имеет функциональные клавиши сверху и отдельную комбинированную область клавиш управления курсором и цифр.

25-28 зарезервировано;

29код контекста (context code);

Устанавливается в 1, если нажата клавиша <Alt>. Этот разряд всегда равен 1 для системных аппаратных сообщений и 0 для несистемных аппаратных сообщений клавиатуры за исключением одного случая: если активное окно минимизировано, оно не имеет фокуса ввода, при этом все нажатия клавиш выра-

батывают сообщения WM_SYSKEYDOWN и WM_SYSKEYUP.

30флаг предыдущего состояния клавиши; 1 если клавиша была нажата перед этим;

31флаг состояния клавиши (transation state).

Виртуальные коды клавиш Гораздо более важным параметром аппаратных сообщений клавиатуры является

параметр wParam. В этом параметре содержится виртуальный код клавиши (virtual key code), идентифицирующий нажатую или отпущенную клавишу.

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

Символьные сообщения

28

Для того, чтобы символьные сообщения клавиатуры появились в очереди сообщений окна нужно дополнить цикл обработки сообщений приложения:

while(GetMessage(&msg, 0, 0, 0)) { TranslateMessage(&msg); DispatchMesage(&msg);

}

Функция GetMessage() по-прежнему заполняет поля структуры msg данными следующего сообщения из очереди, а DispatchMesage() отправляет msg на обработку в оконную процедуру. Между ними находится функция TranslateMessage(), преобразующая аппаратные сообщения клавиатуры в символьные сообщения в соответствии с состоянием драйвера клавиатуры, а также положением управляющих клавиш <Shift> и <CapsLock>. Именно благодаря TranslateMessage(), в очереди сообщений появляются символьные сообщения, а приложение сможет отличить <ф> от <A> при активном драйвере кириллицы. Символьное сообщение всегда будет следующим, после сообщения о нажатии клавиши, которое функция GetMessage() извлечет из очереди.

Существует четыре вида символьных сообщений – WM_CHAR и WM_DEADCHAR относятся к несистемным и приходят вслед за WM_KEYDOWN. Сообщения WM_SYSCHAR и WM_SYSDEADCHAR являются системными и вызваны появлением сообщения WM_SYSKEYDOWN.

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

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

ANSI.

Наиболее типичный обработчик сообщения WM_CHAR выглядит следующим обра-

зом:

case WM_CHAR: switch((char)wParam) {

case ‘b’: // получен символ Backspace //....

break; //....

case ‘\t’:

//....

break; case ‘A’:

//....

break; case ‘a’:

//....

break;

//....

}

return 0;

Определение состояния управляющих клавиш

Параметры wParam и lParam аппаратных сообщений клавиатуры ничего не сообщают о состоянии управляющих клавиш <Shift>, <Ctrl>, <Alt> и клавиш переключателей <CapsLock>, <NumLock>, <ScrollLock>. Приложение может получить текущее состояние любой виртуальной клавиши с помощью функции GetKeyState(). Например:

case WM_KEYDOWN:

// Нажата ли комбинация <Ctrl>+S ? if (wParam == 'S' &&

(0x8000 & GetKeyState(VK_CONTROL))) { // ваши действия

29

}

return 0;

Функция GetKeyState() не отражает состояние клавиатуры в реальном времени. Она позволяет узнать состояние клавиатуры на момент, когда последнее сообщение от клавиатуры было выбрано из очереди. Следовательно, ее можно использовать только в обработчиках клавиатурных сообщений. Недостаток? Это обращается преимуществом, потому что GetKeyState() обеспечивает возможность получения точной информации, даже если сообщение обрабатывается асинхронно, уже после того, как состояние переключателя было изменено.

Если действительно нужна информация о текущем положении клавиши, то можно использовать функцию GetAsyncKeyState().

3.3. ClassWizard и диалоговые панели

Задание. Вывод графика в окно. Изменение размера изображения при изменении размеров окна.

Создать приложение, в рабочей области окна которого выводится строка "График функции Cos(x) для x от -2*π до 2*π" и изображение этого графика. При изменении размеров окна размер изображения графика должен изменяться пропорционально.

Пояснения и указания.

Сообщение WM_DESTROY появляется в очереди сообщений одним из последних. Оно показывает, что Windows находится в процессе ликвидации окна в ответ на полученную от пользователя команду. Пользователь вызывает поступление этого сообщения, если нажмет на кнопке закрытия окна, выберет пункт “Закрыть” из системного меню или нажмет комбинацию клавиш Alt+F4.

Функция главного окна стандартно реагирует на это сообщение, вызывая функцию PostQuitMessage(0), которая ставит последнее для приложения сообщение WM_QUIT в очередь сообщений. Это заставляет функцию WinMain() закончить цикл обработки сообщений и выйти в систему, завершив работу приложения.

3.4. Архитектура Document-View

Задание. Создать приложение, в окне которого при нажатии клавиш-стрелок выводится маршрут, задаваемый пользователем. После нажатия клавиши "Enter" по заданному маршруту определяется кратчайший путь, который выводится другим цветом.

Пояснения и указания.

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

WM_TIMER.

Случаи применения таймера в Windows:

1.Режим автосохранения – таймер может предложить программе сохранять работу пользователя на диске, когда истекает заданный интервал времени.

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

3.Поиск другого приложения, запущенного из текущего.

30