rnd-20090623-1-src
[rocksndiamonds.git] / src / game_sp / Capture.c
1 // ----------------------------------------------------------------------------
2 // Capture.c
3 // ----------------------------------------------------------------------------
4
5 #include "Capture.h"
6
7 static char *VB_Name = "CaptureModule";
8 // --------------------------------------------------------------------
9 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
10 //
11 // Visual Basic 4.0 16/32 Capture Routines
12 //
13 // This module contains several routines for capturing windows into a
14 // picture.  All the routines work on both 16 and 32 bit Windows
15 // platforms.
16 // The routines also have palette support.
17 //
18 // CreateBitmapPicture - Creates a picture object from a bitmap and
19 // palette.
20 // CaptureWindow - Captures any window given a window handle.
21 // CaptureActiveWindow - Captures the active window on the desktop.
22 // CaptureForm - Captures the entire form.
23 // CaptureClient - Captures the client area of a form.
24 // CaptureScreen - Captures the entire screen.
25 // PrintPictureToFitPage - prints any picture as big as possible on
26 // the page.
27 //
28 // NOTES
29 //    - No error trapping is included in these routines.
30 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
31 //
32 // --- Option Explicit
33 // --- Option Base 0
34
35 // ::: #ifndef HAS_PALETTEENTRY
36 // ::: typedef struct
37 // ::: {
38 // :::   byte peRed;
39 // :::   byte peGreen;
40 // :::   byte peBlue;
41 // :::   byte peFlags;
42 // ::: } PALETTEENTRY;
43 // ::: #define HAS_PALETTEENTRY
44 // ::: #endif
45
46 // ::: #ifndef HAS_LOGPALETTE
47 // ::: typedef struct
48 // ::: {
49 // :::   int palVersion;
50 // :::   int palNumEntries;
51 // :::   PALETTEENTRY palPalEntry[255];  // Enough for 256 colors.
52 // ::: } LOGPALETTE;
53 // ::: #define HAS_LOGPALETTE
54 // ::: #endif
55
56 // ::: #ifndef HAS_GUID
57 // ::: typedef struct
58 // ::: {
59 // :::   long Data1;
60 // :::   int Data2;
61 // :::   int Data3;
62 // :::   byte Data4[7];
63 // ::: } GUID;
64 // ::: #define HAS_GUID
65 // ::: #endif
66
67 #if Win32
68
69 #define RASTERCAPS                      (38)
70 #define RC_PALETTE                      (0x100)
71 #define SIZEPALETTE                     (104)
72
73 // ::: #ifndef HAS_RECT
74 // ::: typedef struct
75 // ::: {
76 // :::   long left;
77 // :::   long top;
78 // :::   long right;
79 // :::   long bottom;
80 // ::: } RECT;
81 // ::: #define HAS_RECT
82 // ::: #endif
83
84 long CreateCompatibleDC(long hDC);
85 long CreateCompatibleBitmap(long hDC, long nWidth, long nHeight);
86 long GetDeviceCaps(long hDC, long iCapabilitiy);
87 long GetSystemPaletteEntries(long hDC, long wStartIndex, long wNumEntries, PALETTEENTRY lpPaletteEntries);
88 long CreatePalette(LOGPALETTE lpLogPalette);
89 long SelectObject(long hDC, long hObject);
90 long BitBlt(long hDCDest, long XDest, long YDest, long nWidth, long nHeight, long hDCSrc, long XSrc, long YSrc, long dwRop);
91 long DeleteDC(long hDC);
92 long GetForegroundWindow();
93 long SelectPalette(long hDC, long hPalette, long bForceBackground);
94 long RealizePalette(long hDC);
95 long GetWindowDC(long hWnd);
96 long GetDC(long hWnd);
97 long GetWindowRect(long hWnd, RECT lpRect);
98 long ReleaseDC(long hWnd, long hDC);
99 long GetDesktopWindow();
100
101 // ::: #ifndef HAS_PicBmp
102 // ::: typedef struct
103 // ::: {
104 // :::   long Size;
105 // :::   long Type;
106 // :::   long hBmp;
107 // :::   long hPal;
108 // :::   long Reserved;
109 // ::: } PicBmp;
110 // ::: #define HAS_PicBmp
111 // ::: #endif
112
113 long OleCreatePictureIndirect(PicBmp PicDesc, GUID RefIID, long fPictureOwnsHandle, IPicture IPic);
114
115 #elif Win16
116
117 #define RASTERCAPS                      (38)
118 #define RC_PALETTE                      (0x100)
119 #define SIZEPALETTE                     (104)
120
121 // ::: #ifndef HAS_RECT
122 // ::: typedef struct
123 // ::: {
124 // :::   int left;
125 // :::   int top;
126 // :::   int right;
127 // :::   int bottom;
128 // ::: } RECT;
129 // ::: #define HAS_RECT
130 // ::: #endif
131
132 int CreateCompatibleDC(int hDC);
133 int CreateCompatibleBitmap(int hDC, int nWidth, int nHeight);
134 int GetDeviceCaps(int hDC, int iCapabilitiy);
135 int GetSystemPaletteEntries(int hDC, int wStartIndex, int wNumEntries, PALETTEENTRY lpPaletteEntries);
136 int CreatePalette(LOGPALETTE lpLogPalette);
137 int SelectObject(int hDC, int hObject);
138 int BitBlt(int hDCDest, int XDest, int YDest, int nWidth, int nHeight, int hDCSrc, int XSrc, int YSrc, long dwRop);
139 int DeleteDC(int hDC);
140 int GetForegroundWindow();
141 int SelectPalette(int hDC, int hPalette, int bForceBackground);
142 int RealizePalette(int hDC);
143 int GetWindowDC(int hWnd);
144 int GetDC(int hWnd);
145 int GetWindowRect(int hWnd, RECT lpRect);
146 int ReleaseDC(int hWnd, int hDC);
147 int GetDesktopWindow();
148
149 // ::: #ifndef HAS_PicBmp
150 // ::: typedef struct
151 // ::: {
152 // :::   int Size;
153 // :::   int Type;
154 // :::   int hBmp;
155 // :::   int hPal;
156 // :::   int Reserved;
157 // ::: } PicBmp;
158 // ::: #define HAS_PicBmp
159 // ::: #endif
160
161 int OleCreatePictureIndirect(PicBmp PictDesc, GUID RefIID, int fPictureOwnsHandle, IPicture IPic);
162
163 #endif
164
165 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
166 //
167 // CreateBitmapPicture
168 //    - Creates a bitmap type Picture object from a bitmap and
169 //      palette.
170 //
171 // hBmp
172 //    - Handle to a bitmap.
173 //
174 // hPal
175 //    - Handle to a Palette.
176 //    - Can be null if the bitmap doesn't use a palette.
177 //
178 // Returns
179 //    - Returns a Picture object containing the bitmap.
180 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
181 //
182 #if Win32
183 Picture CreateBitmapPicture(long hBmp, long hPal)
184 {
185   Picture CreateBitmapPicture;
186
187   long r;
188
189 #elif Win16
190 Picture CreateBitmapPicture(int hBmp, int hPal)
191 {
192   Picture CreateBitmapPicture;
193
194   int r;
195
196 #endif
197   PicBmp pic;
198
199   // IPicture requires a reference to "Standard OLE Types."
200   IPicture IPic;
201   GUID IID_IDispatch;
202
203   // Fill in with IDispatch Interface ID.
204   {
205     IID_IDispatch.Data1 = 0x20400;
206     IID_IDispatch.Data4[0] = 0xC0;
207     IID_IDispatch.Data4[7] = 0x46;
208   }
209
210   // Fill Pic with necessary parts.
211   {
212     pic.Size = Len(pic);          // Length of structure.
213     pic.Type = vbPicTypeBitmap;   // Type of Picture (bitmap).
214     pic.hBmp = hBmp;              // Handle to bitmap.
215     pic.hPal = hPal;              // Handle to palette (may be null).
216   }
217
218   // Create Picture object.
219   r = OleCreatePictureIndirect(pic, IID_IDispatch, 1, IPic);
220
221   // Return the new Picture object.
222   CreateBitmapPicture = IPic;
223
224   return CreateBitmapPicture;
225 }
226
227 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
228 //
229 // CaptureWindow
230 //    - Captures any portion of a window.
231 //
232 // hWndSrc
233 //    - Handle to the window to be captured.
234 //
235 // Client
236 //    - If True CaptureWindow captures from the client area of the
237 //      window.
238 //    - If False CaptureWindow captures from the entire window.
239 //
240 // LeftSrc, TopSrc, WidthSrc, HeightSrc
241 //    - Specify the portion of the window to capture.
242 //    - Dimensions need to be specified in pixels.
243 //
244 // Returns
245 //    - Returns a Picture object containing a bitmap of the specified
246 //      portion of the window that was captured.
247 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
248 // '''''
249 //
250 #if Win32
251 Picture CaptureWindow(long hWndSrc, boolean Client, long LeftSrc, long TopSrc, long WidthSrc, long HeightSrc)
252 {
253   Picture CaptureWindow;
254
255   long hDCMemory;
256   long hBmp;
257   long hBmpPrev;
258   long r;
259   long hDCSrc;
260   long hPal;
261   long hPalPrev;
262   long RasterCapsScrn;
263   long HasPaletteScrn;
264   long PaletteSizeScrn;
265
266 #elif Win16
267 Picture CaptureWindow(int hWndSrc, boolean Client, int LeftSrc, int TopSrc, long WidthSrc, long HeightSrc)
268 {
269   Picture CaptureWindow;
270
271   int hDCMemory;
272   int hBmp;
273   int hBmpPrev;
274   int r;
275   int hDCSrc;
276   int hPal;
277   int hPalPrev;
278   int RasterCapsScrn;
279   int HasPaletteScrn;
280   int PaletteSizeScrn;
281
282 #endif
283   LOGPALETTE LogPal;
284
285   // Depending on the value of Client get the proper device context.
286   if (Client)
287   {
288     hDCSrc = GetDC(hWndSrc); // Get device context for client area.
289   }
290   else
291   {
292     hDCSrc = GetWindowDC(hWndSrc); // Get device context for entire
293     // window.
294   }
295
296   // Create a memory device context for the copy process.
297   hDCMemory = CreateCompatibleDC(hDCSrc);
298   // Create a bitmap and place it in the memory DC.
299   hBmp = CreateCompatibleBitmap(hDCSrc, WidthSrc, HeightSrc);
300   hBmpPrev = SelectObject(hDCMemory, hBmp);
301
302   // Get screen properties.
303   RasterCapsScrn = GetDeviceCaps(hDCSrc, RASTERCAPS); // Raster
304   // capabilities.
305   HasPaletteScrn = RasterCapsScrn & RC_PALETTE;       // Palette
306   // support.
307   PaletteSizeScrn = GetDeviceCaps(hDCSrc, SIZEPALETTE); // Size of
308   // palette.
309
310   // If the screen has a palette make a copy and realize it.
311   if (HasPaletteScrn && (PaletteSizeScrn == 256))
312   {
313     // Create a copy of the system palette.
314     LogPal.palVersion = 0x300;
315     LogPal.palNumEntries = 256;
316     r = GetSystemPaletteEntries(hDCSrc, 0, 256, LogPal.palPalEntry[0]);
317     hPal = CreatePalette(LogPal);
318     // Select the new palette into the memory DC and realize it.
319     hPalPrev = SelectPalette(hDCMemory, hPal, 0);
320     r = RealizePalette(hDCMemory);
321   }
322
323   // Copy the on-screen image into the memory DC.
324   r = BitBlt(hDCMemory, 0, 0, WidthSrc, HeightSrc, hDCSrc, LeftSrc, TopSrc, vbSrcCopy);
325
326   // Remove the new copy of the  on-screen image.
327   hBmp = SelectObject(hDCMemory, hBmpPrev);
328
329   // If the screen has a palette get back the palette that was
330   // selected in previously.
331   if (HasPaletteScrn && (PaletteSizeScrn == 256))
332   {
333     hPal = SelectPalette(hDCMemory, hPalPrev, 0);
334   }
335
336   // Release the device context resources back to the system.
337   r = DeleteDC(hDCMemory);
338   r = ReleaseDC(hWndSrc, hDCSrc);
339
340   // Call CreateBitmapPicture to create a picture object from the
341   // bitmap and palette handles. Then return the resulting picture
342   // object.
343
344   CaptureWindow = CreateBitmapPicture(hBmp, hPal);
345
346   return CaptureWindow;
347 }
348
349 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
350 //
351 // CaptureScreen
352 //    - Captures the entire screen.
353 //
354 // Returns
355 //    - Returns a Picture object containing a bitmap of the screen.
356 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
357 //
358 Picture CaptureScreen()
359 {
360   Picture CaptureScreen;
361
362 #if Win32
363   long hWndScreen;
364
365 #elif Win16
366   int hWndScreen;
367
368 #endif
369
370   // Get a handle to the desktop window.
371   hWndScreen = GetDesktopWindow();
372
373   // Call CaptureWindow to capture the entire desktop give the handle
374   // and return the resulting Picture object.
375
376   CaptureScreen = CaptureWindow(hWndScreen, False, 0, 0, Screen.Width / Screen.TwipsPerPixelX, Screen.Height / Screen.TwipsPerPixelY);
377
378   return CaptureScreen;
379 }
380
381 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
382 //
383 // CaptureForm
384 //    - Captures an entire form including title bar and border.
385 //
386 // frmSrc
387 //    - The Form object to capture.
388 //
389 // Returns
390 //    - Returns a Picture object containing a bitmap of the entire
391 //      form.
392 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
393 //
394 Picture CaptureForm(Form frmSrc)
395 {
396   Picture CaptureForm;
397
398   // Call CaptureWindow to capture the entire form given its window
399   // handle and then return the resulting Picture object.
400   CaptureForm = CaptureWindow(frmSrc.hWnd, False, 0, 0, frmSrc.ScaleX(frmSrc.Width, vbTwips, vbPixels), frmSrc.ScaleY(frmSrc.Height, vbTwips, vbPixels));
401
402   return CaptureForm;
403 }
404
405 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
406 //
407 // CaptureClient
408 //    - Captures the client area of a form.
409 //
410 // frmSrc
411 //    - The Form object to capture.
412 //
413 // Returns
414 //    - Returns a Picture object containing a bitmap of the form's
415 //      client area.
416 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
417 //
418 Picture CaptureClient(Form frmSrc)
419 {
420   Picture CaptureClient;
421
422   // Call CaptureWindow to capture the client area of the form given
423   // its window handle and return the resulting Picture object.
424   CaptureClient = CaptureWindow(frmSrc.hWnd, True, 0, 0, frmSrc.ScaleX(frmSrc.ScaleWidth, frmSrc.ScaleMode, vbPixels), frmSrc.ScaleY(frmSrc.ScaleHeight, frmSrc.ScaleMode, vbPixels));
425
426   return CaptureClient;
427 }
428
429 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
430 //
431 // CaptureActiveWindow
432 //    - Captures the currently active window on the screen.
433 //
434 // Returns
435 //    - Returns a Picture object containing a bitmap of the active
436 //      window.
437 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
438 //
439 Picture CaptureActiveWindow()
440 {
441   Picture CaptureActiveWindow;
442
443 #if Win32
444   long hWndActive;
445   long r;
446
447 #elif Win16
448   int hWndActive;
449   int r;
450
451 #endif
452   RECT RectActive;
453
454   // Get a handle to the active/foreground window.
455   hWndActive = GetForegroundWindow();
456
457   // Get the dimensions of the window.
458   r = GetWindowRect(hWndActive, RectActive);
459
460   // Call CaptureWindow to capture the active window given its
461   // handle and return the Resulting Picture object.
462   CaptureActiveWindow = CaptureWindow(hWndActive, False, 0, 0, RectActive.right - RectActive.left, RectActive.bottom - RectActive.top);
463
464   return CaptureActiveWindow;
465 }
466
467 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
468
469 //
470 // PrintPictureToFitPage
471 //    - Prints a Picture object as big as possible.
472 //
473 // Prn
474 //    - Destination Printer object.
475 //
476 // Pic
477 //    - Source Picture object.
478 // ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
479 //
480 void PrintPictureToFitPage(Printer Prn, Picture pic)
481 {
482   #define vbHiMetric                    (8)
483   double PicRatio;
484   double PrnWidth;
485   double PrnHeight;
486   double PrnRatio;
487   double PrnPicWidth;
488   double PrnPicHeight;
489
490   // Determine if picture should be printed in landscape or portrait
491   // and set the orientation.
492   if (pic.Height >= pic.Width)
493   {
494     Prn.Orientation = vbPRORPortrait;   // Taller than wide.
495   }
496   else
497   {
498     Prn.Orientation = vbPRORLandscape;  // Wider than tall.
499   }
500
501   // Calculate device independent Width-to-Height ratio for picture.
502   PicRatio = pic.Width / pic.Height;
503
504   // Calculate the dimentions of the printable area in HiMetric.
505   PrnWidth = Prn.ScaleX(Prn.ScaleWidth, Prn.ScaleMode, vbHiMetric);
506   PrnHeight = Prn.ScaleY(Prn.ScaleHeight, Prn.ScaleMode, vbHiMetric);
507   // Calculate device independent Width to Height ratio for printer.
508   PrnRatio = PrnWidth / PrnHeight;
509
510   // Scale the output to the printable area.
511   if (PicRatio >= PrnRatio)
512   {
513     // Scale picture to fit full width of printable area.
514     PrnPicWidth = Prn.ScaleX(PrnWidth, vbHiMetric, Prn.ScaleMode);
515     PrnPicHeight = Prn.ScaleY(PrnWidth / PicRatio, vbHiMetric, Prn.ScaleMode);
516   }
517   else
518   {
519     // Scale picture to fit full height of printable area.
520     PrnPicHeight = Prn.ScaleY(PrnHeight, vbHiMetric, Prn.ScaleMode);
521     PrnPicWidth = Prn.ScaleX(PrnHeight * PicRatio, vbHiMetric, Prn.ScaleMode);
522   }
523
524   // Print the picture using the PaintPicture method.
525   Prn_PaintPicture(pic, 0, 0, PrnPicWidth, PrnPicHeight);
526 }
527
528 // --------------------------------------------------------------------
529