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