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

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

Контекст устройства



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

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

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


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


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


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


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


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

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

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


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

Rambler's Top100

Первая программа Win32 | Все обучалки раздела | Цветной текст

Описание

Дается понятие контекста устройства и демонстрируется, как использовать его в программировании Win32.

Программа создает и выводит на экран окно, закрашивая его в черный цвет с помощью контекста устройства.

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

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

Исходный код

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

/*      Эта обучалка о том, что такое контекст устройства. В программе Win32
      он обычно объявляется как HDC (handle to a device context, ссылка на
      контекст устройства). Итак, для начинающих, что же такое этот контекст
      устройства? MSDN определяет его как "структура, которая определяет
      набор графических объектов и их атрибутов, а также графические режимы,
      влияющие на вывод. Вдобавок, контекст устройства ссылается на физическое
      устройство вывода, его имя, драйвер и другие атрибуты."

      Это довольно хорошее определение. HDC (если видите HDC, думайте о контексте
      устройства) по существу является "указателем" на структуру, которая 
      содержит всю необходимую информацию о контексте устройства.

      Есть четыре типа контекстов устройства. Вот они:

      Display - поддерживает операции рисования на видеотерминал
      Printer - поддерживает запись/вывод на принтер
      Memory - поддерживает операции по работе с bitmap
      Information - поддерживает получение данных об устройстве.

      В целом, мы можем считать главными двумя контексты display и memory.
      В этой обучалке мы будем говорить только о display HDC.

      Теперь, когда у вас есть начальное понятие о том, что такое HDC, давайте
      поговорим о том, что делает эта простая программа. Все что мы хотим
      сделать - это создать окно, получить его HDC и, используя HDC, закрасить
      окно черным цветом. Не правда ли просто?
*/

#include <windows.h>

#define WIN_WIDTH 320
#define WIN_HEIGHT 240

#define class_name "GameTutorials_HDC"


// Стандартная 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 
                                      "Device context",            // Текст заголовка окна
                                      WS_OVERLAPPEDWINDOW,      // Стиль окна
                                      CW_USEDEFAULT,            // x левого верхнего угла окна (по умолчанию)
                                      CW_USEDEFAULT,            // y левого верхнего угла окна (по умолчанию)
                                      WIN_WIDTH,                  // Ширина окна в пикселях
                                      WIN_HEIGHT,                  // Высота окна в пикселях
                                      NULL,                              // Ссылка на "родительское окно" (у нас его нет) 
                                      NULL,                              // Ссылка на меню (у нас его нет)
                                      hinstance,                  // Ссылка на экземпляр окна (передается WinMain())
                                      NULL);                        // "Дополнительная информация" для передачи 
                                                                        // в WinProc (у нас ее нет)

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

      /*      А теперь мы получаем HDC, ссылку на контекст устройства DISPLAY.
            После этого мы сможем рисовать в нашем окне. Для любого типа
            графического устройства, компьютер должен знать, где рисовать.
            HDC окна как раз и говорит это компьютеру.      */
      HDC hdc = GetDC(hwnd);

            // Мы должны проверить и убедиться, что вызов сработал.
            // Если "hdc" равно NULL, то вызов не удался и мы должны
            // прервать программу.
            if(!hdc)
                  return EXIT_FAILURE; // Не удалось получить hdc окна

    ShowWindow(hwnd, ishow); // Показать окно (сделать его видимым)
    UpdateWindow(hwnd);             // Обновить окно (послать сообщение WM_PAINT. Мы поговорим
                                           // об этом в следующих обучалках. Просто знайте, что
                                           // так окно перерисовывается).

      /*      А теперь мы сделаем окно черным. Рассмотрим это шаг за шагом.
            Сперва нам нужно получить прямоугольник RECT который описывает
            CLIENT область окна (внутренняя область, в которую не входят края и заголовок).      */

      RECT rect;

      GetClientRect(hwnd, &rect);      // К счастью, эта функция как раз и сделает это.
                                                // Передаем ссылку на нужное окно и указатель
                                                // на RECT, и туда запишутся размеры CLIENT области.
      
      /*      Теперь, когда у нас есть RECT, мы вызываем заполнение этой области черным.
            Разберем параметры:

            hdc - контекст устройства, куда мы хотим рисовать (наше окно).
            &rect - адрес области в hdc, куда мы хотим рисовать (client область окна).
            (HBRUSH)GetStockObject(BLACK_BRUSH) - функция возвращает тип HBRUSH
            (благодаря преобразованию типов). Пока что запомните, что так мы задаем
            цвет. Попробуйте заменить BLACK_BRUSH на DKGRAY_BRUSH.      */

      FillRect(hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
   

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


      /*      ОЧЕНЬ важно всегда освобождать память, связанную с HDC. Win2K и выше
            сделают это за вас, но даже в этом случае это произойдет только
            в конце программы. Если вы будете вызывать GetDC() в цикле, то вы
            очень быстро израсходуете память. Чтобы освободить память, просто 
            сделайте это:      */

      ReleaseDC(hwnd,hdc);      // Освобождает память от HDC

      /*      А также очень важно освобождать память, связанную с классом окна,
            когда вы завершили работу с ним. Когда мы вызываем RegisterClassEx(),
            некоторое количество памяти выделяется для описания класса (WNDCLASSEX)
            окна, которое мы собираемся создать. Если мы не освободим эту память, то
            это будет плохо. Поэтому мы вызываем специальную функцию, для того, чтобы
            освободить память, занятую после вызова RegisterClassEx(). В большинстве
            случаев вы захотите сделать это в конце вашей Win32 программы.

            Примечание. Вам нужно вызывать UnregisterClass() только тогда, когда вы
            регистрируете класс окна функцией RegisterClassEx(). Более ранняя функция
            RegisterClass() (без Ex), не требует этого вызова. */

      UnregisterClass(class_name,hinstance);

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


// WinProc - оконная процедура
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    // В зависимости от сообщения мы выполняем различные вещи.
    switch(message)
    {
            /*    Как видите, мы сделали WinProc() очень простой.

                  Просто чтобы вы знали, в зависимости от того, как закрывается окно,
                  посылается одно из сообщений, либо WM_DESTROY либо WM_CLOSE, поэтому
                  я всегда проверяю оба и пишу соответствующий код закрытия.

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

        case WM_DESTROY:
            case WM_CLOSE:
            
                  PostQuitMessage(0);
             return 0;

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

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

/*      Очень важно, чтобы вы поняли, что такое HDC. В программировании Win32 вы увидите
      это снова и снова и снова и снова. Если вы все еще не совсем понимаете, то представьте
      себе HDC вот так:

      HDC это "дверь" к пикселям, из которых состоит окно. Используя DISPLAY DEVICE CONTEXT
      (это то, что возвращает вам GetDC()) вы можете рисовать в окне. Win32 позволяет
      рисовать в окне многими способами, FillRect() это один из них. В последующих обучалках
      вы увидите, что HDC постоянно используется для рисования в окне. Поэтому, все, чем является
      HDC - это средством для рисования в окне. */

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

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

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

Первая программа Win32 | Все обучалки раздела | Цветной текст

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

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

цена путевки в MIRAMARE , комплексное спортивное сооружение , При расчете каско онлайн калькулятор на нашем сайте определяет стоимость полиса для...