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

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

Ввод с помощью мыши



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

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

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


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


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


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


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


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

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

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


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

Rambler's Top100

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

Описание

Показывается, как определять координаты мыши, используя WndProc().

Программа печатает в окне текущие координаты курсора мыши.

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

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

Исходный код

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


/*      Эта обучалка о получении ввода с помощью мыши в приложениях Win32.
      В частности, мы узнаем, как получать текущие координаты мыши. Мы получим
      эту информацию в WinProc(), проверяя сообщение WM_MOUSEMOVE.

      Это приложение достаточно простое. Каждый раз, когда мышь передвигается, мы
      будем отображать текущие координаты курсора (x,y) в центре экрана.
*/

#include <windows.h>
#include <stdio.h>

#define WIN_WIDTH 320
#define WIN_HEIGHT 240

#define class_name "GT_MouseInput"


// Эта функция будет печатать передаваемые координаты мыши в центре окна
void PrintMouseCoords(HWND hwnd, int xPos, int yPos);

// Стандартная 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;

    // В зависимости от сообщения, выполняем различные действия
    switch(message)
    {
            // Это сообщение, которое отправляется окну, когда двигается мышь. 
            case WM_MOUSEMOVE: 
            {
                  // Здесь мы обрабатываем получаемую из сообщения информацию

                  // "flags" содержит данные, говорящие, нажаты ли определенные
                  // клавиши, такие как CTRL. Подробнее об этом в конце файла.
                  int flags = wparam; 

                  int xPos = LOWORD(lparam);  // Дает нам положение X курсора
                                                         
                  int yPos = HIWORD(lparam);  // Дает нам положение Y курсора
                  
                  PrintMouseCoords(hwnd,xPos,yPos); // Печатаем это на экран
                        return 0;

                  // **Замечение**
                  //
                  // Вы можете также создать структуру POINTS - структуру Win32, которая
                  // содержит 'x' и 'y' определенные как SHORT (16-битные целые)
                  // вызвав этот макрос:
                  //
                  //      POINTS point = MAKEPOINTS(lparam); // "point" будет равно положению (x,y) мыши
                  
            }

            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);
}


// Печатает координаты мыши по центру окна
void PrintMouseCoords(HWND hwnd, int xPos, int yPos)
{
      
      HDC hdc = GetDC(hwnd); // Получаем контекст устройства

            // Проверка ошибок
            if(!hdc)
                  return; // Невозможно рисовать в окне без HDC, выходим из функции

      RECT rect;
      GetClientRect(hwnd,&rect); // Получаем клиент-область окна RECT

      // Закрашиваем окно (клиент-область) в белый цвет
      FillRect(hdc,&rect,(HBRUSH)GetStockObject(WHITE_BRUSH));

            // **Замечание**
            //
            // Что именно является клиент областью окна? Когда вы думаете об окне,
            // вам нужно представить его как два RECT, описывающих окно. Первый это
            // WINDOW RECT.  Как и говорит это название, он включает в себя все окно.
            // Второй это CLIENT RECT. Это та область окна, где все и рисуется.
            // Клиент область не включает в себя заголовок и рамку окна. Ее верхний
            // левый угол всегда начинается с (0,0) и считается относительно окна.
            // В этом приложении, клиент-область это прямоугольная область, которая
            // закрашена белым цветом и где отображаются координаты мыши.

      char buffX[128] = {0}; // char буфер для положения X
      char buffY[128] = {0}; // char буфер для положения Y

      // Заполняем оба буфера соответствующим текстом
      sprintf(buffX,"X Pos = %d",xPos);
      sprintf(buffY,"Y Pos = %d",yPos);

      /*      А здесь начинается математика. Чтобы отобразить текст с горизонтальным
            центрированием в окне, мы должны прибегнуть к помощи основ алгебры.
            Итак, мы хотим половину текста слева от центра окна, и половину текста
            справа от центра окна, и тогда он будет центрирован. Это дает нам
            такое уравнение:

            xStart = centerX - (длина текста / 2)
            yStart = все, что мы выберем, мы беспокоимся только о горизонтальном центрировании

            Но мы забыли одну вещь, ширину каждой буквы текста. Поэтому мы добавляем ее
            в уравнение:

            xStart = centerX - ((lengthOfText / 2) * widthOfACharacter)
            yStart = все, что мы выберем, мы беспокоимся только о горизонтальном центрировании

            Теперь, когда у нас есть уравнение, мы можем записывать переменные
            
            Сперва, получим центр окна. Обратите внимание на то, как мы используем 
            CLIENT rect, чтобы получить центр (x,y) окна.
      */

      int centerX = rect.right / 2;
      int centerY = rect.bottom / 2;

      // Теперь получим "ширину текста". Чтобы сделать это, используем структуру
      // TEXTMETRIC. TEXTMETRIC это структура Win32, в которой хранится вся
      // информация о шрифте.

      TEXTMETRIC textmetric;

      GetTextMetrics(hdc,&textmetric); 

      // Так мы заполняем "textmetric" информацией о текущем шрифте. Так как мы
      // не установили никакого определенного шрифта, структура заполнится
      // информацией о шрифте по умолчанию.

      // Сперва выведем координату х мыши, поэтому давайте используем наше
      // уровнение для вычисления координаты х начала рисования текста.
      // Вы увидите, что мы используем переменную "tmAveCharWidth" структуры
      // TEXTMETRIC. Она дает нам среднюю ширину символа, что как раз является
      // тем, что нам нужно.

      int start = centerX - ((strlen(buffX) / 2) * textmetric.tmAveCharWidth);

      // А теперь фактически выведем текст на экран.
      // Мы нарисуем его чуть выше вертикального центра экрана, т.е.
      // (centerY - 25)

      TextOut(hdc, start, centerY - 25, buffX, strlen(buffX));

      // Теперь выведем координату y мыши, поэтому пересчитаем начальное положение
      // текста

      start = centerX - ((strlen(buffY) / 2) * textmetric.tmAveCharWidth);

      // Рисуем текст на экране немного ниже вертикального центра окна
      
      TextOut(hdc, start, centerY + 25, buffY, strlen(buffY));

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

}


//      Больше о мыши --------------

/*      Как было обещано, вот информация о переменных, которые заполняются
      каждый раз, когда WinProc() получает сообщение WM_MOUSEMOVE.
      Важно отметить, что переменные (значение WPARAM) могут содержать
      любые комбинации нижеперечисленного:

      MK_CONTROL            Установлено, если нажата клавиша ctrl. 
      MK_LBUTTON            Установлено, если нажата левая кнопка мыши.
      MK_MBUTTON            Установлено, если нажата средняя кнопка мыши.
      MK_RBUTTON            Установлено, если нажата правая кнопка мыши.
      MK_SHIFT            Установлено, если нажата клавиша shift.

      Чтобы определить если, скажем, нажата клавиша ctrl, мы просто
      используем наших старых друзей - бинарные операторы, и сделаем
      что-то вроде этого:
 
      if(flags & MK_CONTROL)
            // Делать это, потому что нажата клавиша ctrl.
*/

/*
|  TheTutor                    
|  thetutor@gametutorials.com  
|  © 2000-2002 GameTutorials   
*/

// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

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

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

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

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

пример проекта дачного дома , www.maxistroy.com. керамогранит керама марацци . продажа керамогранита , бурение скважин для воды