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 
WinMain(HINSTANCE HInstance,HINSTANCE HPrevInstance,LPTSTR lpCmdLine,int nCmdShow)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 
ConvertBitmapTo32Bpp(HDC hDC,BITMAP * bmp)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 
MainWndProc(HWND HWnd,UINT Msg,WPARAM WParam,LPARAM LParam)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