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