Программирование для IBM OS2

         

Сообщение WM_CHAR


Обработчик сообщения WM_CHAR получает пространство отображения и выбирает в него шрифт с фиксированной шириной символов, вызывая функцию SetCourierFont.

Далее при помощи макрокоманды CHARMSG обработчик разбирает параметры сообщения WM_CHAR и записывает их в соответствующие поля структуры cm типа CHRMSG.

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

После отображения отформированной текстовой строки обработчик сообщения WM_CHAR восстанавливает шрифт и возвращает пространство отображения.

Затем содержимое всего окна за исключением строки заголовка сдвигается вверх при помощи функции WinScrollWindow . Прототип этой функции приведен ниже:

LONG WinScrollWindow ( HWND hwnd, // идентификатор окна LONG lDx, // величина сдвига вправо LONG lDy, // величина сдвига вверх PRECTL prclScroll, // область сдвига PRECTL prclClip, // область ограничения HRGN hrgnUpdateRgn, // область обновления PRECTL prclUpdate, // прямоугольная область обновления ULONG flOptions); // параметры сдвига

В нашем приложении эта функция используется сделующим образом:

WinScrollWindow (hWnd, 0, cyChar + cyDesc, &rec, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN );

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

Область свертки (т. е. область, в которой будет выполняться сдвиг), определяется содержимым полей структуры rec, для заполнения которой мы использовали функцию WinSetRect :

WinSetRect (hab, &rec, 0, 2 * cyChar, cxClient, cyClient);

Прототип функции WinSetRect приведен ниже:

BOOL WinSetRect ( HAB hab, // идентификатор блока Anchor-block PRECTL prclrect, // адрес структуры RECTL LONG lLeft, // левый край LONG lBottom, // нижний край LONG lRight, // правый край LONG lTop); // верхний край

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


Приложение выполняет обработку этого сообщения для дублирования функций мыши при помощи клавиатуры.



Так как сообщение WM_CHAR приходит и при нажатии, и при отжатии клавиш, наш обработчик фильтрует сообщения, пропуская только те, что соответствуют нажатиям. Кроме того, мы фильтруем сообщения от обычных символьных клавиш, которые не имеют виртуального кода клавиши:

if((CHARMSG (&msg) ->fs & KC_KEYUP) | (!(CHARMSG(&msg) ->fs & KC_VIRTUALKEY))) return 0;

После фильтрации обработчик сообщения WM_CHAR определяет текущие экранные координаты курсора мыши и преобразует их в оконные координаты, вызывая для этого функции WinQueryPointerPos и WinMapWindowPoints . Текущие оконные координаты курсора мыши сохраняютя в глобальных переменных xMouse и yMouse.

Далее наш обработчик сообщения WM_CHAR анализирует полученный код виртуальной клавиши, изменяя соответствующим образом значения глобальных переменных xMouse и yMouse.

Если были нажаты клавиши перемещения курсора влево или вправо, содержимое переменной xMouse, соответственно, уменьшается или увеличивается на ширину курсора мыши (увеличенную на 5 пикселов для обеспечения зазора при отображении). Аналогично, если пользователь нажимает клавиши перемещения курсора вверх или вниз, содержимое переменной yMouse, соовтетственно, увеличивается или уменьшается на величину высоты курсора мыши. Вы, разумеется, можете выбрать для своего приложения иной шаг изменения позиции курсора мыши.

Когда пользователь нажимает клавиши <Home> или <End>, курсор мыши устанавливается, соответственно, в верхний левый или правый нижний угол окна. Все остальные коды виртуальных клавиш фильтруются.

После изменения переменных xMouse и yMouse обработчик сообщения изменяет содержимое полей x и y структуры ptl таким образом, чтобы новые координаты курсора мыши не выходили за границы окна Client Window , размеры которого были определены при обработке сообщения WM_SIZE :

ptl.x = max(min(xMouse, cxClient - 1), 0); ptl.y = max(min(yMouse, cyClient - 1), 0);

Затем полученные таким образом оконные координаты преобразуются в экранные и используются для установки новой позиции курсора мыши.




Обычно в приложениях Presentation Manager вы можете работать с полосами просмотра не только при помощи мыши, но и при помощи клавиатуры. Для обеспечения такой возможности в нашем приложении предусмотрен обработчик клавиатурного сообщения WM_CHAR.

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

if(!(CHARMSG(&msg) ->fs & KC_VIRTUALKEY)) return 0; if(!(CHARMSG(&msg) ->fs & KC_KEYUP)) return 0;

Затем анализируется код виртуальной клавиши и в зависимости от него окну Client Window посылаются сообщения WM_HSCROLL или WM_VSCROLL с соответствующим кодом команды, например:

switch(CHARMSG(&msg) -> vkey) { case VK_LEFT: { WinSendMsg(hWnd, WM_HSCROLL, NULL, MPFROM2SHORT(0, SB_LINELEFT)); break; } case VK_RIGHT: { WinSendMsg(hWnd, WM_HSCROLL, NULL, MPFROM2SHORT(0, SB_LINERIGHT)); break; } . . . }



Содержание раздела