// // グラフィックで遊ぶ>単色化 // // 1998/ 6/27 宍戸 輝光 // #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); BOOL readBMP(char fn[]); void grayScale(int); HINSTANCE hInst; HWND hwnd; int xSize,ySize; BOOL loaded; LPBITMAPINFO lpInfo; LPBYTE lpBMP,lpBuf; 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 = "Test Window"; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); RegisterClassEx (&wndclass); hwnd = CreateWindow ("Test Window", "グラフィックの単色化", WS_OVERLAPPEDWINDOW, 64,64, 480,400, NULL, NULL, hInstance, NULL); DragAcceptFiles(hwnd,TRUE); // ドラッグ&ドロップ受入 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) { static OPENFILENAME ofn; static char szFn[256],szFt[256]; HDROP hDrop; static HWND hwOpenB,hwGrayB,hwBlueB; HDC hdc; PAINTSTRUCT ps; ofn.lStructSize=sizeof(OPENFILENAME); // ファイルを開くダイアログ設定 ofn.hwndOwner=hwnd; ofn.hInstance=NULL; ofn.lpstrFilter= // フィルター "ビットマップ(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0"; ofn.lpstrCustomFilter=NULL; ofn.nMaxCustFilter=0; ofn.nFilterIndex=1; // フィルターの初期位置 ofn.lpstrFile=szFn; // ファイル名用文字列バッファ ofn.nMaxFile=255; // 文字列バッファのサイズ ofn.lpstrFileTitle=szFt; // タイトル用文字列バッファ ofn.nMaxFileTitle=255; // 文字列バッファのサイズ ofn.lpstrInitialDir=NULL; ofn.lpstrTitle="読み込むファイルを選んでください"; // タイトル ofn.Flags=OFN_FILEMUSTEXIST;// | OFN_HIDEREADONLY; ofn.nFileOffset=0; ofn.nFileExtension=0; ofn.lpstrDefExt=NULL; ofn.lCustData=0; ofn.lpfnHook=NULL; ofn.lpTemplateName=NULL; switch (iMsg) { case WM_CREATE: hwOpenB=CreateWindow("Button","読み込み", // ボタン作成 WS_CHILD | WS_VISIBLE,16,8,96,32,hwnd, (HMENU)0,hInst,NULL); hwGrayB=CreateWindow("Button","白黒", WS_CHILD | WS_VISIBLE,128,8,64,32,hwnd, (HMENU)1,hInst,NULL); hwBlueB=CreateWindow("Button","青白", WS_CHILD | WS_VISIBLE,208,8,64,32,hwnd, (HMENU)2,hInst,NULL); loaded=FALSE; // 読み込みフラグリセット EnableWindow(hwGrayB,FALSE); // 単色化ボタン無効 EnableWindow(hwBlueB,FALSE); return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case 0: // 読み込みボタン if (!GetOpenFileName(&ofn)) // ファイルを選択 return 0; if (readBMP(szFn)) { // BMPファイル読み込み EnableWindow(hwGrayB,TRUE); // 24ビットならボタン有効 EnableWindow(hwBlueB,TRUE); } else { // 24ビットDIBでなければボタン無効 EnableWindow(hwGrayB,FALSE); EnableWindow(hwBlueB,FALSE); } return 0; case 1: // 白黒ボタン grayScale(1); return 0; case 2: // 青白ボタン grayScale(2); return 0; } break; case WM_DROPFILES: // ファイルがドロップされた時の処理 hDrop=(HDROP)wParam; // HDROPを取得 DragQueryFile(hDrop,0,szFn,256); // ファイル名を取得 if (readBMP(szFn)) { // BMPファイル読み込み EnableWindow(hwGrayB,TRUE); // 24ビットならボタン有効 EnableWindow(hwBlueB,TRUE); } else { // 24ビットDIBでなければボタン無効 EnableWindow(hwGrayB,FALSE); EnableWindow(hwBlueB,FALSE); } DragFinish(hDrop); // 終了処理 return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); if (loaded) StretchDIBits(hdc,4,48,xSize,ySize,0,0,xSize,ySize,lpBMP, lpInfo,DIB_RGB_COLORS,SRCCOPY); // DIBを画面に描画 EndPaint(hwnd,&ps); return 0; case WM_DESTROY : if (loaded) GlobalFree(lpBuf); PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } BOOL readBMP(char fn[]) { // ビットマップ読み込み char str[280]; DWORD offset,dummy; HANDLE fh; if (loaded) // 以前確保したバッファを解放 GlobalFree(lpBuf); fh=CreateFile(fn,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); // ファイルオープン lpBuf=GlobalAlloc(GPTR,GetFileSize(fh,NULL)); // バッファ確保 ReadFile(fh,lpBuf,GetFileSize(fh,NULL),&dummy,NULL); lpInfo=(LPBITMAPINFO)(lpBuf+sizeof(BITMAPFILEHEADER)); offset=*(LPDWORD)(lpBuf+10); lpBMP=lpBuf+offset; // ビットマップバッファの先頭アドレス CloseHandle(fh); if (lpBuf[0]!='B' || lpInfo->bmiHeader.biBitCount<16) { // BMPでない GlobalFree(lpBuf); loaded=FALSE; SetWindowText(hwnd,"Error!!"); return FALSE; } xSize=lpInfo->bmiHeader.biWidth; ySize=lpInfo->bmiHeader.biHeight; wsprintf(str,"%s %d*%dPixel %dBit",fn,xSize,ySize, lpInfo->bmiHeader.biBitCount); SetWindowText(hwnd,str); // ビットマップの情報表示 loaded=TRUE; // 読み込みフラグセット InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); // 再描画 // 読み込んだDIBがフルカラーかつ横方向4ピクセル単位ならTRUE return (lpInfo->bmiHeader.biBitCount==24 && (xSize % 4)==0); } void grayScale(int mode) { // 単色スケールに変換 int i; BYTE r,g,b,c; for (i=0;i