1 #include <windows.h> 2 #include <string.h> 3 4 BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heightDst, 5 HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, 6 BLENDFUNCTION blendFunction); 7 8 #ifndef AC_SRC_ALPHA 9 #define AC_SRC_ALPHA (0x1) 10 #endif 11 12 HINSTANCE HInst; 13 const char* WndClassName = "GMainWnd"; 14 LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, 15 LPARAM LParam); 16 17 int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, 18 LPTSTR lpCmdLine, int nCmdShow) 19 { 20 WNDCLASS wc; 21 MSG msg; 22 23 HInst = HInstance; 24 25 memset(&wc, 0, sizeof(WNDCLASS)); 26 27 wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; 28 wc.lpfnWndProc = MainWndProc; 29 wc.hInstance = HInstance; 30 wc.hCursor = LoadCursor(NULL, (LPCTSTR)IDC_ARROW); 31 /* wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1); */ 32 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); 33 wc.lpszClassName = WndClassName; 34 35 if (RegisterClass(&wc)) 36 { 37 HWND HWnd = 38 CreateWindow( 39 WndClassName, TEXT("AlphaBlend Rendering Demo"), 40 WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | 41 WS_VISIBLE | WS_CLIPSIBLINGS, 42 0, 0, 320, 430, 43 NULL, NULL, HInst, NULL 44 ); 45 46 if (HWnd) 47 { 48 ShowWindow(HWnd, nCmdShow); 49 UpdateWindow(HWnd); 50 51 while (GetMessage(&msg, NULL, 0, 0)) 52 { 53 TranslateMessage(&msg); 54 DispatchMessage(&msg); 55 } 56 } 57 } 58 return 0; 59 } 60 61 /* image related */ 62 BITMAP bmp; 63 LPCSTR filename = TEXT("lena.bmp"); 64 HDC HMemDC = NULL, HMemDC2 = NULL; 65 HBITMAP HOldBmp = NULL; 66 PVOID pBmpBits = NULL; 67 HBITMAP H32BppBitmap = NULL; 68 BITMAPINFO bmpi; 69 70 BOOL ConvertBitmapTo32Bpp(HDC hDC, BITMAP *bmp) 71 { 72 ZeroMemory(&bmpi, sizeof(BITMAPINFO)); 73 bmpi.bmiHeader.biSize = sizeof(BITMAPINFO); 74 bmpi.bmiHeader.biWidth = bmp->bmWidth; 75 bmpi.bmiHeader.biHeight = bmp->bmHeight; 76 bmpi.bmiHeader.biPlanes = 1; 77 bmpi.bmiHeader.biBitCount = 32; 78 bmpi.bmiHeader.biCompression = BI_RGB; 79 bmpi.bmiHeader.biSizeImage = 4 * bmpi.bmiHeader.biWidth * bmpi.bmiHeader.biHeight; 80 H32BppBitmap = CreateDIBSection(hDC, &bmpi, DIB_RGB_COLORS, &pBmpBits, 0, 0); 81 if(H32BppBitmap) 82 { 83 HBITMAP bmpalpha; 84 SelectObject(hDC, H32BppBitmap); 85 BitBlt(hDC, 0, 0, bmp->bmWidth, bmp->bmHeight, HMemDC, 0, 0, SRCCOPY); 86 87 /* load and apply alpha channel */ 88 bmpalpha = LoadImage(HInst, MAKEINTRESOURCE(2000), IMAGE_BITMAP, 89 0, 0, 0); 90 if(bmpalpha) 91 { 92 COLORREF *col = pBmpBits; 93 int x, y; 94 HDC hdcTemp = CreateCompatibleDC(NULL); 95 if(!hdcTemp) 96 { 97 DeleteObject(bmpalpha); 98 return FALSE; 99 } 100 SelectObject(hdcTemp, bmpalpha); 101 102 for(y = 0; y < bmp->bmHeight; y++) 103 { 104 for(x = 0; x < bmp->bmWidth; x++) 105 { 106 COLORREF Color = (COLORREF)GetRValue(GetPixel(hdcTemp, x, y)) << 24; 107 *col++ |= Color; 108 } 109 } 110 111 DeleteObject(bmpalpha); 112 DeleteDC(hdcTemp); 113 return TRUE; 114 } 115 return FALSE; 116 } 117 return FALSE; 118 } 119 120 LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, 121 LPARAM LParam) 122 { 123 switch (Msg) 124 { 125 case WM_CREATE: 126 { 127 /* create a memory DC */ 128 HMemDC = CreateCompatibleDC(NULL); 129 if (HMemDC) 130 { 131 /* load a bitmap from file */ 132 HBITMAP HBmp = 133 /* static_cast<HBITMAP> */( 134 LoadImage(HInst, MAKEINTRESOURCE(1000), IMAGE_BITMAP, 135 0, 0, 0) 136 ); 137 if (HBmp) 138 { 139 /* extract dimensions of the bitmap */ 140 GetObject(HBmp, sizeof(BITMAP), &bmp); 141 142 /* associate the bitmap with the memory DC */ 143 /* HOldBmp = static_cast<HBITMAP> */ 144 (SelectObject(HMemDC, HBmp) 145 ); 146 HMemDC2 = CreateCompatibleDC(NULL); 147 if(!ConvertBitmapTo32Bpp(HMemDC2, &bmp)) 148 { 149 PostQuitMessage(0); 150 return 0; 151 } 152 } 153 } 154 } 155 case WM_PAINT: 156 { 157 PAINTSTRUCT ps; 158 BLENDFUNCTION BlendFunc; 159 HDC Hdc = BeginPaint(HWnd, &ps); 160 #if 0 161 try 162 #endif 163 { 164 165 BlendFunc.BlendOp = AC_SRC_OVER; 166 BlendFunc.BlendFlags = 0; 167 BlendFunc.SourceConstantAlpha = 128; 168 BlendFunc.AlphaFormat = 0; 169 170 BitBlt(Hdc, 100, 90, 171 bmp.bmWidth, bmp.bmHeight, 172 HMemDC2, 0, 0, 173 SRCCOPY); 174 GdiAlphaBlend(Hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, 175 HMemDC2, 0, 0, bmp.bmWidth, bmp.bmHeight, 176 BlendFunc); 177 GdiAlphaBlend(Hdc, bmp.bmWidth - 15, 10, bmp.bmWidth / 2, bmp.bmHeight / 2, 178 HMemDC2, 0, 0, bmp.bmWidth, bmp.bmHeight, 179 BlendFunc); 180 181 BlendFunc.SourceConstantAlpha = 255; 182 BlendFunc.AlphaFormat = AC_SRC_ALPHA; 183 184 GdiAlphaBlend(Hdc, 140, 200, bmp.bmWidth, bmp.bmHeight, 185 HMemDC2, 0, 0, bmp.bmWidth, bmp.bmHeight, 186 BlendFunc); 187 GdiAlphaBlend(Hdc, 20, 210, (bmp.bmWidth / 3) * 2, (bmp.bmHeight / 3) * 2, 188 HMemDC2, 0, 0, bmp.bmWidth, bmp.bmHeight, 189 BlendFunc); 190 } 191 #if 0 192 catch (...) 193 { 194 EndPaint(HWnd, &ps); 195 } 196 #endif 197 EndPaint(HWnd, &ps); 198 break; 199 } 200 case WM_DESTROY: 201 { 202 /* clean up */ 203 DeleteObject(SelectObject(HMemDC, HOldBmp)); 204 DeleteDC(HMemDC); 205 DeleteDC(HMemDC2); 206 207 PostQuitMessage(0); 208 return 0; 209 } 210 } 211 return DefWindowProc(HWnd, Msg, WParam, LParam); 212 } 213