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 руб./мес


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




 Битовые образы / Основы программирования с помощью библиотеки MFC / Visual C++

Битовые образы

Битовые образы - очень важная часть Windows. При хранении битовых образов в отдельном файле обычно используется расширение BMP (это единственный растровый формат, который напрямую поддерживается Windows). Часто они хранятся и в ресурсах. Битовые образы используются шире, чем все остальные ресурсы. Это объясняется наличием для них чрезвычайно мощной поддержки. Если Вы имеете большой опыт программирования только под DOS, то будете удивлены, узнав, что в Windows многие вещи, которые можно легко нарисовать программно, отображаются с помощью готовых битовых образов. Например, кнопки в нажатом и отпущенном состоянии, каркасы для целых окон. Так как компьютеры теперь имеют большие жесткие диски, то выбор между программным рисованием объекта и готовой картинкой часто однозначно решается в пользу последней.

Создание битовых образов

В MFC битовые образы описываются классом CBitmap. Для их создания можно использовать либо ресурсный редактор, либо импортировать в ресурсы готовые файлы BMP, созданные при помощи графических пакетов. Битовый образ является таким же ресурсом, как иконка или диалог. Нужно помнить, что область ресурсов с битовыми образами в EXE-файле может занимать большой размер. Но это не очень страшно, так как ресурсы автоматически не загружаются в память.

Вывод битового образа на экран

Когда битовый образ помещен в ресурсы, его можно выводить на экран. Но этот процесс не такой уж и простой.

Сначала необходимо создать объект типа CBitmap и с помощью функции LoadBitmap() загрузить в него битовый образ из ресурсов. Прототип функции таков:

 
 	BOOL CBitmap::LoadBitmap(LPCSTR ResourceName);
 
 
Параметр определяет строковый идентификатор ресурса.

После загрузки битового образа его нужно вывести в клиентскую область окна. Для этого обработчик WM_PAINT должен содержать приблизительно такой код (предполагается, что битовый образ загружен в объект backgroundBitmap):

 	CPaintDC clientDC(this);
 	CDC memDC; // Контекст памяти
 	// Создать совместимый контекст памяти 
 	memDC.CreateCompatibleDC(&clientDC);
 	// Выбрать битовый образ в контекст устройства
 	memDC.SelectObject(&backgroundBitmap);
 	// Получить характеристики битового образа в структуру BITMAP
 	BITMAP bmp;
 	backgroundBitmap.GetBitmap(&bmp); 
 	// Скопировать битовый образ из контекста памяти в контекст 
    // клиентской области окна
 	clientDC.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &memDC, 
         				0, 0, SRCCOPY);
 
Сначала объявляются два контекста устройства. Первый связан с текущим окном. Второй не инициализирован и предназначен для области памяти, в которой будет храниться изображение. Затем с помощью функции CreateCompatibleDC() этот контекст объявляется совместимым с контекстом окна. Функция имеет прототип:
 	
 	virtual BOOL CDC::CreateCompatibleDC(CDC *pDC);
 
 
Область памяти используется для вывода изображения на экран. Перед выводом на экран изображение должно быть выбрано в контекст устройства, связанный с областью памяти, с помощью функции SelectObject(). Мы используем ее вариант с прототипом:
 
 	CBitmap *CDC::SelectObject(CBitmap *pBmp);
 
 
Параметр - это указатель на объект битового образа.

Для вывода изображения на экран используется функция BitBlt(), которая копирует изображение из исходного контекста устройства в контекст, связанный с вызывающим функцию объектом. Прототип функции такой:

 	BOOL CDC::BitBlt(int x, int y, int Width, int Height, 
 	CDC *pSourceDC, int SourceX, int SourceY, 
 	DWORD RasterOpCode); 
 
Первые два параметра задают координаты начальной точки изображения. Размеры изображения задают следующие два параметра. Параметр pSourceDC является указателем на исходный контекст устройства. Координаты SourceX и SourceY задают левый верхний угол изображения и обычно равны 0. Последний параметр задает код операции, которая будет проделана при передаче изображения из одного контекста в другой. Мы будем использовать только значение SRCCOPY, в этом случае изображение просто копируется. Существует также много других констант.

Следует отметить, что указанным методом нельзя корректно выводить битовые образы более чем с 16 цветами в видеорежимах с 256 цветами. В режимах же HiColor и TrueColor без всяких проблем этим методом выводятся любые битовые образы. Так как на всех современных компьютерах используются по крайней мере HiColor режимы, мы не будем рассматривать ограничения худших режимов и манипуляции с палитрой. На сегодняшний день этот материал устарел.

