Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Аппаратное обеспечение персонального компьютера

© Александр Фролов, Григорий Фролов
Том 33, М.: Диалог-МИФИ, 1997, 304 стр.

[Назад] [Содеожание] [Дальше]

Мышь Microsoft IntelliMouse

В 1997 году Microsoft выпустила новую мышь с названием Microsoft IntelliMouse, добавив в нее принципиально новый орган управления – небольшое колесо, расположенное между левой и правой клавишами мыши. Это небольшое, на первый взгляд, усовершенствование намного упрощает работу пользователей с приложениями Windows, в которых нужно просматривать длинные документы или выполнять плавное масштабирование изображений.

Колесо имеет двойное назначение.

Во-первых, оно служит вместо третьей кнопки, которая есть в трехкнопочных мышах типа Mouse System и совместимых с ними. Ранее Microsoft упорно игнорировала третью кнопку в приложениях Windows, однако как вы увидите, теперь положение несколько изменилось.

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

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

К сожалению, для использования возможности новой мыши вам не достаточно просто подключить ее к компьютеру и установить соответствующий драйвер. Программы MS-DOS и приложения Microsoft Windows версии 3.1 совсем не могут пользоваться колесом, принимая новую мышь как обычную двухкнопочную мышь Microsoft. Что же касается приложений Microsoft Windows 95 и Microsoft Windows NT, то в них необходимо предусмотреть обработку сообщений, создаваемых колесом.

Заметим, что все новые приложения, созданные Microsoft, такие как Microsoft Office 97 и Microsoft Visual C++ версии 5.0, умеют работать с мышью Microsoft IntelliMouse.

Для того чтобы воспользоваться колесом в старых приложениях, таких как Microsoft Word 7.0, вы можете применить условно-бесплатное приложение Flywheel, загрузив его из Internet с сервера Web, расположенного по адресу http://www.plannetarium.com. Это приложение преобразует сообщения от колеса в сообщения от вертикальной полосы просмотра и выполняет ряд других интересных функций.

Мы же в этой книге расскажем вам, как можно оорганизовать обработку сообщений от колеса мыши Microsoft IntelliMouse в своих приложениях.

Проверка наличия мыши Microsoft IntelliMouse

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

Способ проверки зависит от операционной системы.

Проверка в среде Microsoft Windows 95 и Microsoft Windows NT версии 3.51

В текущей на момент написания книги версии Microsoft Windows 95 драйвер мыши Microsoft IntelliMouse отсутствует. Если вы купили такую мышь, необходимо установить драйвер с дискеты, которая прилагается к мыши.

Для проверки наличия мыши с колесом в среде Microsoft Windows 95 вам следует сначала зарегистрировать сообщение с кодом MSH_WHEELSUPPORT, вызвав для этого функцию RegisterWindowMessage:


UINT uMSH_SUPPORT = 0;
uMSH_SUPPORT = RegisterWindowMessage(MSH_WHEELSUPPORT);

Идентификатор MSH_WHEELSUPPORT, а также другие идентификаторы, необходимые для программирования новой мыши, находятся в файле zmouse.h, который можно бесплатно переписать в составе Microsoft IntelliMouse SDK с сервера Microsoft с адресом http://www.microsoft.com.

Далее нужно определить идентификатор главного окна приложения MSWheel, которое устанавливается с дискеты, входящей в комплект мыши. Идентификатор определяется следующим образом:


HWND hwndMSHWheel  = NULL;
hwndMSHWheel = FindWindow(MSH_WHEELMODULE_CLASS, 
  MSH_WHEELMODULE_TITLE);

Если сообщение MSH_WHEELSUPPORT успешно зарегистрировано, а указанный выше идентификатор определен, можно послать сообщение MSH_WHEELSUPPORT в окно приложения MSWheel, вызвав для этого функцию SendMessage:


BOOL fWheel = FALSE;
if(uMSH_SUPPORT != 0 && hwndMSHWheel != 0)
{
  fWheel = 
    (BOOL)SendMessage(hwndMSHWheel, uMSH_SUPPORT, 0, 0);
}

Если мышь Microsoft IntelliMouse подключена, функция SendMessage возвратит значение TRUE, если нет – FALSE.

Проверка в среде Microsoft Windows NT версии 4.0

Операционная система Microsoft Windows NT версии 4.0 содержит драйвер мыши Microsoft IntelliMouse, поэтому установка дополнительных драйверов не требуется.

Проверить наличие мыши с колесом можно при помощи обычной функции GetSystemMetrics, передав ей в качестве параметра значение SM_MOUSEWHEELPRESENT:


if(!GetSystemMetrics(SM_MOUSEWHEELPRESENT))
{
  MessageBox(NULL, "Microsoft IntelliMouse not found",
  "Error message", MB_OK);
}

Если функция возвратит нулевое значение, значит мышь Microsoft IntelliMouse не подключена к компьютеру.

Определение величины свертки

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

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

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

Определение величины свертки в среде Microsoft Windows 95 и Microsoft Windows NT версии 3.51

В среде операционных систем Microsoft Windows 95 и Microsoft Windows NT версии 3.51 для определения величины свертки вначале необходимо зарегистрировать сообщение MSH_SCROLL_LINES:


UINT uMSH_SCROLL_LINES = 0;
uMSH_SCROLL_LINES = RegisterWindowMessage(MSH_SCROLL_LINES);

Затем это сообщение посылается приложению MSWheel с помощью функции SendMessage:


UINT uiScrollLines = 3;
uiScrollLines = 
  (BOOL)SendMessage(hwndMSHWheel, uMSH_SCROLL_LINES, 0, 0);

Функция возвращает величину свертки в строках или значение WHEEL_PAGESCROLL, если в параметрах драйвера мыши задано, что при вращении колеса мыши должна выполняться постраничная свертка.

Определение величины свертки в среде Microsoft Windows NT версии 4.0

Если приложение работает в среде операционной системы Microsoft Windows NT версии 4.0, то оно должно определять величину свертки с помощью функции SystemParametersInfo:


UINT uiScrollLines = 3;
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, 
  &uiScrollLines, 0);

Эта функция предназначена для определения различных системных параметров. В качестве первого параметра функции SystemParametersInfo передается значение SPI_GETWHEELSCROLLLINES, а в качестве третьего – адрес переменной типа UINT, в которую будет записана величина свертки.

Сообщение MSH_MOUSEWHEEL

Работа мыши Microsoft IntelliMouse в среде операционных систем Microsoft Windows 95 и Microsoft Windows NT версии 3.51 обеспечивается приложением MSWheel, которое устанавливается с дискеты, входящей в комплект мыши. При повороте колеса приложение MSWheel посылает сообщение MSH_MOUSEWHEEL в функцию главного окна приложения, над которым находится курсор мыши.

Перед тем как использовать это сообщение, его необходимо зарегистрировать функцией RegisterWindowMessage:


UINT uMSH_MOUSEEHEEL = 0;
uMSH_MOUSEEHEEL = RegisterWindowMessage(MSH_MOUSEWHEEL);

Ниже мы привели парамтеры сообщения MSH_MOUSEWHEEL:

Параметр

Описание

(short)wParam

Угол поворота

LOWORD(lParam)

Координата X курсора мыши относительно левого верхнего угла окна

HIWORD(lParam)

Координата Y курсора мыши относительно левого верхнего угла окна

Значение угла поворота изменяется дискретно с шагом 120. Если это значение положительно, колесо поворачивается в сторону пользователя, если отрицательно – в сторону монитора компьютера (это правило может быть изменено пользователем соответствующей настройкой параметров драйвера мыши).

Получив сообщение MSH_MOUSEWHEEL, функция главного окна приложения может обработать его самостоятельно или передать дочерним окнам.

Сообщение WM_MOUSEWHEEL

Сообщение WM_MOUSEWHEEL определено в операционной системе Microsoft Windows NT версии 4.0 и будет влкючено в новую версию операционной системы Microsoft Windows 95. По своему назначению оно аналогично сообщению MSH_MOUSEWHEEL, но имеет немного другие параметры:

Параметр

Описание

LOWORD(wParam)

Код виртуальной клавиши, нажатой в момент прихода сообщения

(short)HIWORD(wParam)

Угол поворота

(short)LOWORD(lParam)

Координата X курсора мыши относительно левого верхнего угла окна

(short)HIWORD(lParam)

Координата Y курсора мыши относительно левого верхнего угла окна

Код виртуальной клавиши может иметь следующие значения:

Код

Нажатая клавиша

MK_CONTROL

<Control>

MK_LBUTTON

Левая клавиша мыши

MK_MBUTTON

Средняя клавиша мыши

MK_RBUTTON

Правая клавиша мыши

MK_SHIFT

<Shift>

Другие сообщения от мыши Microsoft IntelliMouse

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

Подробное описание параметров всех этих сообщений вы найдете в 11 томе «Библиотеки системного программиста», который называется «Операционная система Microsoft Windows для программиста».

Приложение 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));
    }
  }
}
. . .

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

[Назад] [Содеожание] [Дальше]