Школа создателей компьютерных игр

BannerDrive.ru
[Главная] [С чего начать?] [Дистанционное обучение] [Статьи] [Обучалки] [Книги] [Софт] [Форум] [Ссылки] [О сайте]

Ввод с помощью мыши часть 2



Подпишитесь на рассылку "Создание компьютерных игр"

Рассылки Subscribe.Ru
Создание компьютерных игр

Рассылка выходит раз в месяц.


Понравился сайт? Узнайте, как помочь сайту.


Рекомендуемые книги


Андре Ламот.
Программирование трехмерных игр для Windows. Советы профессионала по трехмерной графике и растеризации


Андре Ламот.
Программирование игр для Windows. Советы профессионала


Проголосуйте за сайт в рейтинге GameTop!
(нажмите на кнопку рейтинга)

GameTop - рейтинг игровых ресурсов. Портал Rolemancer (www.rolemancer.ru)

Не забывайте, что результаты рейтинга обновляются раз в неделю. Пожалуйста, голосуйте почаще!


Статистика посещаемости

Rambler's Top100

Ввод с помощью мыши | Все обучалки раздела | Ввод мышью и цвет фона

Описание

Объясняется, как работать с кнопками и колесом мыши.

Программа печатает в окне текст, в зависимости от нажатия кнопок мыши и вращения колеса.

Скачать обучалку (Visual C++ 6)

Работа программы

Исходный код

// Done by TheTutor -- 6/13/02
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

/*      Вновь обратимся к теме получения ввода с помощью мыши в приложении Win32.
      На этот раз мы узнаем, как проверять левую, правую кнопки мыши и колесо.

      Вот что будет делать наша программа:

      1)      Пока удерживается левая кнопка мыши, в центре экрана
            появится текст "Left MB"
      2)      Пока удерживается правая кнопка мыши, в центре экрана 
            появится текст "Right MB"
      3)      Вращение колеса мыши изменит цвет текста для обоих сообщений.
*/

// Сперва нужно заткнуть дыру MS. Если почитаете MSDN, то прочтете, что
// программировать колесо мыши можно если у вас Windows 98 и выше.
// Это неправда. В зависимости от вашей системы, вам может понадобиться
// определить колесо самим.
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 522 // Значение из Winuser.h
#endif

#include <windows.h>

#define WIN_WIDTH 320
#define WIN_HEIGHT 240

// Положение Y для отображения текста для левой и правой кнопок мыши
#define LMB_YPOS 80
#define RMB_YPOS 120

#define class_name "GT_MouseInput2"


// Эта функция печатает текст на экране начиная с "yPos", 
// горизонтально центруя его в окне и используя передаваемый цвет.
void TextOutCentered(HWND hwnd, char *text, int yPos, COLORREF color);

// Стандарнтая callback функция
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);


int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{
    HWND hwnd;      // Ссылка на наше окно
    MSG msg;      // В этой переменной будут сохраняться сообщения (такие, как
                        // щелчок мышью), которые может получить наше окно.
                        
    WNDCLASSEX wndclassex = {0};      // Это наш "класс окна". "EX" означает
                                                      // "extended style" (расширенный стиль),
                                                      // который дает нам больше опций, когда
                                                      // мы создаем наше окно (хотя мы и проигнорируем их).

      // Заполняем нужные нам поля
      wndclassex.cbSize = sizeof(WNDCLASSEX);            // Всегда должно быть установлено
      wndclassex.style = CS_HREDRAW | CS_VREDRAW; // Стиль класса окна
      wndclassex.lpfnWndProc = WinProc;                  // Указатель туда, где определена WinProc()
      wndclassex.hInstance = hinstance;                  // Ссылка на экземпляр нашего окна
      wndclassex.lpszClassName = class_name;            // Имя нашего класса окна
      wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // Устанавливаем фоновый
                                                                                                      // цвет окна - белый

    RegisterClassEx(&wndclassex);      // Регистрируем класс окна, чтобы вызовы CreateWindow()
                                                      // и CreateWindowEx() знали, какой класс окна использовать
                                                      // при создании окна

    hwnd = CreateWindowEx(NULL,                              // Дополнительные атрибуты окна, NULL - их нет
                                      class_name,                  // Имя, которое мы дали WNDCLASSEX     
                                      "Mouse",                  // Текст заголовка окна
                                      WS_OVERLAPPEDWINDOW,      // Стиль окна
                                      CW_USEDEFAULT,            // x левого верхнего угла окна (по умолчанию)
                                      CW_USEDEFAULT,            // y левого верхнего угла окна (по умолчанию)
                                      WIN_WIDTH,                  // Ширина окна в пикселях
                                      WIN_HEIGHT,                  // Высота окна в пикселях
                                      NULL,                              // Ссылка на "родительское окно" (у нас его нет) 
                                      NULL,                              // Ссылка на меню (у нас его нет)
                                      hinstance,                  // Ссылка на экземпляр окна (передается WinMain())
                                      NULL);                        // "Дополнительная информация" для передачи 
                                                                        // в WinProc (у нас ее нет)

            // Проверка ошибок
            if(!hwnd)
                  return EXIT_FAILURE; // Случилось что-то плохое!

    ShowWindow(hwnd, ishow); // Показать окно (сделать его видимым)
    UpdateWindow(hwnd);             // Обновить окно (нарисовать его)
                                          
    while(1)
      {
            // Получаем сообщения, если они есть
            if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                  if(msg.message == WM_QUIT)
                        break;
                        
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
            }
            else
            {
                  // Здесь проводим все сложные вычисления :)
            }
      }

      // Освободить память, выделенную WNDCLASSEX
      UnregisterClass(class_name,hinstance);

            return msg.wParam; // Выход из программы
}


