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