/*****************************************************************************
* *
* 基本的なwindowプログラム *
* 製作者:侵入部長 *
* *
******************************************************************************/
/*----------インクルード---------------------*/
#include <windows.h>
#include <stdio.h>
/*-----------マクロ--------------------------*/
#define ID_TIMER 100
/*----------プロトタイプ宣言-----------------*/
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE,int);
int FileRead(HDC);
int ReadFileError(const char *fname);
HDC ReadBitmap(char *szName,HDC hdc,int xWidth,int yHeight );
/*-----------構造体----------------------------------*/
struct Bitmap
{
char fname[256];/*原則として画像名は256文字(半角)まで*/
int x,y;/*POINT構造体でもOK*/
HDC hBitmap;
};
/*----------グローバル変数-------------------*/
char g_ClassName[]="BitmapRead"; //登録するクラス名
struct Bitmap g_bmp[10]; //ファイルの大きさやデータが入った構造体
HINSTANCE hInst;
/********************************************************
WinMain関数
C言語の授業でやってたときのmain関数ではなく、WinMain関数を使う。
一番最初に実行される関数で、必ずなくてはならない関数である。
*********************************************************/
int WINAPI WinMain(HINSTANCE hCurInst,HINSTANCE hPrevInst,LPSTR lpsCmdLine,int nCmdShow)
{
MSG msg;
BOOL bRet;
hInst=hCurInst;
if(!InitApp(hCurInst))
return FALSE;
if(!InitInstance(hCurInst,nCmdShow))
return FALSE;
while((bRet=GetMessage(&msg,NULL,0,0) != 0))
{
if(bRet == -1)
{
MessageBox(NULL,"GetMessageエラー","Error",MB_OK);
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
/*************************************************************
InitApp関数
ウィンドウの登録
戻り値:失敗するとFALSEが返る
***************************************************************/
ATOM InitApp(HINSTANCE hInst)
{
/*--------WINDCALSSEX構造体に格値を代入*/
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc; //プロシージャ名
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst; //インスタンス
wc.hIcon = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hCursor = (HCURSOR)LoadImage(NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL; //メニュー名
wc.lpszClassName= (LPCSTR)g_ClassName;
wc.hIconSm = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
return (RegisterClassEx(&wc));
}
/*************************************************
InitInstance関数
ウィンドウを作成する。
戻り値:失敗するとFALSEが返る
***************************************************/
BOOL InitInstance(HINSTANCE hInst,int nCmdShow)
{
HWND hWnd;
hWnd = CreateWindow(g_ClassName,
//タイトルバーに表示される文字列
"猫でもわかるWindowsプログラミング",
WS_OVERLAPPEDWINDOW &~WS_MAXIMIZEBOX, //ウィンドウの種類
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
CW_USEDEFAULT, //幅
CW_USEDEFAULT, //高さ
NULL, //新ウィンドウのハンドル、親を作るときはNULL
NULL, //メニューハンドル、クラスメニューを使うときはNULL
hInst, //インスタンスハンドル
NULL);
if(!hWnd)
return FALSE;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
/*************************************************************
WndProc関数
ウィンドウプロシージャ
どこからも呼ばれていない
コールバック関数という。(修飾子CALLBACKを付ける)
ユーザーが何かするたびにメッセージが送られてきて、
そのメッセージを処理するのがこの関数の目的である。
**************************************************************/
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp)
{
HDC hdc;
PAINTSTRUCT ps;
static int no,maxno;
switch(msg)
{
case WM_CREATE:
no=0;
SetTimer(hWnd,ID_TIMER,500,NULL);
hdc=GetDC(hWnd);
maxno=FileRead(hdc);
ReleaseDC(hWnd,hdc);
if(maxno==-1)
SendMessage(hWnd,WM_CLOSE,0,0);
break;
case WM_TIMER:
if(wp!=ID_TIMER)
break;
no++;
if(maxno<=no)
no=0;
InvalidateRect(hWnd,NULL,TRUE);
break;
case WM_PAINT:
BeginPaint(hWnd,&ps);
BitBlt(ps.hdc,0,0,g_bmp[no].x,g_bmp[no].y,g_bmp[no].hBitmap,0,0,SRCCOPY);
EndPaint(hWnd,&ps);
break;
case WM_CLOSE:
if(KillTimer(hWnd,ID_TIMER)==0)
MessageBox(NULL,"エラー","タイマーを介抱できません。",MB_OK);
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd,msg,wp,lp));
}
return 0;
}
/************************************************
FileRead関数
画像ファイル一覧表(bmp.txt)から
画像ファイルの名前、縦幅、横幅を取得し、
一覧表にある全ての画像ファイルを読み込む
引数
HDC hdc
ディスプレイのデバイスコンテキストハンドルが入る。
戻り値:
通常時は読み込んだ画像数
エラー時は-1
************************************************/
int FileRead(HDC hdc)
{
FILE *fp;
fp=fopen("bmp.txt","r");
if(fp==NULL)
return ReadFileError("bmp.txt");
/*画像ファイル数は最大10個までとする*/
for(int i=0;i<10;i++)
{
if(feof(fp)!=0)/*ファイルが終端に達したら(0以外だったら)読み込み終了*/
break;
/*画像のステータスを読み込む。*/
fscanf(fp,"%s",g_bmp[i].fname);
fscanf(fp,"%d",&g_bmp[i].x);
fscanf(fp,"%d",&g_bmp[i].y);
g_bmp[i].hBitmap=ReadBitmap(g_bmp[i].fname,hdc,g_bmp[i].x,g_bmp[i].y );
if(g_bmp[i].hBitmap==NULL)
{
i--;
break;
}
}
if(i<0)
return -1;
fclose(fp);
return i;
}
/********ReadBitmap関数*******************************************
ビットマップを読み込む
引数:
char *szName:ビットマップファイル名
HDC hdc:CreateCompatibleDCで使う(指定したデバイスと互換性を持たせるため)
int xWidth:ビットマップの横幅
int yHeight:ビットマップの縦幅
戻り値:
読み込んだ画像のデバイスコンテキストハンドル
読み込めなかったらNULLが返る。
************************************************************************/
HDC ReadBitmap(char *szName,HDC hdc,int xWidth,int yHeight )
{
HDC hBitmap;
HBITMAP hBmp;
hBmp=(HBITMAP)LoadImage(hInst,szName,IMAGE_BITMAP,xWidth,yHeight,LR_LOADFROMFILE);
if(hBmp==NULL)
{
ReadFileError(szName);
return NULL;
}
hBitmap=CreateCompatibleDC(hdc);
SelectObject(hBitmap,hBmp);
DeleteObject(hBmp);
return hBitmap;
}
/**************************************************
ReadFileError
読み込み失敗したときに呼び出す関数です。
引数:
const char *fname
読み込みに失敗したファイ名です。
戻り値
-1
****************************************************/
int ReadFileError(const char *fname)
{
char error[256];
wsprintf(error,"%sが読み込めません",fname);
MessageBox(NULL,"読み込みエラー",error,MB_OK);
return -1;
}