DIB画像ファイルの透過処理について。

C/C++

12//ウィンドウ表示3#include <Windows.h>4#include <tchar.h>5#include <locale.h>6#include <stdlib.h>7#include <string.h>8#include <mmsystem.h>9 10//timeGetTime()を使うためのライブラリ11#pragma comment(lib, "Winmm.lib")12//TransparentBlt()を使うためのライブラリ13#pragma comment(lib, "Msimg32.lib")14 15/* Windows Init */16HINSTANCE hInstance;17HWND hwnd;18 19/* DIB */20static LPBYTE lpDIB;21static LPBITMAPINFO bmpInfo;22static LPDWORD PixelBit;23 24LPBYTE lpBMP;25LPBITMAPINFOHEADER lpbmpInfo;26LPBYTE lpPixelBit;27 28/* WindowSize */29#define WINDOW_WIDTH 64030#define WINDOW_HEIGHT 48031 32/* FPS */33static TCHAR time[255];34static DWORD frames = 0;35static DWORD beforeTime = 0;36static DWORD nowTime, progress;37 38/* アニメーション用 定数 */39#define FRAME_WIDTH 64 //表示するフレームの幅40#define FRAME_HEIGHT 64 //表示するフレームの高さ41#define FRAME_COUNT 4 //フレームの数42/* アニメーション用 変数 */43static DWORD animation = 0;44/* キャラクター画像分割 向き初期値 */45static DWORD Muki = 1;46/* アニメーション用画像 座標 初期値 */47static int px = 250;48static int py = 180;49 50/**/51HWND button1, button2;52 53//シーン遷移フラグ54BOOL titleScene = FALSE;55BOOL logoScene = FALSE;56BOOL Update = FALSE;57 58//Window Procedure Proto it.59LRESULT WindowProcedure(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);60 61/* シーン */62VOID DrawTitleScene();63VOID DrawLogoScene();64VOID UpdateGame();65 66/* ウィンドウの 初期化 */67int InitWindow(int window_width, int window_height)68{69 setlocale(LC_ALL, "");70 71 if (FindWindow(_T("Test"), NULL) != NULL)72 {73 MessageBox(NULL, TEXT("多重起動を確認しました"), NULL, MB_OK);74 }75 76 WNDCLASSEX w = {};77 MSG msg = {};78 79 w.cbSize = sizeof(WNDCLASSEX);80 w.lpfnWndProc = WindowProcedure;//コールバック関数の指定81 w.lpszClassName = TEXT("Test");//(適当)82 w.hInstance = GetModuleHandle(0);83 w.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);84 RegisterClassEx(&w);85 86 RECT wrc = { 0,0, window_width, window_height };87 AdjustWindowRect(&wrc, WS_OVERLAPPEDWINDOW, false);88 //ウィンドウオブジェクトの生成89 hwnd = CreateWindowEx(90 WS_EX_COMPOSITED,//ダブルバッファ(ちらつき抑制)91 w.lpszClassName,//クラス名指定92 _T("Win32API Sample"),//タイトルバーの文字93 WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX,//タイトルバーと境界線があるウィンドウ94 //サイズ固定↑95 CW_USEDEFAULT,//表示X座標はOSにお任せします96 CW_USEDEFAULT,//表示Y座標はOSにお任せします97 wrc.right - wrc.left,//ウィンドウ幅98 wrc.bottom - wrc.top,//ウィンドウ高99 nullptr,//親ウィンドウハンドル100 nullptr,//メニューハンドル101 w.hInstance,//呼び出しアプリケーションハンドル102 nullptr 103 );//追加パラメータ104 105 ShowWindow(hwnd, SW_SHOW);//ウィンドウ表示106 107 /* メイン・ループ */108 while (TRUE)109 {110 /* メッセージ*/111 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))112 {113 /* メッセージ処理(WM_QUIT が 来たら 抜ける */114 if (msg.message == WM_QUIT) break;115 TranslateMessage(&msg);116 DispatchMessage(&msg);117 }118 else119 {120 /* ループ内 処理 */121 if (Update == TRUE) UpdateGame();122 }123 }124 return (int)msg.wParam;125}126/**/127VOID DrawTitleScene()128{129 HDC hdc = GetDC(hwnd);130 131 RECT rect = { 0 };132 133 rect.right = 640;134 rect.bottom = 320;135 136 SetBkColor(hdc, RGB(0, 0, 0));137 SetTextColor(hdc, RGB(255, 255, 255));138 TextOut(hdc, 300, 100, TEXT("TITLE"), 5);139 140 //button を 表示141 ShowWindow(button1, SW_SHOW);142 ShowWindow(button2, SW_SHOW);143 144 ReleaseDC(hwnd, hdc);145}146 147VOID DrawLogoScene()148{149 HDC hdc = GetDC(hwnd);150 151 RECT rect = { 0 };152 153 rect.right = 640;154 rect.bottom = 320;155 156 // window の 現在の状態を得る157 //現在の状態を得た後、ボタンを消す。158 if (IsWindowVisible(button1)) ShowWindow(button1, SW_HIDE);159 if (IsWindowVisible(button2)) ShowWindow(button2, SW_HIDE);160 161 SetBkColor(hdc, RGB(0, 0, 0));162 SetTextColor(hdc, RGB(255, 255, 255));163 TextOut(hdc, 300, 100, TEXT("LOGO BY KAZ."), 12);164 165 ReleaseDC(hwnd, hdc);166}167/**/168VOID UpdateGame()169{170 /* window の 現在の状態を得る */171 /* 現在の状態を得た後、ボタンを消す。*/172 if (IsWindowVisible(button1)) ShowWindow(button1, SW_HIDE);173 if (IsWindowVisible(button2)) ShowWindow(button2, SW_HIDE);174 175 /* 時間 取得 */176 timeBeginPeriod(1);177 178 if (beforeTime == 0) beforeTime = timeGetTime();179 180 nowTime = timeGetTime();181 progress = nowTime - beforeTime;182 183 InvalidateRect(hwnd, NULL, FALSE);184 185 /* 1000 / 60 を求めることで、一回の更新を16.66ミリ秒(60FPS)に割り当てる */186 if ((frames * (1000 / 60)) > progress)187 {188 Sleep((frames * (1000 / 60)) - progress);189 }190 191 /* 1秒経過したとき.... */192 if (progress >= 1000)193 {194 beforeTime = nowTime;195 frames = 0;196 197 /* animation 変数が 定数 4 を超えた場合、animation 変数を初期値へ */198 if (++animation >= FRAME_COUNT)199 {200 animation = 0;201 }202 203 }204 /* frames カウント インクリメント */205 frames++;206 207 /* Key入力 */208 if (GetKeyState(VK_RIGHT) < 0)209 {210 Muki = 0;211 px++;212 InvalidateRect(hwnd, NULL, FALSE);213 }214 /* Key入力 */215 if (GetKeyState(VK_LEFT) < 0)216 {217 Muki = 2;218 px--;219 InvalidateRect(hwnd, NULL, FALSE);220 }221 /* Key入力 */222 if (GetKeyState(VK_UP) < 0)223 {224 Muki = 3;225 py--;226 InvalidateRect(hwnd, NULL, FALSE);227 }228 /* Key入力 */229 if (GetKeyState(VK_DOWN) < 0)230 {231 Muki = 1;232 py++;233 InvalidateRect(hwnd, NULL, FALSE);234 }235 236 timeEndPeriod(1);237 /* 時間 取得 終了 */238}239 240/* ウィンドウ プロシジャ */241LRESULT WindowProcedure(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)242{243 PAINTSTRUCT ps{};244 HDC hdc = {};245 246 static int iWidth, iHeight, iLength;247 int iFileSize, iOffset;248 int i, j;249 HANDLE hFile;250 DWORD dwRead;251 252 //create に ボタン253 if (msg == WM_CREATE)254 {255 /* button 定義 一覧 */256 button1 = CreateWindow(257 TEXT("BUTTON"), TEXT("START"),258 WS_CHILD | WS_VISIBLE | BS_FLAT,259 300, 300, 80, 30,260 hwnd, (HMENU)1,261 NULL, NULL262 );263 264 button2 = CreateWindow(265 TEXT("BUTTON"), TEXT("END"),266 WS_CHILD | WS_VISIBLE | BS_FLAT,267 300, 330, 80, 30,268 hwnd, (HMENU)2,269 NULL, NULL270 );271 272 /* 最初のシーン */273 logoScene = TRUE;274 275 hFile = CreateFile(TEXT("cHip.bmp"), GENERIC_READ, 0,276 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);277     /* ここから DIB・・・ */278 iFileSize = GetFileSize(hFile, NULL);279 280 lpBMP = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, iFileSize);281 282 (void)ReadFile(hFile, lpBMP, iFileSize, &dwRead, NULL);283 284 CloseHandle(hFile);285 286 lpbmpInfo = (LPBITMAPINFOHEADER)287 (lpBMP + sizeof(BITMAPFILEHEADER));288 289 iOffset = *(LPDWORD)(lpBMP + 10);290 291 lpPixelBit = lpBMP + iOffset;292 293 iWidth = lpbmpInfo->biWidth;294 iHeight = lpbmpInfo->biHeight;295 296 if (iWidth % 4 == 0)297 {298 iLength = iWidth * 3;299 }300 else301 {302 iLength = iWidth * 3 + (4 - (iWidth * 3) % 4);303 }304 305 lpDIB = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,306 sizeof(BITMAPINFO) + iWidth * iHeight * 4);307 308 bmpInfo = (LPBITMAPINFO)lpDIB;309 PixelBit = (LPDWORD)(lpDIB + sizeof(BITMAPINFO));310 311 if (bmpInfo)312 {313 bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);314 bmpInfo->bmiHeader.biWidth = iWidth;315 bmpInfo->bmiHeader.biHeight = iHeight;316 bmpInfo->bmiHeader.biPlanes = 1;317 bmpInfo->bmiHeader.biBitCount = 32;318 bmpInfo->bmiHeader.biCompression = BI_RGB;319 }320 321 for (i = 0; i < iHeight; i++)322 {323 for (j = 0; j < iWidth; j++)324 {325 if (PixelBit)326 {327 if (PixelBit[j + i * iWidth] != 0x00ffffff)328 {329 PixelBit[j + i * iWidth] =330 lpPixelBit[j * 3 + i * iLength, 3];331 }332 }333 }334 }335 336 HeapFree(GetProcessHeap(), 0, lpBMP);337 338 return 0;339 }340 //描画341 if (msg == WM_PAINT)342 {343 hdc = BeginPaint(hwnd, &ps);344 345 if (logoScene)346 {347 DrawLogoScene();348 }349 else if (titleScene)350 {351 DrawTitleScene();352 }353 else if (Update)UpdateGame();354 355 /* 描画関数のとき */356 if (Update == TRUE)357 {358 RECT rect;359 GetClientRect(hwnd, &rect);360 HBRUSH hbr = 361 (HBRUSH)GetStockObject(GRAY_BRUSH);362 FillRect(hdc, &rect, hbr);363 364 StretchDIBits(365 hdc,366 px,367 py,368 FRAME_WIDTH,369 FRAME_HEIGHT,370 FRAME_WIDTH * animation, 371 FRAME_HEIGHT * Muki, 372 FRAME_WIDTH,373 FRAME_HEIGHT,374 PixelBit,375 bmpInfo,376 DIB_RGB_COLORS,377 SRCCOPY 378 );379 380 // frames 表示(描画) //381 wsprintf(time, TEXT("FRAME:%d"), frames);382 SetBkColor(hdc, RGB(0,0,0));383 SetTextColor(hdc, RGB(255, 255, 255));384 TextOut(hdc, 10, 10, time, lstrlen(time));385 }386 EndPaint(hwnd, &ps);387 return 0;388 }389 if (msg == WM_LBUTTONUP)390 {391 if (logoScene)392 {393 logoScene = FALSE;394 titleScene = TRUE;395 }396 InvalidateRect(hwnd, NULL, TRUE);397 return 0;398 }399 if (msg == WM_COMMAND)400 {401 if (LOWORD(wparam) == 1)402 {403 if (titleScene)404 {405 titleScene = FALSE;406 Update = TRUE;407 //IsRun = TRUE;408 }409 }410 else if (LOWORD(wparam) == 2)411 {412 MessageBox(hwnd, _T("GAME END"), _T("CHECK IT"), MB_OK);413 SendMessage(hwnd, WM_CLOSE, 0, 0);414 }415 //再描画416 InvalidateRect(hwnd, NULL, TRUE);417 return 0;418 }419 if (msg == WM_DESTROY)420 {421 HeapFree(GetProcessHeap(), 0, lpDIB);422 423 PostQuitMessage(0);424 return 0;425 }426 return DefWindowProc(hwnd, msg, wparam, lparam);//規定の処理を行う427}428//entry Point429int main()430{431 /* Window size 初期化 */432 InitWindow(640, 480);433 return 0;434}

コメントを投稿

0 コメント