/* ビットマップの合成 1999/ 7/27 宍戸 輝光 */ #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); BOOL readBMP(int); void mixBMP(void); HINSTANCE hInst; HWND hwnd; DWORD dwWidth,dwHeight,dwLength,dwCount; BOOL loaded[2],fTimer=FALSE; LPBYTE lpBuf[2],lpBMP[2]; LPBITMAPINFO lpInfo[2]; char* fn[]={"test1.bmp","test2.bmp"}; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASSEX wndclass ; hInst=hInstance; /* プロセスのハンドルを保存 */ wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); RegisterClassEx (&wndclass); hwnd = CreateWindow ("CWindow","ビットマップの合成", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,560,480, NULL,NULL,hInstance,NULL); ShowWindow (hwnd,iCmdShow); /* ウインドウを表示 */ UpdateWindow (hwnd); /* 再描画 */ while (GetMessage (&msg,NULL,0,0)) { /* メッセージループ */ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static HWND hwDoB; switch (iMsg) { case WM_CREATE: if (!(readBMP(0) && readBMP(1))) { /* ビットマップ読み込み */ MessageBox(hwnd,"ファイルを読み込めませんでした", "エラー",MB_OK); DestroyWindow(hwnd); } hwDoB=CreateWindow("Button","合成開始", /* ボタン作成 */ WS_CHILD | WS_VISIBLE,16,8,96,32,hwnd, (HMENU)0,hInst,NULL); break; case WM_COMMAND: switch (LOWORD(wParam)) { case 0: /* 合成開始ボタン */ /* タイマーセット */ dwCount=0; SetTimer(hwnd,1,300,NULL); fTimer=TRUE; EnableWindow(hwDoB,FALSE); break; } break; case WM_TIMER: mixBMP(); break; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); if (loaded[0]) /* ビットマップが読み込まれていれば */ StretchDIBits(hdc,4,48,dwWidth,dwHeight, 0,0,dwWidth,dwHeight,lpBMP[0],lpInfo[0], DIB_RGB_COLORS,SRCCOPY); /* DIBを画面に描画 */ EndPaint(hwnd,&ps); break; case WM_DESTROY : if (loaded[0]) GlobalFree(lpBuf[0]); if (loaded[1]) GlobalFree(lpBuf[1]); if (fTimer) KillTimer(hwnd,1); /* タイマーストップ */ PostQuitMessage(0); break; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } BOOL readBMP(int n) { /* ビットマップ読み込み */ DWORD offset,dummy; HANDLE fh; fh=CreateFile(fn[n],GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); /* ファイルオープン */ if (fh==INVALID_HANDLE_VALUE) return FALSE; lpBuf[n]=(LPBYTE)GlobalAlloc (GPTR,GetFileSize(fh,NULL)); /* バッファ確保 */ ReadFile(fh,lpBuf[n],GetFileSize(fh,NULL),&dummy,NULL); lpInfo[n]=(LPBITMAPINFO)(lpBuf[n]+sizeof(BITMAPFILEHEADER)); offset=*(LPDWORD)(lpBuf[n]+10); lpBMP[n]=lpBuf[n]+offset; /* ビットマップバッファの先頭アドレス */ CloseHandle(fh); /* 24ビットフルカラービットマップでなければ無効 */ if (lpInfo[n]->bmiHeader.biBitCount!=24) { GlobalFree(lpBuf[n]); loaded[n]=FALSE; return FALSE; } if (n==0) { /* ビットマップの大きさ保存 */ dwWidth=lpInfo[0]->bmiHeader.biWidth; dwHeight=lpInfo[0]->bmiHeader.biHeight; } else if (dwWidth!=lpInfo[1]->bmiHeader.biWidth || dwHeight!=lpInfo[1]->bmiHeader.biHeight) { GlobalFree(lpBuf[n]); loaded[n]=FALSE; return FALSE; } if ((dwWidth*3) % 4==0) /* バッファの1ラインの長さを計算 */ dwLength=dwWidth*3; else dwLength=dwWidth*3+(4-(dwWidth*3) % 4); loaded[n]=TRUE; /* 読み込みフラグセット */ InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); /* 再描画 */ return TRUE; } void mixBMP(void) { /* ビットマップを混ぜ合わせる */ DWORD i,j; for (i=0;i20) { /* 最後にビットマップを上書き */ CopyMemory(lpBMP[0],lpBMP[1],dwLength*dwHeight); KillTimer(hwnd,1); /* タイマーストップ */ fTimer=FALSE; } InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); /* 再描画 */ dwCount++; /* 処理回数カウンタ更新 */ }