#include #define SOURCE_FILENAME "C:\\LABO\\TESTBMP\\TEST.BMP" HINSTANCE hInst ; HPALETTE hPal ; HBITMAP hBitmap ; short width ; short height ; class exceptBasic {} ; LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ; int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE previnst, LPSTR lpstrCmdline, int nCmdshow) { hInst = hInstance ; WNDCLASS wc; wc.style = 0 ; wc.lpfnWndProc = WindowProc ; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst ; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL ; wc.lpszClassName = "TESTWINDOW" ; RegisterClass(&wc); HWND hwndMain = CreateWindow("TESTWINDOW", "BMP Test", WS_OVERLAPPEDWINDOW, /* style */ CW_USEDEFAULT, /* init. x pos */ CW_USEDEFAULT, /* init. y pos */ 640, /* init. x size */ 480, /* init. y size */ NULL, /* parent window */ NULL, /* menu handle */ hInst, /* program handle */ NULL /* create parms */ ); if(hwndMain == NULL) { MessageBox(NULL, "Error:Windowの作成に失敗しました", "Test BMP", MB_OK|MB_ICONSTOP) ; return -1 ; } // イメージの読み込み&各種ハンドルの作成 HANDLE hFile = INVALID_HANDLE_VALUE ; LPVOID imageBuf = NULL ; hPal = NULL ; hBitmap = NULL ; try{ hFile = CreateFile(SOURCE_FILENAME, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ; if(hFile == INVALID_HANDLE_VALUE) { char text[500] ; wsprintf(text, "Error:%sのオープンに失敗しました", SOURCE_FILENAME) ; MessageBox(NULL, text, "Test BMP", MB_OK|MB_ICONSTOP) ; throw exceptBasic() ; } long filesize ; filesize = GetFileSize(hFile, NULL) ; /* この部分をHeapAllocに直で入れないのは、 その方がデバッグが楽になるからである */ imageBuf = HeapAlloc(GetProcessHeap(), 0, filesize) ; if(imageBuf == NULL) { MessageBox(NULL, "メモリの確保に失敗しました", "Test BMP", MB_OK|MB_ICONSTOP) ; throw exceptBasic() ; } DWORD readedBytes ; if(ReadFile(hFile, imageBuf, filesize, &readedBytes, NULL) == FALSE) { char text[500] ; wsprintf(text, "Error:%sの読み込みに失敗しました", SOURCE_FILENAME) ; MessageBox(NULL, text, "Test BMP", MB_OK|MB_ICONSTOP) ; throw exceptBasic() ; } CloseHandle(hFile) ; hFile = INVALID_HANDLE_VALUE ; BITMAPINFO *bmInfo ; bmInfo = (BITMAPINFO *)((unsigned long)imageBuf + sizeof(BITMAPFILEHEADER)) ; // Bitmapのサイズを得る width = (short)bmInfo->bmiHeader.biWidth ; height = (short)bmInfo->bmiHeader.biHeight ; // 色数を判断する short colors ; colors = 1 << bmInfo->bmiHeader.biBitCount ; // パレットの作成 LOGPALETTE *lpal ; lpal = (LOGPALETTE *)new char[sizeof(WORD) * 2 + sizeof(PALETTEENTRY) * colors] ; if(lpal == NULL) { MessageBox(NULL, "メモリの確保に失敗しました", "Test BMP", MB_OK|MB_ICONSTOP) ; throw exceptBasic() ; } PALETTEENTRY *pal = lpal->palPalEntry ; RGBQUAD *rgb = bmInfo->bmiColors ; for(short i = 0 ; i < colors ; i ++) { pal->peRed = rgb->rgbRed ; pal->peGreen = rgb->rgbGreen ; pal->peBlue = rgb->rgbBlue ; pal->peFlags = 0 ; } lpal->palVersion = 0x300 ; lpal->palNumEntries = colors ; hPal = CreatePalette(lpal) ; if(hPal == NULL) { delete [] (char *)lpal ; MessageBox(NULL, "パレットの作成に失敗しました", "Test BMP", MB_OK|MB_ICONSTOP) ; throw exceptBasic() ; } delete [] (char *)lpal ; // ビットマップハンドルの作成 HDC hdc ; hdc = GetDC(hwndMain) ; if(hdc == NULL) { MessageBox(NULL, "DCの取得に失敗しました", "Test BMP", MB_OK|MB_ICONSTOP) ; throw exceptBasic() ; } LPVOID imagePtr = (LPVOID)((unsigned long)bmInfo + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * colors) ; hBitmap = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)bmInfo, CBM_INIT, imagePtr, bmInfo, DIB_RGB_COLORS) ; ReleaseDC(hwndMain, hdc) ; if(hBitmap == NULL) { MessageBox(NULL, "ビットマップハンドルの作成に失敗しました", "Test BMP", MB_OK|MB_ICONSTOP) ; throw exceptBasic() ; } // 後始末 HeapFree(GetProcessHeap(), 0, imageBuf) ; } catch(exceptBasic &) { if(hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile) ; } if(imageBuf != NULL) { HeapFree(GetProcessHeap(), 0, imageBuf) ; } if(hPal != NULL) { DeleteObject(hPal) ; } if(hBitmap != NULL) { DeleteObject(hBitmap) ; } DestroyWindow(hwndMain) ; return -1 ; } ShowWindow(hwndMain, nCmdshow); UpdateWindow(hwndMain); MSG msg ; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } DeleteObject(hPal) ; DeleteObject(hBitmap) ; return msg.wParam; } /******************************************** Window procedure *********************************************/ LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_PAINT: { PAINTSTRUCT ps ; HDC hdc ; hdc = BeginPaint(hwnd, &ps) ; HDC hMemDC ; hMemDC = CreateCompatibleDC(hdc) ; SelectObject(hMemDC, hBitmap) ; HPALETTE hOldPal = SelectPalette(hdc, hPal, FALSE) ; RealizePalette(hdc) ; BitBlt(hdc, 0, 0, width, height, hMemDC, 0, 0, SRCCOPY) ; SelectPalette(hdc, hOldPal, TRUE) ; DeleteDC(hMemDC) ; EndPaint(hwnd, &ps) ; } return 0 ; case WM_DESTROY: PostQuitMessage(0) ; return 0 ; } return DefWindowProc(hwnd, msg, wParam, lParam) ; }