|
|
1.1 ! root 1: /* ! 2: * CLIPFILE.C -- File handling for ClipView ! 3: * Created by Microsoft, IBM Corporation, 1990 ! 4: * ! 5: * This file contains one routine: SaveClipboard(), which uses ! 6: * the OPENDLG library to put up a File...Save... dialog box. ! 7: * ! 8: * After getting a file name, it tries to save the current rendered format. ! 9: */ ! 10: ! 11: ! 12: ! 13: #define INCL_BITMAPFILEFORMAT ! 14: #define INCL_DOSFILEMGR ! 15: #define INCL_DOSMEMMGR ! 16: #define INCL_GPIBITMAPS ! 17: #define INCL_GPIMETAFILES ! 18: #define INCL_WINCLIPBOARD ! 19: #define INCL_WINERRORS ! 20: #include <os2.h> ! 21: ! 22: #include "..\opendlg\opendlg.h" ! 23: ! 24: #include <string.h> ! 25: #include "clipview.h" ! 26: ! 27: ! 28: /* ! 29: * Globals ! 30: */ ! 31: extern HAB vhab; /* Anchor block */ ! 32: extern HWND vhwndClient; /* Main client area */ ! 33: /* ! 34: Macros ! 35: */ ! 36: #define CHK(f) fSuccess = fSuccess && (f) ! 37: #define LOADSTRING(id, sz) WinLoadString(vhab, NULL, id, MAXLEN, sz) ! 38: ! 39: /* ! 40: Private function prototypes ! 41: */ ! 42: BOOL SaveText(HFILE hf, PSZ pszText); ! 43: ! 44: BOOL SaveClipboard(HWND hwnd, USHORT usFormat) { ! 45: /* ! 46: Save the clipboard contents in several formats. ! 47: The "Save BITMAP" code is similar to that in the LINEFRAC sample. ! 48: */ ! 49: BOOL fSuccess = TRUE; /* Did we succeed in saving? */ ! 50: ULONG hItem; /* Handle from QueryClipbrdData */ ! 51: /* ! 52: Variables needed for File...Save... dialog. ! 53: */ ! 54: ! 55: ! 56: DLF dlf; /* Dialog file */ ! 57: HFILE hf; /* Handle to output file */ ! 58: UCHAR szExt[8]; /* Default extension */ ! 59: UCHAR szInst[MAXLEN]; /* Instructions */ ! 60: UCHAR szMessage[MAXLEN]; /* Various messages */ ! 61: UCHAR szTitle[MAXTITLELEN];/* Application title */ ! 62: /* ! 63: Variables needed for saving Metafiles ! 64: */ ! 65: HMF hmfCopy; /* Clipboard metafile copy */ ! 66: /* ! 67: Variables needed for saving BITMAPs ! 68: */ ! 69: BITMAPINFOHEADER bmp; /* Header to be queried */ ! 70: HDC hdcMemory; /* Memory DC for the BITMAP */ ! 71: HPS hpsMemory; /* ...and it's associated PS */ ! 72: PBITMAPFILEHEADER pbfh; /* bmp + color table */ ! 73: POINTL ptlOrigin; /* Bitmap origin */ ! 74: PVOID pBuffer; /* Selector to actual BITMAP */ ! 75: SIZEL sizl; /* Used in PS creation */ ! 76: ULONG cbBuffer; /* No. of bytes in buffer */ ! 77: ULONG cbHeader; /* No. of bytes in header */ ! 78: ULONG cbWritten; /* No. of bytes actually written */ ! 79: ! 80: ULONG CntrlZ = 26; /* Signals end of text file */ ! 81: ! 82: ! 83: /* ! 84: Open the clipboard ! 85: */ ! 86: if (!WinOpenClipbrd(vhab)) ! 87: return FALSE; ! 88: /* ! 89: Get the clipboard data ! 90: */ ! 91: if (hItem = WinQueryClipbrdData(vhab, usFormat)) { ! 92: /* ! 93: Put up the Save... file dialog with the appropriate extensions ! 94: */ ! 95: switch (usFormat) { ! 96: case CF_TEXT: ! 97: case CF_DSPTEXT: strcpy(szExt, "\\*.TXT"); break; ! 98: ! 99: case CF_BITMAP: ! 100: case CF_DSPBITMAP: strcpy(szExt, "\\*.BMP"); break; ! 101: ! 102: case CF_METAFILE: ! 103: case CF_DSPMETAFILE: strcpy(szExt, "\\*.MET"); break; ! 104: ! 105: default: strcpy(szExt, "\\*.*"); break; ! 106: } ! 107: /* ! 108: Put the string "Saving Format: <format>" in the Save dialog box ! 109: */ ! 110: GetFormatName(usFormat, szMessage); ! 111: LOADSTRING(IDS_SAVETITLE, szTitle); ! 112: strcat(szTitle, szMessage); ! 113: ! 114: LOADSTRING(IDS_APPNAME, szMessage); ! 115: LOADSTRING(IDS_INST, szInst); ! 116: ! 117: ! 118: SetupDLF(&dlf, DLG_SAVEDLG, &hf, ! 119: (PSZ) szExt, (PSZ) szMessage, (PSZ) szTitle, (PSZ) szInst); ! 120: ! 121: dlf.szFileName[0] = dlf.szOpenFile[0] = '\0'; ! 122: /* ! 123: Put up a Save file dialog, and respond appropriately to ! 124: the return status. ! 125: */ ! 126: switch (DlgFile(hwnd, &dlf)) { ! 127: case TDF_ERRMEM: ! 128: case TDF_INVALID: ! 129: case TDF_NOSAVE: ! 130: fSuccess = FALSE; ! 131: ! 132: /* fall through... */ ! 133: default: ! 134: break; ! 135: } ! 136: ! 137: if (fSuccess) { ! 138: switch (usFormat) { ! 139: ! 140: case CF_TEXT: ! 141: case CF_DSPTEXT: ! 142: CHK(SaveText(hf, (PSZ) hItem)) ; ! 143: CHK(!DosWrite(hf, "\32", (LONG)sizeof(CHAR), &cbWritten)); ! 144: DosClose(hf); ! 145: break; ! 146: ! 147: case CF_BITMAP: ! 148: case CF_DSPBITMAP: ! 149: /* ! 150: Initialize the Memory DC and its PS ! 151: */ ! 152: sizl.cx = sizl.cy = 0L; ! 153: hdcMemory = DevOpenDC(vhab, OD_MEMORY, "*", 0L, NULL, NULL); ! 154: hpsMemory = GpiCreatePS(vhab, hdcMemory, &sizl, ! 155: GPIA_ASSOC | GPIT_MICRO | PU_PELS); ! 156: /* ! 157: Draw the BITMAP into the Memory DC ! 158: */ ! 159: CHK(GpiSetBitmap(hpsMemory, (HBITMAP) hItem) != HBM_ERROR); ! 160: ptlOrigin.x = ptlOrigin.y = 0L; ! 161: CHK(WinDrawBitmap(hpsMemory, (HBITMAP) hItem, NULL, ! 162: &ptlOrigin, CLR_BLACK, CLR_BACKGROUND, DBM_NORMAL)); ! 163: /* ! 164: Get information about the BITMAP ! 165: */ ! 166: CHK(GpiQueryBitmapParameters((HBITMAP) hItem, ! 167: (PBITMAPINFOHEADER) &bmp) == GPI_OK); ! 168: /* ! 169: Compute the size of the buffer, and allocate ! 170: Make sure that > 64K BITMAPs are handled ! 171: (this code is from LFFILE.C) ! 172: */ ! 173: cbBuffer = ( ((((ULONG)bmp.cBitCount*(ULONG) bmp.cx)+31L)/32L) ! 174: * 4L * (ULONG) bmp.cy * (ULONG) bmp.cPlanes ); ! 175: ! 176: CHK(!DosAllocMem (&pBuffer, cbBuffer, PAG_COMMIT | PAG_WRITE )) ; ! 177: ! 178: /* ! 179: Compute the size of the BITMAPFILEHEADER + color table... ! 180: ...then allocate it. ! 181: */ ! 182: cbHeader = (USHORT) (sizeof(BITMAPFILEHEADER) ! 183: + (sizeof(RGB) << bmp.cBitCount)); ! 184: ! 185: ! 186: CHK(!DosAllocMem(&pbfh, cbHeader, PAG_COMMIT | PAG_WRITE)); ! 187: ! 188: /* ! 189: Copy the BITMAP information from the BITMAPINFOHEADER ! 190: */ ! 191: pbfh->bmp.cbFix = 12; ! 192: pbfh->bmp.cx = bmp.cx; ! 193: pbfh->bmp.cy = bmp.cy; ! 194: pbfh->bmp.cPlanes = bmp.cPlanes; ! 195: pbfh->bmp.cBitCount = bmp.cBitCount; ! 196: ! 197: ! 198: /* ! 199: Get the actual BITMAP bits ! 200: ! 201: */ ! 202: ! 203: ! 204: CHK(GpiQueryBitmapBits(hpsMemory, 0L, (LONG) bmp.cy, ! 205: (PBYTE) pBuffer, (PBITMAPINFO2) &(pbfh->bmp)) ! 206: != GPI_ALTERROR); ! 207: ! 208: ! 209: /* ! 210: Set up the file header ! 211: */ ! 212: pbfh->usType = BFT_BMAP; ! 213: pbfh->cbSize = cbHeader + cbBuffer; ! 214: pbfh->xHotspot = bmp.cx / 2; /* Anywhere will do */ ! 215: pbfh->yHotspot = bmp.cy / 2; ! 216: pbfh->offBits = cbHeader; ! 217: /* ! 218: Blast the BITMAP to a file... ! 219: */ ! 220: /* ! 221: ...first, the header... ! 222: */ ! 223: ! 224: CHK(!DosWrite(hf, pbfh, cbHeader, &cbWritten)); ! 225: /* ! 226: ...then, the possibly large BITMAP itself ! 227: */ ! 228: ! 229: ! 230: CHK(!DosWrite(hf, pBuffer, cbBuffer, &cbWritten)) ; ! 231: ! 232: ! 233: ! 234: /* ! 235: Clean up ! 236: ! 237: Error codes are not checked here because the file has ! 238: already been saved. ! 239: */ ! 240: DosClose(hf); ! 241: DosFreeMem ( pbfh ) ; ! 242: DosFreeMem ( pBuffer ) ; ! 243: GpiSetBitmap(hpsMemory, NULL); ! 244: GpiDestroyPS(hpsMemory); ! 245: DevCloseDC(hdcMemory); ! 246: break; ! 247: ! 248: ! 249: case CF_METAFILE: ! 250: case CF_DSPMETAFILE: ! 251: /* ! 252: Save metafile ! 253: ! 254: We close and delete the file, because GpiSaveMetaFile() ! 255: only allows the user to create a new file. ! 256: ! 257: We copy the metafile because GpiSaveMetafile() ! 258: removes the data from the application's memory. ! 259: */ ! 260: DosClose(hf); ! 261: CHK(!DosDelete( dlf.szFileName )); ! 262: CHK((hmfCopy = GpiCopyMetaFile((HMF) hItem)) != GPI_ERROR); ! 263: CHK(GpiSaveMetaFile(hmfCopy, dlf.szFileName) != GPI_ERROR); ! 264: break; ! 265: default: ! 266: /* ! 267: It may be reasonable to add support for other formats ! 268: here, by saving a bitmap of the current window contents. ! 269: ! 270: But for now, close the file and return an error message. ! 271: */ ! 272: DosClose(hf); ! 273: fSuccess = FALSE; ! 274: break; ! 275: } ! 276: } ! 277: } else ! 278: fSuccess = FALSE; /* Couldn't query the clipboard format! */ ! 279: /* ! 280: Clean up ! 281: */ ! 282: WinCloseClipbrd(vhab); ! 283: return fSuccess; ! 284: } ! 285: ! 286: BOOL SaveText(HFILE hf, PSZ pszText) { ! 287: /* ! 288: Save text format ! 289: ! 290: Count the number of characters, then write them. ! 291: */ ! 292: PSZ pszCounter; /* Temporary to count chars in sel */ ! 293: USHORT ulcch = 0; /* The number of characters */ ! 294: ULONG cbWritten; /* No. of bytes actually written */ ! 295: ! 296: pszCounter = pszText; ! 297: while (*pszCounter++) ulcch++; ! 298: ! 299: return(!DosWrite(hf, pszText, ulcch, &cbWritten)); ! 300: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.