|
|
1.1 root 1: /*------------------------------------
2: BLOWUP.C -- Screen Capture Program
3: ------------------------------------*/
4:
5: #define INCL_WIN
6: #define INCL_GPI
7: #include <os2.h>
8: #include "blowup.h"
9:
10: MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
11:
12: CHAR szClientClass [] = "BlowUp" ;
13: HAB hab ;
14:
15: int main (void)
16: {
17: static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
18: FCF_SIZEBORDER | FCF_MINMAX |
19: FCF_SHELLPOSITION | FCF_TASKLIST |
20: FCF_MENU | FCF_ACCELTABLE ;
21: HMQ hmq ;
22: HWND hwndFrame, hwndClient ;
23: QMSG qmsg ;
24:
25: hab = WinInitialize (0) ;
26: hmq = WinCreateMsgQueue (hab, 0) ;
27:
28: WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
29:
30: hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
31: &flFrameFlags, szClientClass, NULL,
32: 0L, NULL, ID_RESOURCE, &hwndClient) ;
33:
34: WinSendMsg (hwndFrame, WM_SETICON,
35: WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE),
36: NULL) ;
37:
38: while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
39: WinDispatchMsg (hab, &qmsg) ;
40:
41: WinDestroyWindow (hwndFrame) ;
42: WinDestroyMsgQueue (hmq) ;
43: WinTerminate (hab) ;
44: return 0 ;
45: }
46:
47: BOOL BeginTracking (RECTL *prclTrack)
48: {
49: LONG cxScreen, cyScreen, cxPointer, cyPointer ;
50: TRACKINFO ti ;
51:
52: cxScreen = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN) ;
53: cyScreen = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN) ;
54: cxPointer = WinQuerySysValue (HWND_DESKTOP, SV_CXPOINTER) ;
55: cyPointer = WinQuerySysValue (HWND_DESKTOP, SV_CYPOINTER) ;
56:
57: // Set up track rectangle for moving
58:
59: ti.cxBorder = 1 ; // Border width
60: ti.cyBorder = 1 ;
61: ti.cxGrid = 0 ; // Not used
62: ti.cyGrid = 0 ;
63: ti.cxKeyboard = 4 ; // Pixel increment for keyboard
64: ti.cyKeyboard = 4 ;
65:
66: ti.rclBoundary.xLeft = 0 ; // Area for tracking rectangle
67: ti.rclBoundary.yBottom = 0 ;
68: ti.rclBoundary.xRight = cxScreen ;
69: ti.rclBoundary.yTop = cyScreen ;
70:
71: ti.ptlMinTrackSize.x = 1 ; // Minimum rectangle size
72: ti.ptlMinTrackSize.y = 1 ;
73:
74: ti.ptlMaxTrackSize.x = cxScreen ; // Maximum rectangle size
75: ti.ptlMaxTrackSize.y = cyScreen ;
76: // Initial position
77:
78: ti.rclTrack.xLeft = (cxScreen - cxPointer) / 2 ;
79: ti.rclTrack.yBottom = (cyScreen - cyPointer) / 2 ;
80: ti.rclTrack.xRight = (cxScreen + cxPointer) / 2 ;
81: ti.rclTrack.yTop = (cyScreen + cyPointer) / 2 ;
82:
83: ti.fs = TF_MOVE | TF_STANDARD | TF_SETPOINTERPOS ; // Flags
84:
85: if (!WinTrackRect (HWND_DESKTOP, NULL, &ti))
86: return FALSE ;
87: // Switch to "sizing" pointer
88: WinSetPointer (HWND_DESKTOP,
89: WinQuerySysPointer (HWND_DESKTOP, SPTR_SIZENESW, FALSE)) ;
90:
91: // Track rectangle for sizing
92:
93: ti.fs = TF_RIGHT | TF_TOP | TF_STANDARD | TF_SETPOINTERPOS ;
94:
95: if (!WinTrackRect (HWND_DESKTOP, NULL, &ti))
96: return FALSE ;
97:
98: *prclTrack = ti.rclTrack ; // Final rectangle
99:
100: return TRUE ;
101: }
102:
103: HBITMAP CopyScreenToBitmap (RECTL *prclTrack)
104: {
105: BITMAPINFOHEADER bmp ;
106: HBITMAP hbm ;
107: HDC hdcMemory ;
108: HPS hps, hpsMemory ;
109: LONG alBmpFormats[2] ;
110: POINTL aptl[3] ;
111: SIZEL sizl ;
112: // Create memory DC and PS
113:
114: hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
115:
116: sizl.cx = sizl.cy = 0 ;
117: hpsMemory = GpiCreatePS (hab, hdcMemory, &sizl,
118: PU_PELS | GPIF_DEFAULT |
119: GPIT_MICRO | GPIA_ASSOC) ;
120:
121: // Create bitmap for destination
122:
123: GpiQueryDeviceBitmapFormats (hpsMemory, 2L, alBmpFormats) ;
124:
125: bmp.cbFix = sizeof bmp ;
126: bmp.cx = (USHORT) (prclTrack->xRight - prclTrack->xLeft) ;
127: bmp.cy = (USHORT) (prclTrack->yTop - prclTrack->yBottom) ;
128: bmp.cPlanes = (USHORT) alBmpFormats[0] ;
129: bmp.cBitCount = (USHORT) alBmpFormats[1] ;
130:
131: hbm = GpiCreateBitmap (hpsMemory, &bmp, 0L, NULL, NULL) ;
132:
133: // Copy from screen to bitmap
134: if (hbm != NULL)
135: {
136: GpiSetBitmap (hpsMemory, hbm) ;
137: hps = WinGetScreenPS (HWND_DESKTOP) ;
138:
139: aptl[0].x = 0 ;
140: aptl[0].y = 0 ;
141: aptl[1].x = bmp.cx ;
142: aptl[1].y = bmp.cy ;
143: aptl[2].x = prclTrack->xLeft ;
144: aptl[2].y = prclTrack->yBottom ;
145:
146: WinLockVisRegions (HWND_DESKTOP, TRUE) ;
147:
148: GpiBitBlt (hpsMemory, hps, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
149:
150: WinLockVisRegions (HWND_DESKTOP, FALSE) ;
151:
152: WinReleasePS (hps) ;
153: }
154: // Clean up
155: GpiDestroyPS (hpsMemory) ;
156: DevCloseDC (hdcMemory) ;
157:
158: return hbm ;
159: }
160:
161: HBITMAP CopyBitmap (HBITMAP hbmSrc)
162: {
163: BITMAPINFOHEADER bmp ;
164: HBITMAP hbmDst ;
165: HDC hdcSrc, hdcDst ;
166: HPS hpsSrc, hpsDst ;
167: POINTL aptl[3] ;
168: SIZEL sizl ;
169:
170: // Create memory DC's and PS's
171:
172: hdcSrc = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
173: hdcDst = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
174:
175: sizl.cx = sizl.cy = 0 ;
176: hpsSrc = GpiCreatePS (hab, hdcSrc, &sizl, PU_PELS | GPIF_DEFAULT |
177: GPIT_MICRO | GPIA_ASSOC) ;
178:
179: hpsDst = GpiCreatePS (hab, hdcDst, &sizl, PU_PELS | GPIF_DEFAULT |
180: GPIT_MICRO | GPIA_ASSOC) ;
181:
182: // Create bitmap
183:
184: GpiQueryBitmapParameters (hbmSrc, &bmp) ;
185: hbmDst = GpiCreateBitmap (hpsDst, &bmp, 0L, NULL, NULL) ;
186:
187: // Copy from source to destination
188:
189: if (hbmDst != NULL)
190: {
191: GpiSetBitmap (hpsSrc, hbmSrc) ;
192: GpiSetBitmap (hpsDst, hbmDst) ;
193:
194: aptl[0].x = aptl[0].y = 0 ;
195: aptl[1].x = bmp.cx ;
196: aptl[1].y = bmp.cy ;
197: aptl[2] = aptl[0] ;
198:
199: GpiBitBlt (hpsDst, hpsSrc, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
200: }
201: // Clean up
202: GpiDestroyPS (hpsSrc) ;
203: GpiDestroyPS (hpsDst) ;
204: DevCloseDC (hdcSrc) ;
205: DevCloseDC (hdcDst) ;
206:
207: return hbmDst ;
208: }
209:
210: VOID BitmapCreationError (HWND hwnd)
211: {
212: WinMessageBox (HWND_DESKTOP, hwnd, "Cannot create bitmap.",
213: szClientClass, 0, MB_OK | MB_ICONEXCLAMATION) ;
214: }
215:
216: MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
217: {
218: static HBITMAP hbm ;
219: static HWND hwndMenu ;
220: static SHORT sDisplay = IDM_ACTUAL ;
221: HBITMAP hbmClip ;
222: HPS hps ;
223: RECTL rclTrack, rclClient ;
224: USHORT usfInfo ;
225:
226: switch (msg)
227: {
228: case WM_CREATE:
229: hwndMenu = WinWindowFromID (
230: WinQueryWindow (hwnd, QW_PARENT, FALSE),
231: FID_MENU) ;
232: return 0 ;
233:
234: case WM_INITMENU:
235: switch (SHORT1FROMMP (mp1))
236: {
237: case IDM_EDIT:
238: WinSendMsg (hwndMenu, MM_SETITEMATTR,
239: MPFROM2SHORT (IDM_COPY, TRUE),
240: MPFROM2SHORT (MIA_DISABLED,
241: hbm != NULL ? 0 : MIA_DISABLED)) ;
242:
243: WinSendMsg (hwndMenu, MM_SETITEMATTR,
244: MPFROM2SHORT (IDM_PASTE, TRUE),
245: MPFROM2SHORT (MIA_DISABLED,
246: WinQueryClipbrdFmtInfo (hab, CF_BITMAP, &usfInfo)
247: ? 0 : MIA_DISABLED)) ;
248: return 0 ;
249: }
250: break ;
251:
252: case WM_COMMAND:
253: switch (COMMANDMSG(&msg)->cmd)
254: {
255: case IDM_COPY:
256: // Make copy of stored bitmap
257:
258: hbmClip = CopyBitmap (hbm) ;
259:
260: // Set clipboard data to copy of bitmap
261:
262: if (hbmClip != NULL)
263: {
264: WinOpenClipbrd (hab) ;
265: WinEmptyClipbrd (hab) ;
266: WinSetClipbrdData (hab, (ULONG) hbmClip,
267: CF_BITMAP, CFI_HANDLE) ;
268: WinCloseClipbrd (hab) ;
269: }
270: else
271: BitmapCreationError (hwnd) ;
272: return 0 ;
273:
274: case IDM_PASTE:
275: // Get bitmap from clipboard
276:
277: WinOpenClipbrd (hab) ;
278: hbmClip = WinQueryClipbrdData (hab, CF_BITMAP) ;
279:
280: if (hbmClip != NULL)
281: {
282: if (hbm != NULL)
283: GpiDeleteBitmap (hbm) ;
284:
285: // Make copy of it
286:
287: hbm = CopyBitmap (hbmClip) ;
288:
289: if (hbm == NULL)
290: BitmapCreationError (hwnd) ;
291: }
292: WinCloseClipbrd (hab) ;
293: WinInvalidateRect (hwnd, NULL, FALSE) ;
294: return 0 ;
295:
296: case IDM_CAPTURE:
297: if (BeginTracking (&rclTrack))
298: {
299: if (hbm != NULL)
300: GpiDeleteBitmap (hbm) ;
301:
302: hbm = CopyScreenToBitmap (&rclTrack) ;
303:
304: if (hbm == NULL)
305: BitmapCreationError (hwnd) ;
306:
307: WinInvalidateRect (hwnd, NULL, FALSE) ;
308: }
309: return 0 ;
310:
311: case IDM_ACTUAL:
312: case IDM_STRETCH:
313: WinSendMsg (hwndMenu, MM_SETITEMATTR,
314: MPFROM2SHORT (sDisplay, TRUE),
315: MPFROM2SHORT (MIA_CHECKED, 0)) ;
316:
317: sDisplay = COMMANDMSG(&msg)->cmd ;
318:
319: WinSendMsg (hwndMenu, MM_SETITEMATTR,
320: MPFROM2SHORT (sDisplay, TRUE),
321: MPFROM2SHORT (MIA_CHECKED, MIA_CHECKED)) ;
322:
323: WinInvalidateRect (hwnd, NULL, FALSE) ;
324: return 0 ;
325: }
326:
327: case WM_PAINT:
328: hps = WinBeginPaint (hwnd, NULL, NULL) ;
329: GpiErase (hps) ;
330:
331: if (hbm != NULL)
332: {
333: WinQueryWindowRect (hwnd, &rclClient) ;
334:
335: WinDrawBitmap (hps, hbm, NULL, (PPOINTL) &rclClient,
336: CLR_NEUTRAL, CLR_BACKGROUND,
337: sDisplay == IDM_STRETCH ?
338: DBM_STRETCH : DBM_NORMAL) ;
339: }
340: WinEndPaint (hps) ;
341: return 0 ;
342:
343: case WM_DESTROY:
344: if (hbm != NULL)
345: GpiDeleteBitmap (hbm) ;
346: return 0 ;
347: }
348: return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
349: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.