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