/* 256色パレットの減色 1999/11/ 4 宍戸 輝光 */ #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); BOOL readBMP(LPCTSTR); void to256(); HINSTANCE hInst; HWND hwnd; DWORD dwWidth,dwHeight,dwLength; BOOL loaded=FALSE; LPVOID lpDIB,lpPDIB; LPBYTE lpPixel,lpPPixel; LPBITMAPINFO lpInfo,lpPInfo; RGBQUAD rgbPal[256]; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASSEX wndclass ; int i,j,k; hInst=hInstance; /* プロセスのハンドルを保存 */ for (i=0;i<6;i++) /* カラーテーブル作成 */ for (j=0;j<6;j++) for (k=0;k<6;k++) { rgbPal[i*36+j*6+k].rgbRed=k*51; rgbPal[i*36+j*6+k].rgbGreen=j*51; rgbPal[i*36+j*6+k].rgbBlue=i*51; } for (i=1;i<32;i++) { rgbPal[i+223].rgbRed=i*8; rgbPal[i+223].rgbGreen=i*8; rgbPal[i+223].rgbBlue=i*8; } rgbPal[255].rgbRed=255; rgbPal[255].rgbGreen=255; rgbPal[255].rgbBlue=255; /* 色見本用のメモリ確保・ポインタ設定 */ lpPDIB=GlobalAlloc(GPTR,sizeof(BITMAPINFO)+255*sizeof(RGBQUAD)+512*32); lpPInfo=(LPBITMAPINFO)lpPDIB; lpPPixel=(LPBYTE)lpPDIB+sizeof(BITMAPINFO)+255*sizeof(RGBQUAD); /* BITMAPINFO設定 */ lpPInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); lpPInfo->bmiHeader.biWidth=512; lpPInfo->bmiHeader.biHeight=32; lpPInfo->bmiHeader.biPlanes=1; lpPInfo->bmiHeader.biBitCount=8; lpPInfo->bmiHeader.biCompression=BI_RGB; /* カラーテーブルをDIBのカラーテーブルにコピー */ CopyMemory((LPBYTE)lpPInfo+sizeof(BITMAPINFOHEADER),rgbPal,256*4); for (i=0;i<32;i++) /* 色を描く */ for (j=0;j<256;j++) FillMemory(lpPPixel+j*2+i*512,2,j); /* 左右の縦線 */ for (i=0;i<32;i++) { lpPPixel[i*512]=0; lpPPixel[i*512+511]=0; } /* 上下の横線 */ FillMemory(lpPPixel,512,0); FillMemory(lpPPixel+31*512,512,0); 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","256色パレットの減色", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,600,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; HDROP hDrop; PAINTSTRUCT ps; RECT rec; static HWND hwDoB; static char lpszFn[256]; switch (iMsg) { case WM_CREATE: hwDoB=CreateWindow("Button","減色", /* ボタン作成 */ WS_CHILD |WS_VISIBLE,8,8,48,32,hwnd, (HMENU)0,hInst,NULL); EnableWindow(hwDoB,FALSE); DragAcceptFiles(hwnd,TRUE); /* ドラッグ&ドロップ受入 */ break; case WM_COMMAND: switch (LOWORD(wParam)) { case 0: /* 処理開始ボタン */ EnableWindow(hwDoB,FALSE); to256(&lpInfo,&lpPixel); InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); /* 再描画 */ break; } break; case WM_DROPFILES: /* ファイルがドロップされた時の処理 */ hDrop=(HDROP)wParam; /* HDROPを取得 */ DragQueryFile(hDrop,0,lpszFn,256); /* ファイル名を取得 */ if(readBMP(lpszFn)) EnableWindow(hwDoB,TRUE); DragFinish(hDrop); /* 終了処理 */ break; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); GetClientRect(hwnd,&rec); FillRect(hdc,&rec,GetStockObject(WHITE_BRUSH)); StretchDIBits(hdc,64,8,512,32,0,0,512,32,lpPPixel,lpPInfo, DIB_RGB_COLORS,SRCCOPY); /* DIBを画面に描画 */ if (loaded) /* ビットマップが読み込まれていれば */ StretchDIBits(hdc,4,48,dwWidth,dwHeight, 0,0,dwWidth,dwHeight,lpPixel,lpInfo, DIB_RGB_COLORS,SRCCOPY); /* DIBを画面に描画 */ EndPaint(hwnd,&ps); break; case WM_DESTROY : if (loaded) GlobalFree(lpDIB); PostQuitMessage(0); break; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } BOOL readBMP(LPCTSTR fn) { /* ビットマップ読み込み */ DWORD offset,dummy; HANDLE fh; fh=CreateFile(fn,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); /* ファイルオープン */ if (fh==INVALID_HANDLE_VALUE) return FALSE; if (loaded) { GlobalFree(lpDIB); GlobalFree(lpInfo); GlobalFree(lpPixel); } lpDIB=GlobalAlloc(GPTR,GetFileSize(fh,NULL)); /* バッファ確保 */ ReadFile(fh,lpDIB,GetFileSize(fh,NULL),&dummy,NULL); lpInfo=(LPBITMAPINFO)((LPBYTE)lpDIB+sizeof(BITMAPFILEHEADER)); offset=*(LPDWORD)((LPBYTE)lpDIB+10); lpPixel=(LPBYTE)lpDIB+offset; /* ビットマップバッファの先頭アドレス */ CloseHandle(fh); /* 24ビットフルカラービットマップでなければ無効 */ if (lpInfo->bmiHeader.biBitCount!=24) { GlobalFree(lpDIB); loaded=FALSE; return FALSE; } /* ビットマップの大きさ保存 */ dwWidth=lpInfo->bmiHeader.biWidth; dwHeight=lpInfo->bmiHeader.biHeight; if (dwWidth*3 % 4==0) /* バッファの1ラインの長さを計算 */ dwLength=dwWidth*3; else dwLength=dwWidth*3+(4-(dwWidth*3) % 4); loaded=TRUE; /* 読み込みフラグセット */ InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); /* 再描画 */ return TRUE; } void to256() { DWORD dwWLength,dwDis,dwMin; DWORD r,g,b,pr,pg,pb; DWORD i,j,k,no; LPBITMAPINFO lpWInfo; LPBYTE lpWPixels; LPVOID lpWDIB; if (dwWidth % 4==0) /* バッファの1ラインの長さを計算 */ dwWLength=dwWidth; else dwWLength=dwWidth+(4-(dwWidth) % 4); /* DIB用メモリ確保・ポインタ設定 */ lpWDIB=GlobalAlloc(GPTR,sizeof(BITMAPINFO)+255*sizeof(RGBQUAD)+dwHeight*dwWLength); lpWInfo=(LPBITMAPINFO)lpWDIB; lpWPixels=(LPBYTE)lpWDIB+sizeof(BITMAPINFO)+255*sizeof(RGBQUAD); lpWInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); lpWInfo->bmiHeader.biWidth=dwWidth; lpWInfo->bmiHeader.biHeight=dwHeight; lpWInfo->bmiHeader.biPlanes=1; lpWInfo->bmiHeader.biBitCount=8; lpWInfo->bmiHeader.biCompression=BI_RGB; CopyMemory((LPBYTE)lpWInfo+sizeof(BITMAPINFOHEADER),rgbPal,256*4); for (i=0;idwDis) { dwMin=dwDis; no=k; } } lpWPixels[j+i*dwWLength]=no; /* ピクセルの色決定 */ } GlobalFree(lpDIB); /* 表示用DIBを置きかえる */ lpDIB=lpWDIB; lpInfo=lpWInfo; lpPixel=lpWPixels; }