Получение системных метрик

Мы будем рассматривать пример программы, которая выводит битовый образ, хранящийся в ресурсах, в клиентскую область окна. Нужно будет установить размеры клиентской области равными размерам битового образа. Но мы можем задать прямоугольник только для всего окна. Значит, придется рассчитывать размер окна по заданным размерам клиентской области. Это можно сделать, зная размеры элементов окна (заголовка, выпуклого бордюра и т. п.). Для этого используется API-функция:

 
 	int GetSystemMetrics(int Index);
 
 
Параметр определяет конкретное возвращаемое значение. Для наших целей нужны следующие значения:

SM_CXDLGFRAME Ширина бордюра окна без выпуклой рамки (плоского диалогового окна)
SM_CYDLGFRAME Высота бордюра окна без выпуклой рамки (плоского диалогового окна)
SM_CXEDGE Ширина трехмерной выпуклой рамки окна
SM_CYEDGE Высота трехмерной выпуклой рамки окна
SM_CYCAPTION Высота заголовка окна

В нашем случае, функция возвращает указанные размеры в пикселях.

Пример программы

 
 	bmpshow.hpp
 
 	#include "STDAFX.H"
 	class CMainWin: public CFrameWnd {
 	public:
 	CMainWin(CString Title, int HowShow = SW_RESTORE);
	afx_msg void OnPaint();
 	private:
 	// Объект битового образа
 	CBitmap backgroundBitmap;
 	DECLARE_MESSAGE_MAP()
 	};
 	class CApp: public CWinApp {
 	public:
	BOOL InitInstance();
 	};
 
 	bmpshow.cpp
 
 	#include "STDAFX.H"
 	#include <string.h>
 	#include "resource.h"
 	#include "BMPShow.HPP"
 	CApp App;
 	BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd)
 	ON_WM_PAINT()
 	END_MESSAGE_MAP()
 	CMainWin::CMainWin(CString Title, int HowShow)
 	{
 	backgroundBitmap.LoadBitmap("BACKGROUND_BITMAP");
 	// Прямоугольник, в котором должно разместиться окно.
 	RECT rect;
 	rect.top = 0;
 	rect.left = 0;
 	BITMAP bmp;
 	backgroundBitmap.GetBitmap(&bmp); 
 	// Определяем, чему должны быть равны размеры окна, 
 	// если размеры клиентской области должены быть 
 	// равны размерам картинки.
 	rect.right = rect.left + bmp.bmWidth 
                      + (GetSystemMetrics(SM_CXDLGFRAME) 
                      + GetSystemMetrics(SM_CXEDGE)) * 2;
 
 	rect.bottom = rect.top + bmp.bmHeight 
                       + GetSystemMetrics(SM_CYCAPTION) 
                       + (GetSystemMetrics(SM_CYDLGFRAME) 
                       + GetSystemMetrics(SM_CYEDGE)) * 2; 
 
 	this->Create(0, Title, 
                         WS_OVERLAPPED | WS_CAPTION | WS_DLGFRAME 
                         | WS_SYSMENU | WS_MINIMIZEBOX, rect, 0, 0);
 
 	// Если не задана позиция окна, то центрируем его
 	if(x0 < 0 || y0 < 0) 
 	this->CenterWindow();
 	this->ShowWindow(HowShow);
 	this->UpdateWindow();
 	}
 	afx_msg void CMainWin::OnPaint()
 	{ 
 	CPaintDC clientDC(this);
 	CDC memDC; // Контекст памяти
 	// Создать совместимый контекст памяти 
 	memDC.CreateCompatibleDC(&clientDC);
 	// Выбрать битовый образ в контекст устройства
 	memDC.SelectObject(&backgroundBitmap);
 	// Получить характеристики битового образа в структуру BITMAP
 	BITMAP bmp;
 	backgroundBitmap.GetBitmap(&bmp); 
 	// Скопировать битовый образ из контекста памяти в контекст 
    // клиентской области окна
 
 	clientDC.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &memDC, 0, 
 							     0, SRCCOPY);
 	}
 
 	BOOL CApp::InitInstance()
 	{
 	m_pMainWnd = new CMainWin("Вывод битового образа",
                                   SW_RESTORE); 
 	return TRUE;
 	}
 

Рис. 15. Пример программы, выводящей битовый образ из ресурсов

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