|
|
1.1 root 1: /*
2: * snap.c -- PM snapshot utility
3: *
4: * Created by Microsoft, IBM Corporation 1990
5: *
6: * DISCLAIMER OF WARRANTIES. The following [enclosed] code is
7: * sample code created by Microsoft Corporation and/or IBM
8: * Corporation. This sample code is not part of any standard
9: * Microsoft or IBM product and is provided to you solely for
10: * the purpose of assisting you in the development of your
11: * applications. The code is provided "AS IS", without
12: * warranty of any kind. Neither Microsoft nor IBM shall be
13: * liable for any damages arising out of your use of the sample
14: * code, even if they have been advised of the possibility of
15: * such damages.
16: *
17: */
18: #define INCL_WIN
19: #define INCL_GPI
20: #define INCL_DEV
21: #define INCL_DOSMEMMGR
22: #include <os2.h>
23: #include "snap.h"
24:
25: /* Global variables */
26: char szSnap[5];
27:
28: HAB habSnap;
29: HMQ hmqSnap;
30: HWND hwndSnap, hwndSnapFrame;
31: HWND hwndNextClipViewer;
32: HPS hpsScr;
33:
34: HPOINTER hptrSnap;
35: HPOINTER hptrHand;
36: HPOINTER hptrSelect;
37:
38: RECTL wrcRgn; /* holds coordinates of selected region. */
39: RECTL rcScreen; /* rectangle for the screen for bounding */
40:
41: int wSnapMode = IDM_WINDOW; /* snap either selected window or region. */
42:
43: BOOL fSnapWnd = FALSE; /* snap selected window? */
44: BOOL fSnapRgn = FALSE; /* snap selected region? */
45: BOOL fSelect = FALSE; /* in the process of selecting region? */
46: BOOL fNCArea = FALSE; /* exclude nonclient area of window in snap? */
47: BOOL fHide = TRUE; /* hide snap's window while snapping */
48:
49:
50: /* Function prototypes */
51: MRESULT EXPENTRY SnapWndProc(HWND, USHORT, MPARAM, MPARAM);
52: MRESULT EXPENTRY AboutWndProc(HWND, USHORT, MPARAM, MPARAM);
53: MRESULT EXPENTRY SaveFileDlgProc(HWND, USHORT, MPARAM, MPARAM);
54: HFILE OpenSaveFile(HWND);
55: void SnapWindow(ULONG);
56: BOOL SnapInit(void);
57: void SnapPaint(HPS);
58: void SnapRegion(HPS);
59: void DrawRgn(HPS);
60: void SortRect(PRECTL, PRECTL);
61: void SaveBitmap(void);
62: void SaveBitmap2(HFILE hFile, HBITMAP hbm);
63: void convert(NPBYTE pbuf, USHORT cch, USHORT cch2);
64: HDC CreateDC(PSZ, HDC);
65: void Copy(NPBYTE, NPBYTE, USHORT);
66: int cdecl main(void);
67: BOOL GetMem(PPVOID, ULONG);
68:
69:
70: /* Routines */
71: int cdecl main(void)
72: {
73: QMSG msg;
74: ULONG ctlData;
75:
76: if (!SnapInit())
77: return(FALSE);
78:
79: ctlData = FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER |
80: FCF_SYSMENU | FCF_MENU | FCF_ICON;
81: hwndSnapFrame = WinCreateStdWindow(HWND_DESKTOP,
82: FS_ICON, &ctlData,
83: (PCH)szSnap, (PCH)szSnap,
84: 0L,
85: NULL, 1,
86: (HWND *)&hwndSnap);
87:
88:
89: if (!hwndSnap)
90: return(FALSE);
91:
92: WinSetWindowPos(hwndSnapFrame, 0, 0, 0, 200, 75, SWP_SIZE | SWP_MOVE);
93: WinShowWindow(hwndSnapFrame, TRUE);
94:
95: WinSetFocus(HWND_DESKTOP, hwndSnap);
96: WinQueryWindowRect(HWND_DESKTOP, &rcScreen);
97:
98: if (WinOpenClipbrd(habSnap)) {
99: WinSetClipbrdViewer(habSnap, hwndSnap);
100: WinCloseClipbrd(habSnap);
101: }
102:
103: while (WinGetMsg(habSnap, (PQMSG)&msg, NULL, NULL, NULL)) {
104: WinDispatchMsg(habSnap, (PQMSG)&msg);
105: }
106:
107: WinDestroyPointer(hptrSnap);
108: WinDestroyPointer(hptrHand);
109: WinDestroyPointer(hptrSelect);
110:
111: WinDestroyWindow(hwndSnapFrame);
112: WinDestroyMsgQueue(hmqSnap);
113:
114: WinTerminate(habSnap);
115:
116: return 0;
117: } /* end winmain */
118:
119:
120: HDC CreateDC(lpszDriver, hdcCompat)
121: PSZ lpszDriver;
122: HDC hdcCompat;
123: {
124: struct {
125: ULONG *lpLogAddr;
126: PSZ lpszDriver;
127: } opendc;
128:
129: opendc.lpLogAddr = NULL;
130: opendc.lpszDriver = lpszDriver;
131:
132: return((HDC)DevOpenDC(habSnap, OD_MEMORY, (PSZ)"*", 2L,
133: (PDEVOPENDATA)&opendc, hdcCompat));
134: }
135:
136: BOOL SnapInit(void)
137: {
138: /*
139: * Initialize the HAB
140: */
141: habSnap = WinInitialize(NULL);
142:
143: hmqSnap = WinCreateMsgQueue(NULL, 0);
144:
145: WinLoadString(habSnap, (ULONG)0, IDS_SNAP, sizeof(szSnap), (PCH)szSnap);
146:
147: hptrSnap = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDR_PTR_SNAP);
148: hptrHand = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDR_PTR_HAND);
149: hptrSelect = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDR_PTR_SELECT);
150:
151: if (!WinRegisterClass(habSnap, (PCH)szSnap, SnapWndProc, (ULONG)0, 0))
152: return(FALSE);
153:
154: /*
155: * We assume an empty clipboard when we start.
156: */
157: WinOpenClipbrd(habSnap);
158: WinEmptyClipbrd(habSnap);
159: WinCloseClipbrd(habSnap);
160: } /* end snapinit */
161:
162:
163: MRESULT EXPENTRY SnapWndProc(hwnd, message, mp1, mp2)
164: HWND hwnd;
165: USHORT message;
166: MPARAM mp1;
167: MPARAM mp2;
168: {
169: HWND hwndMenu;
170: HPS hps;
171: RECTL wrcUpdate;
172: POINTL wptTemp;
173:
174: switch (message) {
175: case WM_BUTTON1DOWN:
176: if (fSnapWnd) {
177: WinSetPointer(HWND_DESKTOP, hptrSnap);
178: SnapWindow(LONGFROMMP(mp1));
179: WinSetCapture(HWND_DESKTOP, (HWND)NULL);
180: fSnapWnd = FALSE;
181: } else if (fSnapRgn) {
182: wptTemp.x = SHORT1FROMMP(mp1);
183: wptTemp.y = SHORT2FROMMP(mp1);
184: WinMapWindowPoints(hwndSnap, (HWND)HWND_DESKTOP,
185: (PPOINTL)&wptTemp, 1);
186: wrcRgn.yTop = wrcRgn.yBottom = wptTemp.y;
187: wrcRgn.xRight = wrcRgn.xLeft = wptTemp.x;
188: hpsScr = WinGetScreenPS(HWND_DESKTOP);
189: DrawRgn(hpsScr);
190: WinReleasePS(hpsScr);
191: fSelect = TRUE;
192: break;
193: } else {
194: return(WinDefWindowProc(hwnd, message, mp1, mp2));
195: }
196: break;
197:
198: case WM_MOUSEMOVE:
199: if (fSelect) {
200: hpsScr = WinGetScreenPS(HWND_DESKTOP);
201: DrawRgn(hpsScr);
202: wptTemp.x = LOUSHORT(mp1);
203: wptTemp.y = HIUSHORT(mp1);
204: WinMapWindowPoints(hwndSnap, (HWND)HWND_DESKTOP,
205: (PPOINTL)&wptTemp, 1);
206: wrcRgn.yTop = wptTemp.y;
207: wrcRgn.xRight = wptTemp.x;
208: DrawRgn(hpsScr);
209: WinReleasePS(hpsScr);
210: break;
211: }
212: if (fSnapWnd || fSnapRgn) {
213: break;
214: } else {
215: return(WinDefWindowProc(hwnd, message, mp1, mp2));
216: }
217: break;
218:
219: case WM_BUTTON1UP:
220: if (fSelect) {
221: WinSetCapture(HWND_DESKTOP, (HWND)NULL);
222: hpsScr = WinGetScreenPS(HWND_DESKTOP);
223: DrawRgn(hpsScr);
224: SnapRegion(hpsScr);
225: WinReleasePS(hpsScr);
226: fSnapRgn = FALSE;
227: fSelect = FALSE;
228: }
229: break;
230:
231: case WM_DRAWCLIPBOARD:
232: WinInvalidateRect(hwnd, (PRECTL)NULL, TRUE);
233: break;
234:
235: case WM_PAINT:
236: hps = WinBeginPaint(hwnd, NULL, &wrcUpdate);
237: WinFillRect(hps, &wrcUpdate, SYSCLR_WINDOW);
238: SnapPaint(hps);
239: WinEndPaint(hps);
240: break;
241:
242: case WM_INITMENU:
243: hwndMenu = WinWindowFromID(hwndSnapFrame, FID_MENU);
244: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_REGION, TRUE),
245: MPFROM2SHORT(MIA_CHECKED, wSnapMode == IDM_REGION ? MIA_CHECKED : 0));
246: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_WINDOW, TRUE),
247: MPFROM2SHORT(MIA_CHECKED, wSnapMode == IDM_WINDOW ? MIA_CHECKED : 0));
248: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_NCAREA, TRUE),
249: MPFROM2SHORT(MIA_CHECKED, fNCArea ? MIA_CHECKED : 0));
250: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_HIDE, TRUE),
251: MPFROM2SHORT(MIA_CHECKED, fHide ? MIA_CHECKED : 0));
252: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_NCAREA, TRUE),
253: MPFROM2SHORT(MIA_DISABLED, wSnapMode == IDM_WINDOW ? 0 : MIA_DISABLED));
254: break;
255:
256: case WM_COMMAND:
257: switch ((USHORT)mp1) {
258: case IDM_SAVE:
259: SaveBitmap();
260: break;
261:
262: case IDM_SNAP:
263: WinSetCapture(HWND_DESKTOP, hwnd);
264: if (fHide)
265: WinShowWindow(hwndSnapFrame, FALSE);
266: if (wSnapMode == IDM_WINDOW) {
267: fSnapWnd = TRUE;
268: WinSetPointer(HWND_DESKTOP, hptrHand);
269: } else {
270: fSnapRgn = TRUE;
271: WinSetPointer(HWND_DESKTOP, hptrSelect);
272: }
273: break;
274:
275: case IDM_WINDOW:
276: case IDM_REGION:
277: wSnapMode = SHORT1FROMMP(mp1);
278: break;
279:
280: case IDM_NCAREA:
281: fNCArea = !fNCArea;
282: break;
283:
284: case IDM_HIDE:
285: fHide = !fHide;
286: break;
287:
288: case IDM_ABOUT:
289: WinDlgBox(HWND_DESKTOP, hwnd,
290: (PFNWP)AboutWndProc, NULL, IDD_INFO, (PCH)NULL);
291: break;
292: }
293: break;
294:
295: default:
296: return(WinDefWindowProc(hwnd, message, mp1, mp2));
297: }
298:
299: return(0L);
300:
301: } /* end snapwndproc */
302:
303:
304: void SnapPaint(hps)
305: HPS hps;
306: {
307: HBITMAP hbm;
308: POINTL pt;
309: BITMAPINFOHEADER bminfo;
310: RECTL rc;
311:
312: WinOpenClipbrd(habSnap);
313: WinQueryWindowRect(hwndSnap, &rc);
314:
315: if (hbm = (HBITMAP)WinQueryClipbrdData(habSnap, CF_BITMAP)) {
316: GpiQueryBitmapParameters(hbm, &bminfo);
317: pt.x = 0;
318: pt.y = rc.yTop - bminfo.cy;
319: WinDrawBitmap(hps, hbm, (PRECTL)NULL, (PPOINTL)&pt,
320: 0L, 0L, DBM_NORMAL | DBM_IMAGEATTRS);
321: }
322:
323: WinCloseClipbrd(habSnap);
324:
325: } /* end SnapPaint */
326:
327:
328: void SnapWindow(loc)
329: ULONG loc;
330: {
331: BITMAPINFOHEADER bminfo;
332: POINTL pt;
333: HWND hwnd;
334: HWND hwndT;
335: RECTL rc, rcTmp;
336: HPS hpsWnd, hpsMem;
337: HDC hdc;
338: HBITMAP hbm, hbmOld;
339: int cx, cy;
340: POINTL rgpt[3];
341: SIZEL size;
342:
343: pt.y = HIUSHORT(loc);
344: pt.x = LOUSHORT(loc);
345:
346: WinMapWindowPoints(hwndSnap, HWND_DESKTOP, (PPOINTL)&pt, 1);
347: if ((hwnd = WinWindowFromPoint(HWND_DESKTOP, (PPOINTL)&pt, FALSE, FALSE)) == NULL)
348: return;
349: /* get size of target window. clip to screen. */
350: if (fNCArea) /* snap only the client area if it exists */
351: if ((hwndT = WinWindowFromID(hwnd, FID_CLIENT)) != NULL)
352: hwnd = hwndT;
353: WinQueryWindowRect(hwnd, &rcTmp);
354: /* bound window rectangle to screen. */
355: WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&rcTmp.xLeft, 2);
356: WinIntersectRect(habSnap, &rc, &rcTmp, &rcScreen);
357: WinMapWindowPoints(HWND_DESKTOP, hwnd, (PPOINTL)&rc.xLeft, 2);
358: cx = (USHORT)(rc.xRight - rc.xLeft);
359: cy = (USHORT)(rc.yTop - rc.yBottom);
360:
361: /* get window PS */
362: hpsWnd = WinGetPS(hwnd);
363:
364: /* Create a memory DC */
365: hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);
366:
367: /* create a memory PS */
368: size.cx = cx;
369: size.cy = cy;
370: hpsMem = GpiCreatePS( habSnap, hdc, &size,
371: PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC );
372:
373: /* Create a bitmap */
374: bminfo.cbFix = sizeof(BITMAPINFOHEADER);
375: bminfo.cx = cx;
376: bminfo.cy = cy;
377: bminfo.cPlanes = 1;
378: bminfo.cBitCount = 4;
379: if (!(hbm = GpiCreateBitmap(hpsMem, (PBITMAPINFOHEADER2)&bminfo, 0L, 0, 0)))
380: WinMessageBox((HWND)HWND_DESKTOP, hwndSnap,
381: (PCH)"Insufficient memory to create the bitmap.", (PCH)NULL,
382: 0, MB_OK);
383: else {
384: /* put the bitmap into the memory PS */
385: hbmOld = GpiSetBitmap(hpsMem, hbm);
386:
387: /* copy the window to the memory PS */
388: rgpt[0].x = 0;
389: rgpt[0].y = 0;
390: rgpt[1].x = cx;
391: rgpt[1].y = cy;
392: rgpt[2].x = rc.xLeft;
393: rgpt[2].y = rc.yBottom;
394: GpiBitBlt(hpsMem, hpsWnd, 3L, (PPOINTL)&rgpt[0], ROP_SRCCOPY, 0L);
395:
396: /* free the bitmap */
397: GpiSetBitmap(hpsMem, hbmOld);
398:
399: /* store the bitmap */
400: WinOpenClipbrd(habSnap);
401: WinEmptyClipbrd(habSnap);
402: WinSetClipbrdData(habSnap, (ULONG)hbm, CF_BITMAP, CFI_HANDLE);
403: WinCloseClipbrd(habSnap);
404: }
405:
406: /* destroy the memory DC */
407: GpiAssociate( hpsMem, NULL );
408: DevCloseDC(hdc);
409:
410: /* get rid of the PSs */
411: GpiDestroyPS(hpsMem);
412: WinReleasePS(hpsWnd);
413:
414: if (fHide)
415: WinShowWindow(hwndSnapFrame, TRUE);
416:
417: } /* end snapwindow */
418:
419:
420: void SnapRegion(hpsScr)
421: HPS hpsScr;
422: {
423: HDC hdc;
424: HBITMAP hbm, hbmOld;
425: BITMAPINFOHEADER bminfo;
426: RECTL rcTmp;
427: int cx, cy;
428: POINTL rgpt[3];
429: HPS hpsMem;
430: SIZEL size;
431:
432: SortRect((PRECTL)&wrcRgn, (PRECTL)&rcTmp);
433:
434: cx = (USHORT)(rcTmp.xRight - rcTmp.xLeft);
435: cy = (USHORT)(rcTmp.yTop - rcTmp.yBottom);
436:
437: /* Create a memory DC */
438: hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);
439:
440: /* create a memory PS */
441: size.cx = cx;
442: size.cy = cy;
443: hpsMem = GpiCreatePS( habSnap, hdc, &size,
444: PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC );
445:
446: /* Create a bitmap */
447: bminfo.cbFix = sizeof(BITMAPINFOHEADER);
448: bminfo.cx = cx;
449: bminfo.cy = cy;
450: bminfo.cPlanes = 1;
451: bminfo.cBitCount = 4;
452: if (!(hbm = GpiCreateBitmap(hpsMem, (PBITMAPINFOHEADER2)&bminfo, 0L, 0, 0))) {
453: WinMessageBox((HWND)HWND_DESKTOP, hwndSnap,
454: (PCH)"Insufficient memory to create the bitmap.", (PCH)NULL,
455: 0, MB_OK);
456: } else {
457: /* put the bitmap into the memory PS */
458: hbmOld = GpiSetBitmap(hpsMem, hbm);
459:
460: /* copy the window to the memory PS */
461: rgpt[0].x = 0;
462: rgpt[0].y = 0;
463: rgpt[1].x = cx;
464: rgpt[1].y = cy;
465: rgpt[2].x = rcTmp.xLeft;
466: rgpt[2].y = rcTmp.yBottom;
467: GpiBitBlt(hpsMem, hpsScr, 3L, (PPOINTL)&rgpt[0], ROP_SRCCOPY, 0L);
468:
469: /* free the bitmap */
470: GpiSetBitmap(hpsMem, hbmOld);
471:
472: /* store the bitmap */
473: WinOpenClipbrd(habSnap);
474: WinEmptyClipbrd(habSnap);
475: WinSetClipbrdData(habSnap, (ULONG)hbm, CF_BITMAP, CFI_HANDLE);
476: WinCloseClipbrd(habSnap);
477: }
478: /* destroy the memory DC */
479: GpiAssociate( hpsMem, NULL );
480: DevCloseDC(hdc);
481:
482: /* get rid of the PS */
483: GpiDestroyPS(hpsMem);
484:
485: if (fHide)
486: WinShowWindow(hwndSnapFrame, TRUE);
487:
488: } /* end snapregion */
489:
490: void DrawRgn(hps)
491: HPS hps;
492: {
493: RECTL rc;
494:
495: SortRect((PRECTL)&wrcRgn, (PRECTL)&rc);
496:
497: WinDrawBorder(hps, (PRECTL)&rc, 1, 1, SYSCLR_WINDOW, SYSCLR_WINDOW,
498: DB_DESTINVERT | DB_STANDARD);
499: }
500:
501: void SortRect(pwrcIn, pwrcSorted)
502: PRECTL pwrcIn, pwrcSorted;
503: {
504: if (pwrcIn->yTop > pwrcIn->yBottom) {
505: pwrcSorted->yTop = pwrcIn->yTop;
506: pwrcSorted->yBottom = pwrcIn->yBottom;
507: } else {
508: pwrcSorted->yTop = pwrcIn->yBottom;
509: pwrcSorted->yBottom = pwrcIn->yTop;
510: }
511: if (pwrcIn->xRight > pwrcIn-> xLeft) {
512: pwrcSorted->xRight = pwrcIn->xRight;
513: pwrcSorted->xLeft = pwrcIn->xLeft;
514: } else {
515: pwrcSorted->xRight = pwrcIn->xLeft;
516: pwrcSorted->xLeft = pwrcIn->xRight;
517: }
518: }
519:
520: MRESULT EXPENTRY AboutWndProc(hwnd, message, mp1, mp2)
521: HWND hwnd;
522: USHORT message;
523: MPARAM mp1;
524: MPARAM mp2;
525: {
526: switch (message) {
527: case WM_COMMAND:
528: WinDismissDlg(hwnd, TRUE);
529: break;
530: default:
531: return(WinDefDlgProc(hwnd, message, mp1, mp2));
532: break;
533: }
534: return 0L;
535:
536: } /* end aboutwndproc */
537:
538: void SaveBitmap(void)
539: {
540: HFILE hFile;
541: HBITMAP hbm;
542: HPOINTER hptr, hptrWait;
543:
544: WinOpenClipbrd(habSnap);
545: if ((hbm = (HBITMAP)WinQueryClipbrdData(habSnap, CF_BITMAP)) == NULL) {
546: WinCloseClipbrd(habSnap);
547: return;
548: }
549:
550: if (hFile = OpenSaveFile(hwndSnap)) {
551: hptr = WinQueryPointer(HWND_DESKTOP);
552: hptrWait = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, TRUE);
553: WinSetPointer(HWND_DESKTOP, hptrWait);
554: SaveBitmap2(hFile, hbm);
555: WinSetPointer(HWND_DESKTOP, hptr);
556: WinDestroyPointer(hptrWait);
557: } else
558: WinAlarm(HWND_DESKTOP, WA_ERROR);
559:
560: WinCloseClipbrd(habSnap);
561: }
562:
563: /***************************************************************************\
564: * hFile is a handle to an open file. This is closed on exit.
565: \***************************************************************************/
566: void SaveBitmap2(hFile, hbm)
567: HFILE hFile;
568: HBITMAP hbm;
569: {
570: /*
571: * Currently, this puts stuff out in Win386 paint format.
572: */
573: typedef struct _WIN386PAINT {
574: USHORT key1;
575: USHORT key2;
576: USHORT dxFile;
577: USHORT dyFile;
578: USHORT ScrAspectX;
579: USHORT ScrAspectY;
580: USHORT PrnAspectX;
581: USHORT PrnAspectY;
582: USHORT dxPrinter;
583: USHORT dyPrinter;
584: USHORT AspCorX;
585: USHORT AspCorY;
586: USHORT wCheck;
587: USHORT res1;
588: USHORT res2;
589: USHORT res3;
590: } FHDR;
591: FHDR hdr;
592: USHORT i;
593: ULONG cBytesWritten;
594: USHORT *pIndex;
595: USHORT *pIndexT;
596: NPBYTE pScanLine, pBits, pBitsT;
597: USHORT *phdr;
598: USHORT cbIndexTable, cbScanLine, cbScanLineExp, cbBmpLine;
599: HDC hdc;
600: HBITMAP hbmOld;
601: BITMAPINFOHEADER bminfo;
602: BITMAPINFO2 bminfo2;
603: HPS hpsMem;
604: SIZEL size;
605:
606: /*
607: * write header
608: */
609: GpiQueryBitmapParameters(hbm, &bminfo);
610: hdr.key1 = 0x694C;
611: hdr.key2 = 0x536E;
612: hdr.dxFile = bminfo.cx;
613: hdr.dyFile = bminfo.cy;
614: hdr.ScrAspectX = 26;
615: hdr.ScrAspectY = 30;
616: hdr.PrnAspectX = 0x12c;
617: hdr.PrnAspectY = 0x12c;
618: hdr.dxPrinter = 0x8df;
619: hdr.dyPrinter = 0xce1;
620: hdr.AspCorX = 0;
621: hdr.AspCorY = 0;
622:
623: phdr = (USHORT *)&hdr;
624: hdr.wCheck = 0;
625: for (i=0; i < 12; i++)
626: hdr.wCheck ^= *phdr++;
627:
628: hdr.res1 = 0;
629: hdr.res2 = 0;
630: hdr.res3 = 0;
631:
632: DosWrite(hFile, (PSZ)&hdr, sizeof(FHDR), &cBytesWritten);
633:
634: /* calculate sizes */
635: cbIndexTable = sizeof(unsigned int) * bminfo.cy;
636: cbScanLine = (bminfo.cx + 7) >> 3;
637: cbScanLineExp = cbScanLine + ((cbScanLine + 0xff) >> 8);
638: cbBmpLine = (cbScanLine + 3) & 0xfffc;
639:
640: /*
641: * Write index table - (no compression)
642: */
643: /* allocate pIndex */
644: if (GetMem((PPVOID)&pIndex, cbIndexTable))
645: goto Exit;
646:
647: pIndexT = pIndex;
648: for (i=0; i < bminfo.cy; i++)
649: *pIndexT++ = cbScanLineExp;
650:
651: DosWrite(hFile, (PSZ)pIndex, cbIndexTable, &cBytesWritten);
652:
653: /* free pIndex */
654: DosFreeMem((PVOID)pIndex);
655:
656: /*
657: * Write out each scan line
658: */
659: /* allocate pScanLine */
660: if (GetMem((PPVOID)&pScanLine, cbScanLineExp))
661: goto Exit;
662: /* allocate pBits */
663: if (GetMem((PPVOID)&pBits, cbBmpLine*bminfo.cy))
664: goto Exit;
665:
666: /* specify the bitmap format we want */
667: bminfo.cPlanes = 1;
668: bminfo.cBitCount = 1;
669:
670: /* Create memory DC */
671: hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);
672:
673: /* create a memory PS */
674: size.cx = bminfo.cx;
675: size.cy = bminfo.cy;
676: hpsMem = GpiCreatePS( habSnap, hdc, &size,
677: PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC);
678:
679: hbmOld = GpiSetBitmap(hpsMem, hbm);
680: GpiQueryBitmapBits(hpsMem, (LONG)0, (LONG)bminfo.cy, (PBYTE)pBits, &bminfo2);
681:
682: pBitsT = pBits + cbBmpLine * bminfo.cy;
683: for (i = 0; i < bminfo.cy; i++) {
684: pBitsT -= cbBmpLine;
685: Copy(pBitsT, pScanLine, cbScanLine);
686: convert(pScanLine, cbScanLine, cbScanLineExp);
687: DosWrite(hFile, (PSZ)pScanLine, cbScanLineExp, &cBytesWritten);
688: }
689:
690: /* free pBits and pScanLine */
691: DosFreeMem((PVOID)pBits);
692: DosFreeMem((PVOID)pScanLine);
693:
694: GpiAssociate(hpsMem, NULL);
695: DevCloseDC(hdc);
696: GpiDestroyPS(hpsMem);
697:
698: Exit:
699: DosClose(hFile);
700: }
701:
702:
703: /***************************************************************************\
704: * Insert apropriate repeat count bytes into the scanline given.
705: \***************************************************************************/
706: void convert(pbuf, cch, cch2)
707: NPBYTE pbuf;
708: USHORT cch; /* exact length of buffer BEFORE count bytes have been added */
709: USHORT cch2; /* AFTER conversion size */
710: {
711: NPBYTE pWrite, pRead;
712:
713: pWrite = pbuf + cch2 - 1;
714: pRead = pbuf + cch - 1;
715: while (pWrite > pbuf) {
716: *pWrite-- = *pRead--;
717: if (((pWrite - pbuf) & 0x00ff) == 0) {
718: *pWrite-- = (BYTE)((pbuf + cch2 - pWrite) < 0x100 ?
719: (pbuf + cch2 - pWrite) : 0xff);
720: }
721: }
722: }
723:
724: void Copy(src, dest, cb)
725: NPBYTE src;
726: NPBYTE dest;
727: USHORT cb;
728: {
729: USHORT i;
730:
731: for (i = 0; i < cb; i++)
732: *dest++ = *src++;
733: }
734:
735: HFILE OpenSaveFile(hwnd)
736: HWND hwnd;
737: {
738: HFILE hFile= 0L;
739: DLGP dlgp;
740: char fName[32];
741: ULONG action;
742:
743: dlgp.cch = 32;
744: dlgp.psz = fName;
745: if (WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)SaveFileDlgProc, NULL,
746: IDD_SAVEFILE, (PVOID)&dlgp) != 0) {
747: DosOpen(fName, &hFile, &action, 0L, 0, 0x0011, 0x0011, 0L);
748: }
749: return(hFile);
750: }
751:
752: MRESULT EXPENTRY SaveFileDlgProc(hwnd, msg, mp1, mp2)
753: HWND hwnd;
754: USHORT msg;
755: MPARAM mp1;
756: MPARAM mp2;
757: {
758: DLGP *pdlgp;
759: SHORT cch;
760:
761: switch (msg) {
762: case WM_INITDLG:
763: /* squirl away the dlgp pointer in a reentrant fashion */
764: WinSetWindowULong(hwnd, QWL_USER, (ULONG)mp2);
765: break;
766:
767: case WM_CHAR:
768: if ( ((USHORT)mp1 & KC_VIRTUALKEY) &&
769: ((SHORT2FROMMP(mp2) == VK_NEWLINE) ||
770: (SHORT2FROMMP(mp2) == VK_ENTER)) ) {
771: if (pdlgp = (DLGP *)WinQueryWindowULong(hwnd, QWL_USER)) {
772: cch = WinQueryWindowText(WinWindowFromID(hwnd, ID_FILEENTRY),
773: pdlgp->cch, pdlgp->psz);
774: WinDismissDlg(hwnd, cch);
775: } else {
776: WinDismissDlg(hwnd, 0);
777: }
778: return(0);
779: }
780: break;
781: }
782:
783: return(WinDefDlgProc(hwnd, msg, mp1, mp2));
784: }
785:
786: BOOL
787: GetMem (ppv, cb)
788: PPVOID ppv;
789: ULONG cb;
790: {
791: BOOL f;
792:
793: f = DosAllocMem(ppv, cb, fPERM|PAG_COMMIT);
794: if (f) {
795: WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
796: "Sorry, Not enough memory", NULL, 0, MB_OK);
797: *ppv = NULL;
798: return TRUE;
799: }
800: return FALSE;
801: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.