ReactOS  0.4.14-dev-57-g333b8f1
stretchblt.cpp
Go to the documentation of this file.
1 
2 // ------------------------------------------------------------------
3 // Windows 2000 Graphics API Black Book
4 // Chapter 1 - Listing 1.5 (StretchBlt Zooming Demo)
5 //
6 // Created by Damon Chandler <dmc27@ee.cornell.edu>
7 // Updates can be downloaded at: <www.coriolis.com>
8 //
9 // Please do not hesistate to e-mail me at dmc27@ee.cornell.edu
10 // if you have any questions about this code.
11 // ------------------------------------------------------------------
12 
13 // Modified by Aleksey Bragin (aleksey at studiocerebral.com)
14 // to support non-uniform scaling, and output via sretchdibits
15 // (type something in the command line to invoke this mode,
16 // in future it will be source BPP)
17 
18 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
19 #include <windows.h>
20 #include <stdio.h>
21 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
22 
23 
26 const int ID_LISTBOX = 101;
27 const int ID_LISTBOX2 = 102;
28 BOOL useDIBits=FALSE; // How to display the image - via StretchDIBits
29 
33 const char* WndClassName = "GMainWnd";
35  LPARAM LParam);
36 
37 
38 int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance,
39  LPTSTR lpCmdLine, int nCmdShow)
40 {
41  HInst = HInstance;
42  HPrevInst = HPrevInstance;
43  cmdline = lpCmdLine;
44 
45  WNDCLASS wc;
46  memset(&wc, 0, sizeof(WNDCLASS));
47 
50  wc.hInstance = HInstance;
52  wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1);
54 
55  if (RegisterClass(&wc))
56  {
57  HWND HWnd =
58  CreateWindow(WndClassName, TEXT("StretchBlt NonUniform Zooming Demo"),
61  0, 0, 675, 560,
62  NULL, NULL, HInst, NULL);
63 
64  if (HWnd)
65  {
66  HListBox =
67  CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "",
69  530, 5, 130, 150, HWnd,
70  reinterpret_cast<HMENU>(ID_LISTBOX),
71  HInst, NULL);
72  VListBox =
73  CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "",
75  530, 5+170, 130, 150, HWnd,
76  reinterpret_cast<HMENU>(ID_LISTBOX2),
77  HInst, NULL);
78 
79  if (HListBox && VListBox)
80  {
81 // horizontal zoom
83  reinterpret_cast<LPARAM>("Zoom 25%"));
85  reinterpret_cast<LPARAM>("Zoom 50%"));
87  reinterpret_cast<LPARAM>("Zoom 75%"));
89  reinterpret_cast<LPARAM>("Zoom 100%"));
91  reinterpret_cast<LPARAM>("Zoom 125%"));
93  reinterpret_cast<LPARAM>("Zoom 150%"));
95  reinterpret_cast<LPARAM>("Zoom 200%"));
97  reinterpret_cast<LPARAM>("Zoom 300%"));
98 // vertical zoom
100  reinterpret_cast<LPARAM>("Zoom 25%"));
102  reinterpret_cast<LPARAM>("Zoom 50%"));
104  reinterpret_cast<LPARAM>("Zoom 75%"));
106  reinterpret_cast<LPARAM>("Zoom 100%"));
108  reinterpret_cast<LPARAM>("Zoom 125%"));
110  reinterpret_cast<LPARAM>("Zoom 150%"));
112  reinterpret_cast<LPARAM>("Zoom 200%"));
114  reinterpret_cast<LPARAM>("Zoom 300%"));
115 
116  }
117 
118  ShowWindow(HWnd, nCmdShow);
119  UpdateWindow(HWnd);
120 
121  MSG msg;
122  while (GetMessage(&msg, NULL, 0, 0))
123  {
126  }
127  }
128  }
129  return 0;
130 }
131 //------------------------------------------------------------------
132 
133 
134 // image related
137 char *bbits = NULL; // bitmap bits
138 const char* filename = "LENA.BMP";
141 
142 // zooming related
143 float zoom_factor_h = 0.5;
144 float zoom_factor_v = 0.5;
145 RECT RDest = {5, 5, 0, 0};
148 
150  LPARAM LParam)
151 {
152  switch (Msg)
153  {
154  case WM_CREATE:
155  {
156  // check commandline
157  if (strlen(cmdline) != 0)
158  {
159 
160  useDIBits = TRUE;
161  }
162  else
163  useDIBits = FALSE;
164 
165  // create a memory DC
167  if (HMemDC)
168  {
169  // load a bitmap from file
170  HBITMAP HBmp =
171  static_cast<HBITMAP>(
173  0, 0, LR_LOADFROMFILE)
174  );
175  if (HBmp)
176  {
177  // extract dimensions of the bitmap
178  GetObject(HBmp, sizeof(BITMAP), &bmp);
179 
180  // fill the BITMAPINFO stucture for further use by StretchDIBits
182  bmInfo.bmiHeader.biWidth = bmp.bmWidth;
183  bmInfo.bmiHeader.biHeight = bmp.bmHeight;
184  bmInfo.bmiHeader.biPlanes = 1;//bmp.bmPlanes;
185  bmInfo.bmiHeader.biBitCount = bmp.bmBitsPixel;
191 
192  // associate the bitmap with the memory DC
193  HOldBmp = static_cast<HBITMAP>(
195  );
196 
197  if (useDIBits)
198  {
199  bbits = new char[bmp.bmHeight*bmp.bmWidthBytes*(bmp.bmBitsPixel / 8)];
200  //GetDIBits(HMemDC, HBmp, 0, bmp.bmHeight, bbits, &bmInfo, DIB_RGB_COLORS);
201 
202  // Here goes a temp hack, since GetDIBits doesn't exist in ReactOS yet
203  FILE *f = fopen(filename, "rb");
204  BITMAPFILEHEADER bmpHeader;
205 
206  fread(&bmpHeader, sizeof(BITMAPFILEHEADER), 1, f);
207  fread(&bmInfo, sizeof(BITMAPINFO), 1, f);
208  fseek(f, bmpHeader.bfOffBits, SEEK_SET);
209  fread(bbits, bmp.bmHeight*bmp.bmWidthBytes*(bmp.bmBitsPixel / 8), 1, f);
210 
211  fclose(f);
212  }
213  }
214  }
215  }
216  case WM_COMMAND:
217  {
218  if (WParam == MAKEWPARAM(ID_LISTBOX, LBN_SELCHANGE) ||
220  {
221  switch (SNDMSG(HListBox, LB_GETCURSEL, 0, 0))
222  {
223  case ID_ZOOM25: zoom_factor_h = 0.25; break;
224  case ID_ZOOM50: zoom_factor_h = 0.50; break;
225  case ID_ZOOM75: zoom_factor_h = 0.75; break;
226  case ID_ZOOM100: zoom_factor_h = 1.00; break;
227  case ID_ZOOM125: zoom_factor_h = 1.25; break;
228  case ID_ZOOM150: zoom_factor_h = 1.50; break;
229  case ID_ZOOM200: zoom_factor_h = 2.00; break;
230  case ID_ZOOM300: zoom_factor_h = 3.00; break;
231  }
232 
233  switch (SNDMSG(VListBox, LB_GETCURSEL, 0, 0))
234  {
235  case ID_ZOOM25: zoom_factor_v = 0.25; break;
236  case ID_ZOOM50: zoom_factor_v = 0.50; break;
237  case ID_ZOOM75: zoom_factor_v = 0.75; break;
238  case ID_ZOOM100: zoom_factor_v = 1.00; break;
239  case ID_ZOOM125: zoom_factor_v = 1.25; break;
240  case ID_ZOOM150: zoom_factor_v = 1.50; break;
241  case ID_ZOOM200: zoom_factor_v = 2.00; break;
242  case ID_ZOOM300: zoom_factor_v = 3.00; break;
243  }
244 
245  // calculate the new width and height
246  const int new_width =
247  static_cast<int>(zoom_factor_h * bmp.bmWidth);
248  const int new_height =
249  static_cast<int>(zoom_factor_v * bmp.bmHeight);
250 
251  // is zooming in?
252  bool zoom_in = (new_width > RDest.right - RDest.left);
253 
254  // caculate the area that needs to be updated
255  RECT RUpdate = {
256  RDest.left, RDest.top,
257  RDest.left + max(new_width, RDest.right - RDest.left),
258  RDest.top + max(new_height, RDest.bottom - RDest.top)
259  };
260 
261  // adjust the dimenstions of the
262  // destination rectangle
263  RDest.right = RDest.left + new_width;
264  RDest.bottom = RDest.top + new_height;
265 
266  // create an update region from the XOR combination
267  // of the update and destination rectangles
268  HRGN HUpdateRgn = CreateRectRgnIndirect(&RUpdate);
269  HRGN HDestRgn = CreateRectRgnIndirect(&RDest);
270  int result =
271  CombineRgn(HUpdateRgn, HUpdateRgn, HDestRgn, RGN_XOR);
272 
273  // incite a repaint
274  if (result != NULLREGION && result != ERROR)
275  {
276  InvalidateRgn(HWnd, HUpdateRgn, true);
278  }
279  else if (result == NULLREGION)
280  {
281  InvalidateRect(HWnd, &RUpdate, zoom_in ? false : true);
282  }
283 
284  // clean up
285  DeleteObject(HUpdateRgn);
286  DeleteObject(HDestRgn);
287  }
288  break;
289  }
290  case WM_PAINT:
291  {
292  PAINTSTRUCT ps;
293  const HDC Hdc = BeginPaint(HWnd, &ps);
294 #if 0
295  try
296 #endif
297  {
298  //
299  // TODO: add palette support (see Chapter 9)...
300  //
301  if (useDIBits)
302  {
303  if (RDest.right - RDest.left > 0)
304  {
305  if (zoom_factor_h < 1.0 || zoom_factor_v < 1.0)
306  {
308  }
309 
310  // render the zoomed image
312  RDest.right - RDest.left,
313  RDest.bottom - RDest.top,
314  0, 0,
315  bmp.bmWidth, bmp.bmHeight,
316  bbits, &bmInfo,
318  SRCCOPY);
319  }
320  }
321  else
322  {
323  if (RDest.right - RDest.left > 0)
324  {
325 
326  // use BitBlt when not zooming
327  if (zoom_factor_h == 1.0 && zoom_factor_v == 1.0)
328  {
329  BitBlt(Hdc, RDest.left, RDest.top,
330  RDest.right - RDest.left,
331  RDest.bottom - RDest.top,
332  HMemDC, 0, 0,
333  SRCCOPY);
334  }
335  else
336  {
337  if (zoom_factor_h < 1.0 || zoom_factor_v < 1.0)
338  {
340  }
341 
342  // render the zoomed image
343  StretchBlt(Hdc, RDest.left, RDest.top,
344  RDest.right - RDest.left,
345  RDest.bottom - RDest.top,
346  HMemDC, 0, 0,
347  bmp.bmWidth, bmp.bmHeight,
348  SRCCOPY);
349  }
350  }
351  }
352  }
353 #if 0
354  catch (...)
355 #endif
356  {
357  EndPaint(HWnd, &ps);
358  }
359  EndPaint(HWnd, &ps);
360  break;
361  }
362  case WM_DESTROY:
363  {
364  // clean up
366  DeleteDC(HMemDC);
367 
368  if (bbits)
369  delete[] bbits;
370 
371  PostQuitMessage(0);
372  return 0;
373  }
374  }
375  return DefWindowProc(HWnd, Msg, WParam, LParam);
376 }
377 //------------------------------------------------------------------
378 
379 
380 
int WINAPI CombineRgn(_In_opt_ HRGN hrgnDest, _In_opt_ HRGN hrgnSrc1, _In_opt_ HRGN hrgnSrc2, _In_ int fnCombineMode)
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
HDC HMemDC
Definition: stretchblt.cpp:139
HWND VListBox
Definition: stretchblt.cpp:25
int WINAPI StretchDIBits(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ const VOID *, _In_ const BITMAPINFO *, _In_ UINT, _In_ DWORD)
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
#define DispatchMessage
Definition: winuser.h:5666
#define max(a, b)
Definition: svc.c:63
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define TRUE
Definition: types.h:120
#define MAKEWPARAM(l, h)
Definition: winuser.h:3948
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1471
#define CreateWindow
Definition: winuser.h:5655
DWORD biClrImportant
Definition: amvideo.idl:40
#define LB_ADDSTRING
Definition: winuser.h:2013
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERROR(name)
Definition: error_private.h:53
#define LR_LOADFROMFILE
Definition: winuser.h:1082
LONG biXPelsPerMeter
Definition: amvideo.idl:37
struct tagBITMAPINFOHEADER BITMAPINFOHEADER
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
HRGN WINAPI CreateRectRgnIndirect(_In_ LPCRECT)
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
BOOL WINAPI UpdateWindow(_In_ HWND)
#define NULLREGION
Definition: wingdi.h:360
LONG top
Definition: windef.h:292
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define CS_HREDRAW
Definition: winuser.h:648
char * bbits
Definition: stretchblt.cpp:137
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
UINT_PTR WPARAM
Definition: windef.h:207
HBRUSH hbrBackground
Definition: winuser.h:3144
#define WS_CHILD
Definition: pedump.c:617
TCHAR * cmdline
Definition: stretchblt.cpp:32
LONG left
Definition: windef.h:291
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define COLORONCOLOR
Definition: wingdi.h:953
const char * filename
Definition: ioapi.h:135
LONG right
Definition: windef.h:293
#define LBN_SELCHANGE
Definition: winuser.h:2057
static VOID NTAPI BitBlt(IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN PUCHAR Buffer, IN ULONG BitsPerPixel, IN ULONG Delta)
Definition: vga.c:410
BOOL WINAPI StretchBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
float zoom_factor_h
Definition: stretchblt.cpp:143
CHAR * LPTSTR
Definition: xmlstorage.h:192
struct @1576 Msg[]
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
unsigned int BOOL
Definition: ntddk_ex.h:94
#define RGN_XOR
Definition: wingdi.h:359
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
DWORD biCompression
Definition: amvideo.idl:35
HCURSOR hCursor
Definition: winuser.h:3143
#define CreateWindowEx
Definition: winuser.h:5656
const int ID_LISTBOX2
Definition: stretchblt.cpp:27
smooth NULL
Definition: ftsmooth.c:416
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
LONG_PTR LPARAM
Definition: windef.h:208
LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, LPARAM LParam)
Definition: stretchblt.cpp:149
BOOL WINAPI InvalidateRgn(_In_ HWND, _In_opt_ HRGN, _In_ BOOL)
#define DefWindowProc
Definition: ros2win.h:31
#define WM_DESTROY
Definition: winuser.h:1591
#define WS_CAPTION
Definition: pedump.c:624
#define CS_VREDRAW
Definition: winuser.h:653
#define SEEK_SET
Definition: jmemansi.c:26
char TCHAR
Definition: xmlstorage.h:189
GLfloat f
Definition: glext.h:7540
HINSTANCE HPrevInst
Definition: stretchblt.cpp:31
const char * WndClassName
Definition: stretchblt.cpp:33
RECT RDest
Definition: stretchblt.cpp:145
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
HINSTANCE HInst
Definition: stretchblt.cpp:30
DWORD biSizeImage
Definition: amvideo.idl:36
#define GetObject
Definition: wingdi.h:4463
#define WM_PAINT
Definition: winuser.h:1602
#define COLOR_BTNFACE
Definition: winuser.h:918
#define RDW_NOERASE
Definition: winuser.h:1201
#define CS_DBLCLKS
Definition: winuser.h:646
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
BITMAP bmp
Definition: stretchblt.cpp:135
#define WM_COMMAND
Definition: winuser.h:1722
LPCSTR lpszClassName
Definition: winuser.h:3146
HWND HListBox
Definition: stretchblt.cpp:24
#define LoadCursor
Definition: winuser.h:5713
int WINAPI SetStretchBltMode(_In_ HDC, _In_ int)
Definition: dc.c:1324
UINT style
Definition: winuser.h:3137
#define SNDMSG
Definition: treelist.h:31
#define TEXT(s)
Definition: k32.h:26
#define LBS_NOTIFY
Definition: pedump.c:678
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
BOOL WINAPI DeleteDC(_In_ HDC)
HINSTANCE hInstance
Definition: winuser.h:3141
Definition: bl.h:1331
const int ID_LISTBOX
Definition: stretchblt.cpp:26
#define LB_GETCURSEL
Definition: winuser.h:2021
unsigned int UINT
Definition: ndis.h:50
#define IMAGE_BITMAP
Definition: winuser.h:211
#define GetMessage
Definition: winuser.h:5691
WNDPROC lpfnWndProc
Definition: winuser.h:3138
BITMAPINFO bmInfo
Definition: stretchblt.cpp:136
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define WM_CREATE
Definition: winuser.h:1590
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
HBITMAP HOldBmp
Definition: stretchblt.cpp:140
LONG bottom
Definition: windef.h:294
#define LoadImage
Definition: winuser.h:5716
static HBITMAP
Definition: button.c:44
#define RegisterClass
Definition: winuser.h:5737
int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
Definition: stretchblt.cpp:38
LONG_PTR LRESULT
Definition: windef.h:209
#define DIB_RGB_COLORS
Definition: wingdi.h:366
#define WS_VISIBLE
Definition: pedump.c:620
BOOL useDIBits
Definition: stretchblt.cpp:28
float zoom_factor_v
Definition: stretchblt.cpp:144
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
#define BI_RGB
Definition: precomp.h:34
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define SRCCOPY
Definition: wingdi.h:332
#define APIENTRY
Definition: api.h:79
#define RDW_INVALIDATE
Definition: winuser.h:1200
HBITMAP HBmp