// Оконная процедура
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
      PAINTSTRUCT ps;

      static unsigned char red, green, blue; // Цвета нашего текста

    // В зависимости от сообщения, выполняем различные действия
    switch(message)
    {
            case WM_CREATE:

                  // Устанавливаем цвет текста черный
                  red = green = blue = 0;
                        return 0;


            /*      Это сообщение, которое посылается, когда нажата левая кнопка мыши,
                  в то время, как курсор находится в клиент области окна (области окна,
                  которая не включает в себя заголовок и границы окна).
                  И когда мы получаем это сообщение, мы выведем на экран текст "Left MB".
            */
            case WM_LBUTTONDOWN:

                  TextOutCentered(hwnd,"Left MB",LMB_YPOS,RGB(red,green,blue));
                        return 0;


            /*      Это сообщение, которое посылается, когда левая кнопка мыши освобождается,
                  в то время, как курсор находится в клиент области окна. И когда мы получаем
                  это сообщение, мы отображаем тот же самый текст, но с использованием
                  цвета (255,255,255), что создает видимость стирания текста.
            */
            case WM_LBUTTONUP:

                  TextOutCentered(hwnd,"Left MB",LMB_YPOS,RGB(255,255,255));
                        return 0;

            /*      Это сообщение, которое посылается, когда нажата правая кнопка мыши,
                  в то время, как курсор находится в клиент области окна (области окна,
                  которая не включает в себя заголовок и границы окна).
                  И когда мы получаем это сообщение, мы выведем на экран текст "Right MB".
            */
            case WM_RBUTTONDOWN:

                  TextOutCentered(hwnd,"Right MB",RMB_YPOS,RGB(red,green,blue));
                        return 0;


            /*      Это сообщение, которое посылается, когда правая кнопка мыши освобождается,
                  в то время, как курсор находится в клиент области окна. И когда мы получаем
                  это сообщение, мы отображаем тот же самый текст, но с использованием
                  цвета (255,255,255), что создает видимость стирания текста.
            */
            case WM_RBUTTONUP:

                  TextOutCentered(hwnd,"Right MB",RMB_YPOS,RGB(255,255,255));
                        return 0;


            /*      Это сообщение посылается, когда вращается колесо мыши. Это сообщение
                  будет посылаться текущему активному окну. Получим из сообщения информацию,
                  которая нам необходима.
            */
            case WM_MOUSEWHEEL:
            {
                  int flags = LOWORD(wparam); // LOWORD параметра WPARAM содержит информацию о том,
                                                          // нажаты ли такие клавиши, как CTRL.
                                                            // Подробнее о "flags" внизу файла.

                  /*      HIWORD параметра WPARAM содержит информацию о расстоянии, на которое
                        вращается колесо, выражаемом числом WHEEL_DELTA, равном 120.
                        Положительное значение означает, что колесо вращается вперед, от
                        пользователя, отрицательное значение означает, что колесо вращается
                        назад, к пользователю. Больше информации об использовании WHEEL_DELTA
                        внизу этого файла.
                  */
            
                  short delta = (short)HIWORD(wparam); 

                  // Мы собираемся отслеживать, вращается ли колесо мыши вперед или назад.
                  // Если оно вращается вперед, мы прибавим 5 к значанию цвета.
                  // Если оно вращается назад, мы отнимем 5 от значения цвета.
                  int amount = (delta >= 0) ? 5 : -5;

                  // Если нажата клавиша CTRL
                  if(flags & MK_CONTROL)
                        red += amount; // Изменим красную составляющую цвета

                  else if(flags & MK_SHIFT) // А если нажата клавиша SHIFT
                        green += amount; // Изменим зеленую составляющую цвета

                  else // В противном случае изменим синюю составляющую цвета
                        blue += amount;

                  // Если нажата левая кнопка мыши
                  if(flags & MK_LBUTTON)
                        TextOutCentered(hwnd,"Left MB",LMB_YPOS,RGB(red,green,blue));

                  // Если нажата правая кнопка мыши
                  if(flags & MK_RBUTTON)
                        TextOutCentered(hwnd,"Right MB",RMB_YPOS,RGB(red,green,blue));

                  return 0;

                  // **Замечание**
                  //
                  // Также из сообщения может быть получена следующая дополнительная информация:
                  //
                  // int xPos = LOWORD(lparam); // горизонтальное положение курсора
                  //
                  // int yPos = HIWORD(lparam); // вертикальное положение курсора
            }

            case WM_PAINT:

                  BeginPaint(hwnd,&ps);
                  EndPaint(hwnd,&ps);
                        return 0;
      
        case WM_DESTROY:
            case WM_CLOSE:
            
                  PostQuitMessage(0);
             return 0;

    } // конец switch(message)

    return DefWindowProc(hwnd, message, wparam, lparam);
}


