// // パレットによる半透明処理 // // 1998/ 8/22 宍戸 輝光 // #include #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); LPBYTE lpBuf,lpBMP,bgBMP,bufBMP,partBMP; LPBITMAPINFO bufDIB; LPRGBQUAD lpRGB; int x,y,p; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ HWND hwnd; MSG msg; WNDCLASSEX wndclass ; int i,j,k; 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, 32,32, 288,288, NULL, NULL, hInstance, NULL); lpBMP=GlobalAlloc(GPTR,256*256+32*32); // 背景・キャラクタ用メモリ bgBMP=lpBMP; // 背景とキャラクタにビットマップメモリを分配 partBMP=lpBMP+256*256; lpBuf=GlobalAlloc // 表示用バッファに必要なメモリをまとめて確保 (GPTR,sizeof(BITMAPINFO)+255*sizeof(RGBQUAD)+256*256); bufDIB=(LPBITMAPINFO)lpBuf; // メモリを分配 lpRGB=(RGBQUAD*)(lpBuf+sizeof(BITMAPINFOHEADER)); bufBMP=(BYTE*)(lpBuf+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)); bufDIB->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); // BITMAPINFO構造体 bufDIB->bmiHeader.biWidth=256; bufDIB->bmiHeader.biHeight=256; bufDIB->bmiHeader.biPlanes=1; bufDIB->bmiHeader.biBitCount=8; bufDIB->bmiHeader.biCompression=BI_RGB; bufDIB->bmiHeader.biSizeImage=0; bufDIB->bmiHeader.biXPelsPerMeter=0; bufDIB->bmiHeader.biYPelsPerMeter=0; bufDIB->bmiHeader.biClrUsed=0; bufDIB->bmiHeader.biClrImportant=0; bufDIB->bmiColors[0]=lpRGB[0]; // カラーテーブルの先頭 lpRGB[0].rgbRed=0; // 背景の色設定 lpRGB[0].rgbGreen=0; lpRGB[0].rgbBlue=0; lpRGB[1].rgbRed=255; lpRGB[1].rgbGreen=0; lpRGB[1].rgbBlue=0; lpRGB[2].rgbRed=0; lpRGB[2].rgbGreen=255; lpRGB[2].rgbBlue=0; lpRGB[3].rgbRed=0; lpRGB[3].rgbGreen=0; lpRGB[3].rgbBlue=255; lpRGB[4].rgbRed=255; lpRGB[4].rgbGreen=255; lpRGB[4].rgbBlue=0; lpRGB[5].rgbRed=255; lpRGB[5].rgbGreen=0; lpRGB[5].rgbBlue=255; lpRGB[6].rgbRed=0; lpRGB[6].rgbGreen=255; lpRGB[6].rgbBlue=255; lpRGB[7].rgbRed=255; lpRGB[7].rgbGreen=255; lpRGB[7].rgbBlue=255; lpRGB[8].rgbRed=64; // キャラクタ本来の色を設定 lpRGB[8].rgbGreen=128; lpRGB[8].rgbBlue=255; lpRGB[16].rgbRed=255; lpRGB[16].rgbGreen=128; lpRGB[16].rgbBlue=64; lpRGB[24].rgbRed=255; lpRGB[24].rgbGreen=255; lpRGB[24].rgbBlue=255; for (i=1;i<8;i++) { // 半透明の色を設定 lpRGB[8+i].rgbRed=(lpRGB[8].rgbRed*2+lpRGB[i].rgbRed)/3; lpRGB[8+i].rgbGreen=(lpRGB[8].rgbGreen*2+lpRGB[i].rgbGreen)/3; lpRGB[8+i].rgbBlue=(lpRGB[8].rgbBlue*2+lpRGB[i].rgbBlue)/3; lpRGB[16+i].rgbRed=(lpRGB[16].rgbRed*2+lpRGB[i].rgbRed)/3; lpRGB[16+i].rgbGreen=(lpRGB[16].rgbGreen*2+lpRGB[i].rgbGreen)/3; lpRGB[16+i].rgbBlue=(lpRGB[16].rgbBlue*2+lpRGB[i].rgbBlue)/3; lpRGB[24+i].rgbRed=(lpRGB[24].rgbRed*2+lpRGB[i].rgbRed)/3; lpRGB[24+i].rgbGreen=(lpRGB[24].rgbGreen*2+lpRGB[i].rgbGreen)/3; lpRGB[24+i].rgbBlue=(lpRGB[24].rgbBlue*2+lpRGB[i].rgbBlue)/3; } for (i=0;i<8;i++) // 背景ビットマップを作成 for (j=0;j<8;j++) { p=rand() % 8; for (k=0;k<32;k++) FillMemory(bgBMP+(i*32+k)*256+j*32,32,p); } for (i=0;i<32;i++) // キャラクタを抜き色でクリア for (j=0;j<32;j++) partBMP[j+i*32]=255; for (i=0;i<16;i++) { // キャラクタ作成 FillMemory(partBMP+i*32,32,8); } for (i=0;i<12;i++) FillMemory(partBMP+(32-i)*32+(16-i),i*2,16); for (i=16;i<21;i++) FillMemory(partBMP+i*32+15,2,24); x=112; y=112; 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; int i,j; switch (iMsg) { case WM_DESTROY : GlobalFree(lpBuf); // バッファを解放 GlobalFree(lpBMP); // バッファを解放 PostQuitMessage(0); return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); CopyMemory(bufBMP,bgBMP,256*256); for (i=0;i<32;i++) // キャラクタを半透明で描画 for (j=0;j<32;j++) if (partBMP[j+i*32]!=255) bufBMP[x+j+(y+i)*256]+=partBMP[j+i*32]; StretchDIBits(hdc,0,0,256,256,0,0,256,256,bufBMP,bufDIB, DIB_RGB_COLORS,SRCCOPY); EndPaint(hwnd,&ps); return 0; case WM_KEYDOWN: // カーソルキーでキャラクタ移動 if (wParam==VK_UP && y<224) y=y+2; if (wParam==VK_RIGHT && x<224) x=x+2; if (wParam==VK_DOWN && y>0) y=y-2; if (wParam==VK_LEFT && x>0) x=x-2; InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); // 再描画 return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }