Приложение POINTER
Приложение POINTER отображет в своем окне изображения всех стандартных курсоров мыши и стандартных пиктограмм. Оно демонстрирует способ изменения формы курсора мыши, способ изменения пиктограммы приложения, отображаемой в левом верхнем углу последнего, а также способ управления курсором мыши при помощи клавиатуры.
Внешний вид главного окна приложения показан на рис. 6.2.
Рис. 6.2. Главное окно приложения POINTER
Исходные тексты приложения представлены в листинге 6.5.
Листинг 6.5. Файл pointer\pointer.c
// ================================================= // Определения // =================================================
#define INCL_WIN #define INCL_GPI #define INCL_WINDIALOGS #include <os2.h> #include <stdio.h> #include <stdlib.h> #include "pointer.h"
// Прототип функции окна приложения MRESULT EXPENTRY WndProc(HWND, ULONG, MPARAM, MPARAM);
// ================================================= // Глобальные переменные // =================================================
HAB hab; HWND hWndFrame; HWND hWndClient;
CHAR szAppTitle[] = "Mouse Poiter";
// Размеры пиктограммы курсора мыши LONG cxPointer, cyPointer;
// Размеры окна Client Window LONG cxClient, cyClient;
// ================================================= // Главная функция приложения main // =================================================
int main () { HMQ hmq; QMSG qmsg; BOOL fRc;
// Флаги для создания окна Frame Window ULONG flFrameFlags = FCF_SYSMENU | FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | FCF_SHELLPOSITION | FCF_TASKLIST | FCF_ICON;
// Имя класса главного окна CHAR szWndClass[] = "MOUSEPOINTER";
hab = WinInitialize (0); if(hab == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка инициализации", "Ошибка", 0, MB_ICONHAND | MB_OK); return(-1); }
// Создаем очередь сообщений hmq = WinCreateMsgQueue (hab, 0); if(hmq == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при создании очереди сообщений", "Ошибка", 0, MB_ICONHAND | MB_OK); WinTerminate (hab); return(-1); }
// Регистрация главного окна приложения fRc = WinRegisterClass (hab, szWndClass, (PFNWP)WndProc, 0, 0); if(fRc == FALSE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при регистрации класса главного окна", "Ошибка", 0, MB_ICONHAND | MB_OK); WinDestroyMsgQueue (hmq); WinTerminate (hab);
return(-1); }
// Создаем главное окно приложения hWndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE , &flFrameFlags, szWndClass, szAppTitle, 0, 0, ID_APP_FRAMEWND, &hWndClient); if(hWndFrame == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при создании главного окна", "Ошибка", 0, MB_ICONHAND | MB_OK); WinDestroyMsgQueue (hmq); WinTerminate (hab);
return(-1); }
// Устанавливаем новую пиктограмму // для главного окна WinSendMsg (hWndFrame, WM_SETICON , (MPARAM)WinQuerySysPointer (HWND_DESKTOP, SPTR_ICONINFORMATION, FALSE), NULL);
// Запускаем цикл обработки сообщений while(WinGetMsg (hab, &qmsg, 0, 0, 0)) WinDispatchMsg (hab, &qmsg);
WinDestroyWindow(hWndFrame); WinDestroyMsgQueue (hmq); WinTerminate (hab); return(0); }
// ================================================= // Функция главного окна приложения // =================================================
MRESULT EXPENTRY WndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { HPS hps; RECTL rec; POINTL ptl; LONG x, y; HPOINTER hptr; LONG xMouse, yMouse;
switch (msg) { case WM_CREATE : { // Определяем и сохраняем размеры пиктограмм cxPointer = WinQuerySysValue (HWND_DESKTOP, SV_CXPOINTER);
cyPointer = WinQuerySysValue (HWND_DESKTOP, SV_CYPOINTER);
// Расстояние между пиктограммами cxPointer += 5; return FALSE; }
case WM_PAINT : { // Получаем пространство отображения hps = WinBeginPaint (hWnd, NULLHANDLE, &rec);
// Закрашиваем область, требующую обновления WinFillRect (hps, &rec, CLR_WHITE);
// Рисуем стандартные изображения курсора мыши x = 0; y = cyClient - cyPointer; DrawMousePtr(hps, x, y, SPTR_ARROW);
x += cxPointer; DrawMousePtr(hps, x, y, SPTR_TEXT); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_WAIT); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_MOVE); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_SIZENWSE); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_SIZENESW); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_SIZEWE); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_SIZENS);
// Рисуем стандартные пиктограммы x = 0; y = cyClient - 3*cyPointer; DrawMousePtr(hps, x, y, SPTR_APPICON); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_ICONINFORMATION); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_ICONQUESTION); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_ICONERROR); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_ICONWARNING); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_ILLEGAL); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_FILE); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_MULTFILE); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_FOLDER); x += cxPointer; DrawMousePtr(hps, x, y, SPTR_PROGRAM);
// Освобождаем пространство отображения WinEndPaint (hps); return 0; }
case WM_MOUSEMOVE : { // Получаем идентификатор стандартной // пиктограммы SPTR_ICONINFORMATION hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_ICONINFORMATION, FALSE);
// Устанавливаем курсор мыши так, чтобы он // имел форму пиктограммы SPTR_ICONINFORMATION WinSetPointer (HWND_DESKTOP, hptr); return (MRESULT)TRUE; }
case WM_ERASEBACKGROUND : return(MRFROMLONG(1L));
// При изменении размеров окна приложения // перерисовываем его содержимое case WM_SIZE : { // Сохраняем размеры окна Client Window cxClient = SHORT1FROMMP (mp2); cyClient = SHORT2FROMMP (mp2);
// Обновляем окно Client Window WinInvalidateRect (hWnd, NULL, TRUE); return 0; }
// Выполняем эмуляцию мыши с помощью клавиатуры case WM_CHAR : { // Фильтруем сообщения, соответствующие отжатию // клавиш, а также сообщения от обычных клавиш if((CHARMSG(&msg) ->fs & KC_KEYUP) | (!(CHARMSG(&msg) ->fs & KC_VIRTUALKEY))) return 0;
// Определяем текущую позицию курсора мыши // в экранных координатах WinQueryPointerPos (HWND_DESKTOP, &ptl);
// Преобразуем экранные координаты в оконные WinMapWindowPoints (HWND_DESKTOP, hWnd, &ptl, 1);
// Сохраняем текущие оконные координаты курсора xMouse = ptl.x; yMouse = ptl.y;
// Изменяем координаты в соответствии с // виртуальным кодом нажатой клавиши switch(CHARMSG(&msg) -> vkey) { case VK_LEFT: { xMouse -= cxPointer; break; } case VK_RIGHT: { xMouse += cxPointer; break; } case VK_DOWN: { yMouse -= cyPointer; break; } case VK_UP: { yMouse += cyPointer; break; } case VK_HOME: { xMouse = cxPointer; yMouse = cyClient - cyPointer; break; } case VK_END: { xMouse = cxClient - cxPointer; yMouse = cyPointer; break; } default: break; }
// Не допускаем выхода курсора мыши за пределы // окна приложения ptl.x = max(min(xMouse, cxClient - 1), 0); ptl.y = max(min(yMouse, cyClient - 1), 0);
// Преобразуем оконные координаты в экранные WinMapWindowPoints (hWnd, HWND_DESKTOP, &ptl, 1);
// Устанавливаем новую позицию курсора мыши WinSetPointer Pos (HWND_DESKTOP, (SHORT) ptl.x, (SHORT) ptl.y);
return 0; }
default: return(WinDefWindowProc (hWnd, msg, mp1, mp2)); } }
// ================================================= // Функция рисования курсора мыши // =================================================
void DrawMousePtr(HPS hps, LONG x, LONG y, LONG lPtrId) { HPOINTER hptr;
// Получаем идентификатор стандартного курсора мыши hptr = WinQuerySysPointer (HWND_DESKTOP, lPtrId, FALSE);
// Рисуем изображение курсора мыши WinDrawPointer(hps, x, y, hptr, DP_NORMAL); }