C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Битовые образы. Контекст памяти / Bitmap, Region / Графика

Битовые образы. Контекст памяти.

 

Автор статьи: Alexander E. Popov

Зачем вообще нужен bitmap? Существуют как минимум две проблемы, которые можно решить с помощью bitmap. Во первых: при рисовании в окне, полученный рисунок нигде не хранится, поэтому если вы довольно долго формировали рисунок, и вам понадобилось перерисовать окно, может получиться, что перерисовка занимает довольно много времени. Во вторых, например, вы в OnPaint случайным образом рисуете 10000 прямоугольников, после чего ваше окно перекрывет другое окно. Затем вы опять возвращаетесь к вашему приложению, но часть окна, которая была перекрыта другим окном, заново перерисовывется, но там уже возникают другие случайные прямоугольники. Поэтому нужно сохранять участки отображения в памяти.

Bitmap имеет определенную структуру: количество цветов, длина, ширина, количество плоскостей, ...

CBitmap b; //пока не имеет размеров

Bitmap имеет смысл создавать такой же, как область экрана, т.е. bitmap должен быть совместим с данным экраном, точнее с данным типом отображения.

b.CreateCompatibleBitmap( pDC, //указатель на CDC
                          w,     //ширина
                          h ) ;  //высота

Не существует битовых образов для обычных контекстов отображения (pDC - обычный контекст).

CBitmap b ;
CClientDC dc ( this ) ;
b.CreateCompatibleBitmap ( &dc, 1024, 768 ) ; 

Для того, чтобы рисовать на bitmap, нужно завести специальный контекст, называемый контекстом памяти, и выбрать этот bitmap в контекст памяти.

CDC memDC ; //оболочка MFC над объектом Windows. 
            //Сам объект создается  по Create.
memDC.CreateCompatibleDC(&dc);
//Выберем bitmap в контекст
memDC.SelectObject( &b ) ;
//Теперь можно рисовать на bitmap. Хотя сейчас bitmap заполнен чем 
//попало, поэтому если вы не будете заполнять полностью часть bitmap,
//выводимую на экран, то сначала bitmap нужно очистить, например 
//с помощью FillRect.
memDC.Rectangle ( 10, 10, 100, 100 ) ;

Выведем bitmap на экран:

dc.BitBlt( x, y, w, h, //параметры экрана (куда рисовать)
           &memDC,
           x1, y1, //координаты левого верхнего угла, откуда рисовать 
           SRCCOPY ) ; 

SRCCOPY учитывет только цвет источника, а цвет приемника и цвет текущей кисти игнорируются.
Если режимы отображения различны (например: MM_TEXT и MM_LOMETRIC), то произойдет преобразование координат (может возникнуть проблема).
Есть режим вывода bitmap, при котором он растягивается или сжимается:

dc.StretchBlt( x, y, w, h, //параметры экрана (куда рисовать)
           &memDC,
           x1, y1, w1, h1, 
           SRCCOPY ) ; 

Чтобы использовать BitBlt и StretchBlt, не обязательно иметь контекст памяти.

Перейти в нaчало страницы

Упражнения

  1. Нарисовать несколько объектов в окне. Поменять местами половинки окна.
    Готовый проект на VC++ 5.0.
  2. Поменять местами половинки экрана. Примечание: CreateDC ( "DISPLAY", 0, 0, 0) - контекст, позволяющий работать со всем экраном.
    Готовый проект на VC++ 5.0.
  3. Создать 10 000 случайных прямоугольников в bitmap. Последнее сделать в C...View::OnInitialUpdate. Bitmap и memDС создать как данные-члены C...View. memDC инициализировать в C...View::OnInitialUpdate.
    OnInitialUpdate:
    for (int i=0; i< 10000; i++) 
        memDC.Rectangle(...
    
    OnDraw: 
    pDC -> BitBlt( ..., &memDC, ...) ;
    Готовый проект на VC++ 5.0  
  4. Выполнить задание 3, добавив скролллинг. Для чего представление породить от CScrollView.
    В OnInitialUpdate добавть:
    CSize sizeTotal (1024, 768) ;
    CSize sizePage (512, 384) ;
    CSize sizeLine (30, 30) ;
    SetScrollSizes(MM_TEXT, sizeTotal, sizePagem sizeLine) ;
    Window пытается закрасить цветом кисти перед перерисовкой.  Чтобы этого
    избежать, в PreCreateWindow создать структуру класса с помощью
    AfxRegisterWndClass (необходимо присвоить нулевую кисть) и породить
    от него  окно. 
    Готовый проект на VC++ 5.0