ファイル名 bmpv.h

#define IDEDIT 101
#define IDREAD 102
#define IDSIZE 103

ファイル名 bmpv.rc

#include <windows.h>
#include "bmpv.h"
#include "bmpv.dlg"

ファイル名 bmpv.dlg

bmp viewerのダイアログ
bmpv DIALOG 6, 13, 199, 127
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |
    WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME 
CAPTION "簡易 BMP Viewer"
FONT 12, "System"
BEGIN
    EDITTEXT           IDEDIT, 4, 3, 133, 12, ES_AUTOHSCROLL
    PUSHBUTTON "読込", IDREAD, 139, 2, 30, 14
    PUSHBUTTON "サイズ", IDSIZE, 171, 2, 26, 14
END

ファイル名 bmpv.c

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bmpv.h"
#ifdef WIN32
	#define fmalloc(size) malloc(size)
	#define ffree(ptr)    free(ptr)
#else
	#define fmalloc(size) MAKELONG(0,GlobalAlloc(GMEM_FIXED,size))
	#define ffree(ptr)    GlobalFree((HGLOBAL)HIWORD(ptr))
#endif
LPBITMAPINFOHEADER lpbi; /* bitmap-info-header構造体へのポインタ */
int offBits;             /* DIBヘッダーからビットマップまでのオフセット */

int ReadDib(char *filepath){
	unsigned long size;
	HFILE	       fh;   /* file_handle */
	BITMAPFILEHEADER   bf;   /* bitmap-file-header構造体(実体)       */

	fh = _lopen(filepath, OF_READ);
	if (fh == HFILE_ERROR) return 1;
	/* BITMAPFILEHEADERを読み取る */
	if (_lread (fh, (LPSTR)&bf, sizeof (bf)) != sizeof(bf))
		{_lclose(fh); return 2;}
	if (bf.bfType != 0x4d42)  /* 'BM' */
		{_lclose(fh); return 3;}
	/* メモリ確保 */
	ffree(lpbi);
	size=bf.bfSize-sizeof(BITMAPFILEHEADER);
	lpbi = fmalloc(size);
	if (lpbi==NULL)
		{_lclose(fh); return 4;}
	/* BITMAPを読み取る */
	if (_hread (fh, (LPSTR)lpbi, size) != size)
		{_lclose(fh); return 5;}
	offBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);
	_lclose(fh);
	return 0;
}
#ifdef __cplusplus
extern "C"
#endif
BOOL FAR PASCAL bmpview(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
	RECT		Rectangle;
	static int mode, error=1;
	int height=40;/*コントロールの高さ。本当は実行時に取得すべき*/
	char buf[260], filepath[260];
	PAINTSTRUCT ps;
	HDC hdc;
	switch(msg){
	case WM_COMMAND:
		switch((WORD)wParam) {
		case IDREAD:
			GetDlgItemText(hDlg, IDEDIT, filepath, sizeof(filepath));
			/* ファイルからDIBをロード */
			if ((error=ReadDib(filepath))!=0) {
				strcpy(buf,"BMPファイルの読み込みに失敗しました。\n");
				switch(error){
				case 1:	sprintf(buf+strlen(buf), "ファイル '%s' を開けません。", filepath); break;
				case 2:	sprintf(buf+strlen(buf), "ファイルヘッダーが読めません。");         break;
				case 3:	sprintf(buf+strlen(buf), "このファイルはBMPではありません。");      break;
				case 4:	sprintf(buf+strlen(buf), "ファイルが大きすぎます。");               break;
				case 5:	sprintf(buf+strlen(buf), "読み込みエラーが発生しました。");         break;
				}
				MessageBox(hDlg, buf, "エラー", MB_ICONSTOP | MB_OK);
			}
			InvalidateRect(hDlg, NULL, TRUE);
			break;
		case IDSIZE:
			mode = !mode;
			InvalidateRect(hDlg, NULL, TRUE);
			break;
		case IDCANCEL:		/* システムメニューの「クローズ」 */
			EndDialog( hDlg, wParam );
			break;
		}
		break;
	case WM_PAINT:
		GetClientRect(hDlg, (LPRECT)&Rectangle);
		hdc = BeginPaint(hDlg, &ps);
		SetStretchBltMode(hdc, COLORONCOLOR);
		if (error==0)
			if (mode)
				StretchDIBits(hdc,		   		   /* 出力先 */
					0,							   /* 出力先のX座標 */
					height,                        /* 出力先のY座標 */
					Rectangle.right,			   /* 出力先の横幅 */
					Rectangle.bottom-height,       /* 出力先の高さ */
					0,				               /* ソースのX座標 */
					0,                             /* ソースのY座標 */
					(int)lpbi->biWidth,		   /* ソースの横幅 */
					(int)labs(lpbi->biHeight),   /* ソースの高さ */
					(LPSTR)lpbi + offBits,	   /* BMPのBYTE配列へのポインタ */
					(LPBITMAPINFO)lpbi,		   /* BMPのBITMAPINFO構造体へのポインタ */
					DIB_RGB_COLORS,					   /* カラー指定 */
					SRCCOPY
				);
			else
				SetDIBitsToDevice(hdc,			/* 出力先 */
					0,					 		/* 出力先の左上角のX座標 */
					height,					  	/* 出力先の左上角のY座標 */
					lpbi->biWidth,	 		/* 横幅 */
					labs(lpbi->biHeight),	 	/* 高さ */
					0,				 			/* ソースの左上角のX座標 */
					0,               			/* ソースの左上角のY座標 */
					(UINT)0,                	/* 最初のスキャンライン */
					(UINT)labs(lpbi->biHeight),/* スキャンライン数 */
					(LPSTR)lpbi + offBits,     /* BMPのBYTE配列へのポインタ */
					(LPBITMAPINFO)lpbi,        /* BMPのBITMAPINFO構造体へのポインタ */
					DIB_RGB_COLORS			   /* カラー指定 */
				);
		EndPaint(hDlg, &ps);
		break;
	case WM_INITDIALOG:
		return TRUE;/* SetFocusしたらfalse */
	default:
		return FALSE;
	}
	return TRUE;
}
int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdshow){
	DLGPROC lpProc = (DLGPROC)MakeProcInstance((FARPROC)bmpview, hinst);
	DialogBox(hinst, "bmpv", NULL, lpProc);
	FreeProcInstance((FARPROC)lpProc);
	return 0;
}
戻る