Приложение RTFPAD
В 22 томе «Библиотеки системного программиста», который называется «Операционная система Windows 95 для программиста» мы привели исходные тексты приложения RTFPAD. Это приложение представляет собой текстовый редактор, способный работать с документами в формате RTF. Такой документ может содержать шрифтовое оформление.
Для того чтобы продемонстрировать обработку сообщений от мыши Microsoft IntelliMouse, мы немного изменили приложение RTFPAD. В листинге 3.7 вы найдете исходный текст измененных функций WinMain и WndProc.
Обратите внимание, что при инициализации приложения мы определяем версию операционной системы с тем чтобы приложение могло работать как в среде Microsoft Windows 95, так и в среде Microsoft NT версии 4.0.
Листинг 3.7 (сокращенный). Файл rtfpad\rtfpad.с
// =====================================================
// Редактор текста RTFPAD, способный работать
// с мышью Microsoft IntelliMouse
//
// (C) Фролов А.В, 1996, 1997
//
// E-mail: frolov@glas.apc.org
// WWW: http://www.glasnet.ru/~frolov
// или
// http://www.dials.ccas.ru/frolov
// =====================================================
// Это определение нужно для того, чтобы при компилляции
// файла winuser.h были подключены определения
// идентификаторов SPI_GETWHEELSCROLLLINES
// и WM_MOUSEWHEEL
#define _WIN32_WINNT 0x0400
// Еще один способ определения этих же идентификаторов
//#ifndef SPI_GETWHEELSCROLLLINES
//#define SPI_GETWHEELSCROLLLINES 104
//#endif
//#ifndef WM_MOUSEWHEEL
//#define WM_MOUSEWHEEL WM_MOUSELAST+1
//#endif
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <richedit.h>
// Необходимо для определения значения константы
// UINT_MAX, которая используется в файле zmouse.h
#include <limits.h>
#include "resource.h"
#include "afxres.h"
// Файл определений для IntelliMouse
#include "zmouse.h"
#include "rtfpad.h"
// Код сообщения MSH_MOUSEEHEEL
UINT uMSH_MOUSEEHEEL = 0;
// Код сообщения MSH_SUPPORT
UINT uMSH_SUPPORT = 0;
// Код сообщения MSH_SCROLL_LINES
UINT uMSH_SCROLL_LINES = 0;
// Идентификатор окна для посылки сообщений
// приложению MSWheel
HWND hwndMSHWheel = NULL;
// Флаг наличия мыши Microsoft IntelliMouse
BOOL fWheel = FALSE;
// Количество строк свертки
UINT uiScrollLines = 3;
// Структура для определения версии
// операционной системы
OSVERSIONINFO osv;
HINSTANCE hInst;
char szAppName[] = "RtfEditApp";
char szAppTitle[] = "Rich Text Editor RtfPad";
HWND hwndEdit;
HINSTANCE hRTFLib;
// -----------------------------------------------------
// Функция WinMain
// -----------------------------------------------------
int APIENTRY
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;
hInst = hInstance;
hWnd = FindWindow(szAppName, NULL);
if(hWnd)
{
if(IsIconic(hWnd))
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
return FALSE;
}
// Определяем версию операционной системы
memset(&osv, 0, sizeof(OSVERSIONINFO));
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osv);
// Для Windows 95 и Windows NT версии 3.51 выполняем
// регистрацию сообщений
if( (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
((osv.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
(osv.dwMajorVersion < 4)))
{
// Регистрируем сообщение MSH_WHEELSUPPORT
uMSH_SUPPORT =
RegisterWindowMessage(MSH_WHEELSUPPORT);
// Определяем наличие мыши Microsoft IntelliMouse
hwndMSHWheel =
FindWindow(MSH_WHEELMODULE_CLASS,
MSH_WHEELMODULE_TITLE);
if(uMSH_SUPPORT != 0 && hwndMSHWheel != 0)
{
fWheel =
(BOOL)SendMessage(hwndMSHWheel, uMSH_SUPPORT, 0, 0);
}
if(!fWheel)
{
MessageBox(NULL, "MS Wheel not supported",
"Error message", MB_OK);
}
// Регистрируем сообщение MSH_MOUSEWHEEL
uMSH_MOUSEEHEEL = RegisterWindowMessage(MSH_MOUSEWHEEL);
if(!uMSH_MOUSEEHEEL)
{
MessageBox(NULL, "Error: RegisterWindowMessage",
"Error message", MB_OK);
return FALSE;
}
// Регистрируем сообщение MSH_SCROLL_LINES
uMSH_SCROLL_LINES =
RegisterWindowMessage(MSH_SCROLL_LINES);
// Определяем количество строк свертки
if(uMSH_SCROLL_LINES != 0 && hwndMSHWheel != 0)
{
uiScrollLines =
(BOOL)SendMessage(hwndMSHWheel,
uMSH_SCROLL_LINES, 0, 0);
}
}
// Для Windows NT версии 4.0 применяем другую методику
else
{
// Проверяем наличие мыши Microsoft IntelliPoint
if(!GetSystemMetrics(SM_MOUSEWHEELPRESENT))
{
MessageBox(NULL,
"Microsoft IntelliMouse not found",
"Error message", MB_OK);
}
// Определяем количество строк свертки
SystemParametersInfo(SPI_GETWHEELSCROLLLINES,
0, &uiScrollLines, 0);
}
hRTFLib = LoadLibrary("RICHED32.DLL");
if(!hRTFLib)
return FALSE;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = LoadImage(hInst,
MAKEINTRESOURCE(IDI_APPICONSM), IMAGE_ICON, 16, 16, 0);
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadImage(hInst,
MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 32, 32, 0);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU);
wc.lpszClassName = szAppName;
if(!RegisterClassEx(&wc))
if(!RegisterClass((LPWNDCLASS)&wc.style))
return FALSE;
hWnd = CreateWindow(szAppName, szAppTitle,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
if(!hWnd) return(FALSE);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// -----------------------------------------------------
// Функция WndProc
// -----------------------------------------------------
LRESULT WINAPI
WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Изменение положения колеса
short zDelta;
switch(msg)
{
HANDLE_MSG(hWnd, WM_CREATE, WndProc_OnCreate);
HANDLE_MSG(hWnd, WM_DESTROY, WndProc_OnDestroy);
HANDLE_MSG(hWnd, WM_COMMAND, WndProc_OnCommand);
HANDLE_MSG(hWnd, WM_SIZE, WndProc_OnSize);
HANDLE_MSG(hWnd, WM_SETFOCUS, WndProc_OnSetFocus);
default:
{
if(msg == WM_MOUSEWHEEL)
{
zDelta = (short)HIWORD(wParam);
if(zDelta < 0)
if(uiScrollLines != WHEEL_PAGESCROLL)
SendMessage(hwndEdit, EM_LINESCROLL, 0,
uiScrollLines);
else
SendMessage(hwndEdit, EM_SCROLL,
(WPARAM)(INT)SB_PAGEDOWN, 0);
else
if(uiScrollLines != WHEEL_PAGESCROLL)
SendMessage(hwndEdit, EM_LINESCROLL, 0,
-(LPARAM)uiScrollLines);
else
SendMessage(hwndEdit, EM_SCROLL,
(WPARAM)(INT)SB_PAGEUP, 0);
return 0L;
}
else if(msg == uMSH_MOUSEEHEEL)
{
zDelta = (short)wParam;
if(zDelta < 0)
if(uiScrollLines != WHEEL_PAGESCROLL)
SendMessage(hwndEdit, EM_LINESCROLL, 0,
uiScrollLines);
else
SendMessage(hwndEdit, EM_SCROLL,
(WPARAM)(INT)SB_PAGEDOWN, 0);
else
if(uiScrollLines != WHEEL_PAGESCROLL)
SendMessage(hwndEdit, EM_LINESCROLL, 0,
-(LPARAM)uiScrollLines);
else
SendMessage(hwndEdit, EM_SCROLL,
(WPARAM)(INT)SB_PAGEUP, 0);
return 0L;
}
return(DefWindowProc(hWnd, msg, wParam, lParam));
}
}
}
. . .
При обработке сообщений от колеса мыши мы определяем угол, на который было повернуто колесо. Если этот угол положительный, содержимое окна редактора сворачивается вверх, если отрицательный – вниз. Величина свертки определяется в момент инициализации приложения.