|
|
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.