// Эта функция делает большинство "грязной работы". Она печатает текст
// на экран горизонтально центрируя его, начиная с "yPos".
// Текст печатается цветом, передаваемым COLORREF.
void TextOutCentered(HWND hwnd, char *text, int yPos, COLORREF color)
{
      HDC hdc = GetDC(hwnd); // Получаем контекст устройства окна

            // Проверка на ошибку
            if(!hdc)
                  return;

      RECT rect;
      GetClientRect(hwnd,&rect); // Получаем RECT клиент области окна
      
      TEXTMETRIC textmetric; // Структура, содержащая информацию о шрифте
      GetTextMetrics(hdc,&textmetric); // Заполняем TEXTMETRIC информацией о шрифте нашего окна
                                                      

      // Устатавливаем цвет текста согласно с передаваемым в функцию
      SetTextColor(hdc,color);
      
      // Вычисляем начальную координату Х отображения текста.
      // (rect.right / 2) равняется центру X окна.
      int xPos = (rect.right / 2) - ((strlen(text) / 2) * textmetric.tmAveCharWidth);

      // Выводим текст на экран
      TextOut(hdc, xPos, yPos, text, strlen(text));

      ReleaseDC(hwnd,hdc); // Всегда освобождайте HDC

}


// Колесо неудачи...
/*
      К сожалению, вам "потенциально" приходится делать кое-что особенное, чтобы
      заставить работать колесо мыши (да, можете винить в этом MS).

      Посмотрим на код, который мы используем для WM_MOUSEWHEEL, и вот что он делает:

      
            #ifndef WM_MOUSEWHEEL // Это говорит "Хорошо, если то, что, как утверждает MS,
                                            // определено, на самом деле не определено, то надо что-то
                                            // с этим сделать"
                                            
            #define WM_MOUSEWHEEL 522 // Мы определяем значение согласно с тем, чему оно
                                                  // должно равняться.
                                                  // Мы берем его из Winuser.h
            #endif

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

      Если вам интересно узнать, почему без этого ничего не работает, откройте winuser.h.
      Вы увидите код, который не позволяет ничему работать. Я настоятельно рекомендую НЕ
      изменять winuser.h. Просто делайте так, как в этой обучалке.

      Кстати, без этих изменений я не смог скомпилировать обучалку в Win98 и Win2000,
      используя VC++ 6.0

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

      *Подсказка* посмотрите WM_NCLBUTTONDOWN (и подобные) в MSDN

*/
/*
|  TheTutor                    
|  thetutor@gametutorials.com  
|  © 2000-2002 GameTutorials   
*/
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

Скачать обучалку (Visual C++ 6)

Ввод с помощью мыши | Все обучалки раздела | Ввод мышью и цвет фона

[Главная] [С чего начать?] [Дистанционное обучение] [Статьи] [Обучалки] [Книги] [Софт] [Форум] [Ссылки] [О сайте]

Copyright © 2003-2005 Евгений Казеко. Все права защищены. E-mail: evgeniy@kazeko.com

Балки металлические двутавровые , Любые межкомнатные двери: межкомнатные двери подольск. , ремонтируйте iPhone 3g в Спектре.