ビットマップの情報


ビットマップの大きさ

任意のビットマップを読みこみ表示するようなプログラムの場合
そのビットマップの大きさなどの情報が必要になります

ビットマップのハンドルから、各種の情報を取得することが可能です
GDI オブジェクトの詳細をえる GetObject() 関数を使用します

int GetObject(HGDIOBJ hgdiobj , int cbBuffer , LPVOID lpvObject);

hgdiobj には、情報を取得したい GDI オブジェクトのハンドルを指定します
ビットマップやブラシ、ペンなどの GDI オブジェクトを指定します

cbBuffer にはバッファのサイズを指定します
lpvObject で渡す構造体の大きさを sizeof で渡す方法が安全です
lpvObject にはオブジェクトの情報を格納するバッファへのポインタを指定します

lpvObject に渡すバッファは、hgdiobj で指定したオブジェクトで型が決まります
次のような対応になっています

GDI オブジェクトバッファ
HBITMAP BITMAP 構造体
HBITMAP
(CreateDIBSection() 関数で作成した場合 )
DIBSECTION 構造体
(cbBuffer に sizeof(DIBSECTION) を設定したとき)

または、BITMAP 構造体
(cbBuffer に sizeof(BITMAP) を設定したとき)
HPALETTE WORD 型
(論理パレットのエントリ数が格納されます)
HPEN
(ExtCreatePen() 関数で作成した場合)
EXTLOGPEN 構造体
HPEN LOGPEN 構造体
HBRUSH LOGBRUSH 構造体
HFONT LOGFONT 構造体

つまり、ビットマップの情報を得たい場合 hgdiobj にビットマップのハンドルを渡し
lpvObject に BITMAP 構造体のポインタを渡します
すると、ビットマップの情報が BITMAP 構造体に格納されるという仕組みです

戻り値は、成功すると
これを利用すれば、BITMAP 構造体の bmWidth と bmHeight に
ビットマップのハンドルで指定したビットマップの幅と高さが格納されます
//リソーススクリプト
KITTY BITMAP "test.bmp"
#include <windows.h>

LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
	HDC hdc , hBuffer;
	PAINTSTRUCT ps;
	RECT rect;
	static HBITMAP hBitmap;
	static BITMAP bmBitmap;

	switch (msg) {
	case WM_DESTROY:
		DeleteObject(hBitmap);
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		hBitmap = LoadBitmap(
				((LPCREATESTRUCT)lp)->hInstance ,
				TEXT("KITTY")
		);
		GetObject(hBitmap , sizeof (BITMAP) , &bmBitmap);		
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hwnd , &ps);
		hBuffer = CreateCompatibleDC(hdc);
		SelectObject(hBuffer , hBitmap);

		GetClientRect(hwnd , &rect);
		StretchBlt(
			hdc ,
			rect.right / 2 - bmBitmap.bmWidth / 4 , 
			rect.bottom / 2 - bmBitmap.bmHeight / 4 ,
			bmBitmap.bmWidth / 2 , bmBitmap.bmHeight / 2 ,
			hBuffer , 0 , 0 ,
			bmBitmap.bmWidth , bmBitmap.bmHeight ,
			SRCCOPY
		);

		DeleteDC(hBuffer);
		EndPaint(hwnd , &ps);
		return 0;
	}
	return DefWindowProc(hwnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow ) {
	HWND hwnd;
	MSG msg;
	WNDCLASS winc;
	
	winc.style		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");

	if (!RegisterClass(&winc)) return -1;

	hwnd = CreateWindow(
			TEXT("KITTY") , TEXT("Kitty on your lap") ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL ,
			hInstance , NULL
	);

	if (hwnd == NULL) return -1;

	while(GetMessage(&msg , NULL , 0 , 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}


このプログラムは、リソースから読みこんだビットマップを半分のサイズにし
クライアント領域の中央に配置するというプログラムです
クライアント領域のサイズと、ビットマップのサイズがわかればこのような処理が可能になります


GetObject()

int GetObject(HGDIOBJ hgdiobj , int cbBuffer , LPVOID lpvObject);

指定されたグラフィックオブジェクトの情報を取得します
lpvObject で NULL を指定したときは必要なバッファのバイト数を返します

hgdiobj - GDI オブジェクトを指定します
cbBuffer - バッファのサイズを指定します
lpvObject - バッファへのポインタを指定します。オブジェクトの情報が格納されます

戻り値 - バッファに格納した情報のバイト数、または必要なバイト数。失敗すると 0

GDI オブジェクトとバッファの対応は次のようになります

GDI オブジェクトバッファ
HBITMAP BITMAP 構造体
HBITMAP
(CreateDIBSection() 関数で作成した場合 )
DIBSECTION 構造体
(cbBuffer に sizeof(DIBSECTION) を設定したとき)

または、BITMAP 構造体
(cbBuffer に sizeof(BITMAP) を設定したとき)
HPALETTE WORD 型
(論理パレットのエントリ数が格納されます)
HPEN
(ExtCreatePen() 関数で作成した場合)
EXTLOGPEN 構造体
HPEN LOGPEN 構造体
HBRUSH LOGBRUSH 構造体
HFONT LOGFONT 構造体



前のページへ戻る次のページへ