1 /*
2  * Tests various blit and blend operations with different src
3  * bit depths and scaling where possbile.
4  *
5  * Created by Gregor Schneider <grschneider AT gmail DOT com>, November 2008
6 */
7 
8 #include <windows.h>
9 #include <tchar.h>
10 
11 BOOL WINAPI GdiAlphaBlend(
12                 HDC hdcDst, int xDst, int yDst, int wDst, int hDst,
13                 HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc,
14                 BLENDFUNCTION blendFunction);
15 
16 BOOL WINAPI GdiTransparentBlt(
17                 HDC hdcDst, int xDst, int yDst, int wDst, int hDst,
18                 HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc,
19                 UINT crTransparent);
20 
21 #define CURRENT_BMPS 4
22 #define CURRENT_ICONS 1
23 #define SCALE 1.5
24 #define OFFSET 5
25 
26 HINSTANCE hInst;
27 TCHAR szWindowClass[] = _T("testclass");
28 
29 static LRESULT CALLBACK
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)30 WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
31 {
32     static HBITMAP hbmList[CURRENT_BMPS];
33     static HICON hicList[CURRENT_ICONS];
34 
35     switch (message)
36     {
37         case WM_CREATE:
38         {
39             hbmList[0] = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(100), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
40             hbmList[1] = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(400), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
41             hbmList[2] = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(800), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
42             hbmList[3] = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(2400), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
43             hicList[0] = (HICON)LoadIcon(hInst, MAKEINTRESOURCE(3200));
44             break;
45         }
46 
47         case WM_PAINT:
48         {
49             PAINTSTRUCT ps;
50             HDC hdc, hdcMem;
51             BITMAP bitmap;
52             BLENDFUNCTION bfunc;
53             int x = 0, y = 0, i;
54             hdc = BeginPaint(hWnd, &ps);
55             hdcMem = CreateCompatibleDC(hdc);
56 
57             bfunc.AlphaFormat = AC_SRC_ALPHA;
58             bfunc.BlendFlags = 0;
59             bfunc.BlendOp = AC_SRC_OVER;
60             bfunc.SourceConstantAlpha = 128;
61 
62             /* bitmaps */
63             for(i = 0; i < CURRENT_BMPS; i++)
64             {
65                 y = 0;
66                 SelectObject(hdcMem, hbmList[i]);
67                 GetObject(hbmList[i], sizeof(BITMAP), &bitmap);
68 
69                 /* bit blt */
70                 BitBlt(hdc, x, y, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
71                 y += bitmap.bmHeight + OFFSET;
72 
73                 /* stretch blt, org size */
74                 StretchBlt(hdc, x, y, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
75                 y += bitmap.bmHeight + OFFSET;
76 
77                 /* stretch blt, scaled */
78                 StretchBlt(hdc, x, y, bitmap.bmWidth*SCALE, bitmap.bmHeight*SCALE, hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
79                 y += bitmap.bmHeight*SCALE + OFFSET;
80 
81                 /* transparent blt, transparency: grey */
82                 GdiTransparentBlt(hdc, x, y, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, 128*256*256+128*256+128);
83                 y += bitmap.bmHeight + OFFSET;
84 
85                 /* transparent blt, transparency: grey, scaled */
86                 GdiTransparentBlt(hdc, x, y, bitmap.bmWidth*SCALE, bitmap.bmHeight*SCALE, hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, 128*256*256+128*256+128);
87                 y += bitmap.bmHeight*SCALE + OFFSET;
88 
89                 /* alpha blend, org size */
90                 GdiAlphaBlend(hdc, x, y, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, bfunc);
91                 y += bitmap.bmHeight + OFFSET;
92 
93                 /* alpha blend, scaled */
94                 GdiAlphaBlend(hdc, x, y, bitmap.bmWidth*SCALE, bitmap.bmHeight*SCALE, hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, bfunc);
95                 y += bitmap.bmHeight*SCALE + OFFSET;
96 
97                 x += bitmap.bmWidth*SCALE + OFFSET;
98             }
99 
100             /* icons */
101             for(i = 0; i < CURRENT_ICONS; i++)
102             {
103                 y = 0;
104                 /* pure icon */
105                 DrawIcon(hdc, x, y, hicList[i]);
106                 y += bitmap.bmHeight + OFFSET;
107 
108                 /* normal icon using Ex */
109                 DrawIconEx(hdc, x, y, hicList[i], 0, 0, 0, NULL, DI_NORMAL);
110                 y += bitmap.bmHeight + OFFSET;
111 
112                 /* normal icon using Ex with bigger size */
113                 DrawIconEx(hdc, x, y, hicList[i], bitmap.bmWidth, bitmap.bmHeight, 0, NULL, DI_NORMAL);
114                 y += bitmap.bmHeight + OFFSET;
115 
116                 /* only icon using Ex */
117                 DrawIconEx(hdc, x, y, hicList[i], 0, 0, 0, NULL, DI_IMAGE);
118                 y += bitmap.bmHeight + OFFSET;
119 
120                 /* mask using Ex */
121                 DrawIconEx(hdc, x, y, hicList[i], 0, 0, 0, NULL, DI_MASK);
122                 y += bitmap.bmHeight + OFFSET;
123 
124                 x += bitmap.bmWidth*SCALE + OFFSET;
125             }
126 
127             DeleteDC(hdcMem);
128             EndPaint(hWnd, &ps);
129             break;
130         }
131 
132         case WM_DESTROY:
133             PostQuitMessage(0);
134             break;
135         default:
136             return DefWindowProc(hWnd, message, wParam, lParam);
137     }
138     return 0;
139 }
140 
141 
142 static ATOM
MyRegisterClass(HINSTANCE hInstance)143 MyRegisterClass(HINSTANCE hInstance)
144 {
145     WNDCLASSEX wcex;
146 
147     wcex.cbSize = sizeof(WNDCLASSEX);
148 
149     wcex.style         = CS_HREDRAW | CS_VREDRAW;
150     wcex.lpfnWndProc   = WndProc;
151     wcex.cbClsExtra    = 0;
152     wcex.cbWndExtra    = 0;
153     wcex.hInstance     = hInstance;
154     wcex.hIcon         = NULL;
155     wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
156     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
157     wcex.lpszMenuName  = NULL;
158     wcex.lpszClassName = szWindowClass;
159     wcex.hIconSm       = NULL;
160 
161     return RegisterClassEx(&wcex);
162 }
163 
164 
165 static BOOL
InitInstance(HINSTANCE hInstance,int nCmdShow)166 InitInstance(HINSTANCE hInstance, int nCmdShow)
167 {
168    HWND hWnd;
169 
170    hInst = hInstance;
171 
172    hWnd = CreateWindowEx(0,
173                          szWindowClass,
174                          _T("Various blit and blend operations"),
175                          WS_OVERLAPPEDWINDOW,
176                          CW_USEDEFAULT,
177                          CW_USEDEFAULT,
178                          640,
179                          640,
180                          NULL,
181                          NULL,
182                          hInstance,
183                          NULL);
184 
185    if (!hWnd)
186    {
187       return FALSE;
188    }
189 
190    ShowWindow(hWnd, nCmdShow);
191    UpdateWindow(hWnd);
192 
193    return TRUE;
194 }
195 
196 
197 int WINAPI
_tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)198 _tWinMain(HINSTANCE hInstance,
199                      HINSTANCE hPrevInstance,
200                      LPTSTR    lpCmdLine,
201                      int       nCmdShow)
202 {
203     MSG msg;
204 
205     MyRegisterClass(hInstance);
206 
207     if (!InitInstance(hInstance, nCmdShow))
208     {
209         return FALSE;
210     }
211 
212     while (GetMessage(&msg, NULL, 0, 0))
213     {
214         TranslateMessage(&msg);
215         DispatchMessage(&msg);
216     }
217 
218     return (int)msg.wParam;
219 }
220