Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Битовая карта lParam






 

  Равен 1, если клавиша отпущена, и 0, если она нажата
  Устанавливается, если клавиша уже была нажата перед посылкой сообщения
  Устанавливается в 1, если дополнительно нажата клавиша [Alt]
12¸ 9 Используется операционной системой
  Устанавливается в 1, если нажата клавиша функциональной или допол­нительной части клавиатуры
7¸ 0 Код клавиши (scan-код)

 

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

Чтобы обработать сообщения WM_CHAR, нужно добавить его в оператор switch в функции окна. Приведем оконную функцию, которая обрабатывает ввод символов с клавиатуры и отображает эти символы на экране:

 

char str[80] = " "; // Буфер для строки вывода

 

LRESULT CALLBACK WindowFunc (HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc;

switch (message)

{

case WM_CHAR: // Обработка нажатия клавиши

hdc=GetDC(hwnd); // Для получ. контекста устр-ва

TextOut(hdc, 1, 1, " ", 2); //Стереть старый код

sprintf(str, " %c", (char)wParam); // Записать

// новый символ в выходной буфер

TextOut (hdc, 1, 1, str, strlen(str)); // Вывод

// на экран

ReleaseDC (hwnd, hdc); // Освободить контекст

// устройства

break;

 

case WM_DESTROY: // Завершение программы

PostQuitMessage(0);

break;

default:

// Все сообщения, не обрабатываемые в данной

// функции, направляются на обработку

// по умолчанию

return DefWindowProc (hwnd, message,

wParam, IParam);

}

return 0;

}

 

Вас может удивить тот факт, что для такой простой задачи, как отображение введенного символа, требуется так много операторов. Объясняется это тем, что для вывода на экран Windows должен установить связь между Вашей программой и экраном. Такая связь устанавливается путем создания и получения в программе контекста устройства (Device Context, DC), что происходит при вызове функции GetDC(). В данный момент не важно, что представляет собой контекст устройства, – это будет рассматриваться в следующем разделе. Однако программа может вывести что-либо на экран только получив контекст устройства, а по окончании процесса вывода программа должна этот контекст освободить, вызвав ReleaseDC(). Одновре­менно в Windows может существовать конечное множество контекстов устройств, так что если программа не освобождает DC, у Windows вскоре не останется свободных ресурсов для предоставления DC и очередной вызов GetDC() вернет NULL.

Функции API GetDC() и ReleaseDC() имеют следующие прототипы:


HDC GetDCfHWND hwnd);

int ReleaseDC(HWND hwnd, HDC hdc);

 

GetDC() возвращает контекст устройства, ассоциированный с окном, дескриптор которого задается параметром hwnd. Тип HDC означает дескриптор контекста устройства.

ReleaseDC() возвращает ненулевое значение, если контекст устройства действительно был освобожден. Параметр hwnd задает дескриптор окна, ассоциированного с освобождаемым DC, a hdc – дескриптор освобожденного DC.

Функция API, выводящая символы на экран, называется TextOut(). Вот ее прототип:

 

BOOL TextOut(HDC hdc, int x, int у,

LPSTR lpstr, int nlength);

 

Функция TextOut() выводит на экран строку, задаваемую указателем lpstr, начиная с точки, координаты которой задаются параметрами х и у (по умолчанию эти координаты задаются в пикселах). Длина выводимой строки задается параметром nlength. Функция TextOut() возвращает ненулевое значение при успешном завершении.

В нашем примере каждый раз при получении сообщения WM_CHAR символ, введенный пользователем, преобразуется в строку длиной в один символ при помощи функции sprintf(), а затем выводится на экран при помощи TextOut(), начиная с позиции [1, 1].

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

Левый верхний угол рабочей области окна имеет координаты [0, 0]. Коор­динаты окна всегда задаются относительно начала рабочей области, а не экрана, поэтому вводимые символы всегда будут отображаться в верхнем левом углу рабочей области окна независимо от его положения на экране.

Причина первого вызова TextOut() заключается в необходимости стереть ранее выведенный символ. Поскольку Windows использует графический режим дисплея и символы шрифта могут иметь различный размер, вывод очередного символа на экран не обязательно приведет к полному стиранию предыдущего символа. Например, если Вы выведете символ i поверх w, часть w все равно останется на экране. (Попробуйте закомментировать первый вызов TextOut() – и увидите, каков будет результат.)

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

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

 

Пример 3-1. Приведем полную программу обработки ввода символов с клавиатуры.

 

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

#include < Windows.h>

#include < String.h>

#include < Stdio.h>

LRESULT CALLBACK WindowFunc(HWND, UINT,

WPARAM, LPARAM);

char szWinName[]=" МоеОкно"; // Имя класса окна

char str[80]=" "; // Буфер для строки вывода

int WINAPI WinMain(HINSTANCE hThisInst,

HINSTANCE hPrevInst,

LPSTR lpszArgs,

int nWinMode)

{

HWND hwnd;

MSG msg;

WNDCLASS wcl; // Определить класс окна

wcl.hInstance=hThisInst; // Дескриптор приложения

wcl.lpszClassName=szWinName; // Имя класса окна

wcl.lpfnWndProc=WindowFunc; // Функция окна

wcl.style=0; // Стиль по умолчанию

wcl.hIcon=LoadIcon(NULL, IDI_APPLICATION); // Иконка

wcl.hCursor=LoadCursor(NULL, IDC_ARROW); // Курсор

wcl.lpszMenuName=NULL; // Без меню

wcl.cbClsExtra=0; // Без дополнительной информации

wcl.cbWndExtra=0;

wcl.hbrBackground=

(HBRUSH)GetStockObject(WHITE_BRUSH); //Белый фон

if(! RegisterClass(& wcl)) // Регистрируем класс окна

return 0;

hwnd=CreateWindow(szWinName, // Создать окно

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

WS_OVERLAPPEDWINDOW, // Стиль окна

CW_USEDEFAULT, // x-координата

CW_USEDEFAULT, // y-координата

CW_USEDEFAULT, // Ширина

CW_USEDEFAULT, // Высота

HWND_DESKTOP, // Нет родител. окна

NULL, // Нет меню

hThisInst, // Дескриптор приложения

NULL); // Нет дополнит. аргументов

ShowWindow (hwnd, nWinMode); // Показать окно

UpdateWindow (hwnd); // и перерисовать

 

while(GetMessage(& msg, NULL, 0, 0)) // Запустить цикл

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

TranslateMessage(& msg); // Разреш. исп. клавиатуры

DispatchMessage (& msg); // Вернуть управл. Windows

}

return msg.wParam;

}

 

// Следующая функция вызывается операционной

// системой Windows и получает в качестве

// параметров сообщения из очереди сообщений

// данного приложения

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc;

switch(message)

{

case WM_CHAR: // Обработка нажатия клавиши

hdc=GetDC(hwnd); // Для получ. контекста устр-ва

TextOut(hdc, 1, 1, " ", 2); //Стереть старый код

sprintf(str, " %c", (char)wParam); //Запись символа

TextOut (hdc, 1, 1, str, strlen(str)); // Вывод

ReleaseDC (hwnd, hdc); // Освободить контекст

break;

case WM_DESTROY: // Завершение программы

PostQuitMessage (0);

break;

default:

// Все сообщения, не обрабатываемые в

// данной функции, направляются на обработку

// по умолчанию

return DefWindowProc(hwnd, message,

wParam, lParam);

}

return 0;

}

 

 

На рис. 3.1 представлено окно, создаваемое этой программой.

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

 

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

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

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.