|
|
Microsoft OS/2 SDK 2.0 05-30-1990
/*
* CLIPFILE.C -- File handling for ClipView
* Created by Microsoft, IBM Corporation, 1990
*
* This file contains one routine: SaveClipboard(), which uses
* the OPENDLG library to put up a File...Save... dialog box.
*
* After getting a file name, it tries to save the current rendered format.
*/
#define INCL_BITMAPFILEFORMAT
#define INCL_DOSFILEMGR
#define INCL_DOSMEMMGR
#define INCL_GPIBITMAPS
#define INCL_GPIMETAFILES
#define INCL_WINCLIPBOARD
#define INCL_WINERRORS
#include <os2.h>
#include "..\opendlg\opendlg.h"
#include <string.h>
#include "clipview.h"
/*
* Globals
*/
extern HAB vhab; /* Anchor block */
extern HWND vhwndClient; /* Main client area */
/*
Macros
*/
#define CHK(f) fSuccess = fSuccess && (f)
#define LOADSTRING(id, sz) WinLoadString(vhab, NULL, id, MAXLEN, sz)
/*
Private function prototypes
*/
BOOL SaveText(HFILE hf, PSZ pszText);
BOOL SaveClipboard(HWND hwnd, USHORT usFormat) {
/*
Save the clipboard contents in several formats.
The "Save BITMAP" code is similar to that in the LINEFRAC sample.
*/
BOOL fSuccess = TRUE; /* Did we succeed in saving? */
ULONG hItem; /* Handle from QueryClipbrdData */
/*
Variables needed for File...Save... dialog.
*/
DLF dlf; /* Dialog file */
HFILE hf; /* Handle to output file */
UCHAR szExt[8]; /* Default extension */
UCHAR szInst[MAXLEN]; /* Instructions */
UCHAR szMessage[MAXLEN]; /* Various messages */
UCHAR szTitle[MAXTITLELEN];/* Application title */
/*
Variables needed for saving Metafiles
*/
HMF hmfCopy; /* Clipboard metafile copy */
/*
Variables needed for saving BITMAPs
*/
BITMAPINFOHEADER bmp; /* Header to be queried */
HDC hdcMemory; /* Memory DC for the BITMAP */
HPS hpsMemory; /* ...and it's associated PS */
PBITMAPFILEHEADER pbfh; /* bmp + color table */
POINTL ptlOrigin; /* Bitmap origin */
PVOID pBuffer; /* Selector to actual BITMAP */
SIZEL sizl; /* Used in PS creation */
ULONG cbBuffer; /* No. of bytes in buffer */
ULONG cbHeader; /* No. of bytes in header */
ULONG cbWritten; /* No. of bytes actually written */
ULONG CntrlZ = 26; /* Signals end of text file */
/*
Open the clipboard
*/
if (!WinOpenClipbrd(vhab))
return FALSE;
/*
Get the clipboard data
*/
if (hItem = WinQueryClipbrdData(vhab, usFormat)) {
/*
Put up the Save... file dialog with the appropriate extensions
*/
switch (usFormat) {
case CF_TEXT:
case CF_DSPTEXT: strcpy(szExt, "\\*.TXT"); break;
case CF_BITMAP:
case CF_DSPBITMAP: strcpy(szExt, "\\*.BMP"); break;
case CF_METAFILE:
case CF_DSPMETAFILE: strcpy(szExt, "\\*.MET"); break;
default: strcpy(szExt, "\\*.*"); break;
}
/*
Put the string "Saving Format: <format>" in the Save dialog box
*/
GetFormatName(usFormat, szMessage);
LOADSTRING(IDS_SAVETITLE, szTitle);
strcat(szTitle, szMessage);
LOADSTRING(IDS_APPNAME, szMessage);
LOADSTRING(IDS_INST, szInst);
SetupDLF(&dlf, DLG_SAVEDLG, &hf,
(PSZ) szExt, (PSZ) szMessage, (PSZ) szTitle, (PSZ) szInst);
dlf.szFileName[0] = dlf.szOpenFile[0] = '\0';
/*
Put up a Save file dialog, and respond appropriately to
the return status.
*/
switch (DlgFile(hwnd, &dlf)) {
case TDF_ERRMEM:
case TDF_INVALID:
case TDF_NOSAVE:
fSuccess = FALSE;
/* fall through... */
default:
break;
}
if (fSuccess) {
switch (usFormat) {
case CF_TEXT:
case CF_DSPTEXT:
CHK(SaveText(hf, (PSZ) hItem)) ;
CHK(!DosWrite(hf, "\32", (LONG)sizeof(CHAR), &cbWritten));
DosClose(hf);
break;
case CF_BITMAP:
case CF_DSPBITMAP:
/*
Initialize the Memory DC and its PS
*/
sizl.cx = sizl.cy = 0L;
hdcMemory = DevOpenDC(vhab, OD_MEMORY, "*", 0L, NULL, NULL);
hpsMemory = GpiCreatePS(vhab, hdcMemory, &sizl,
GPIA_ASSOC | GPIT_MICRO | PU_PELS);
/*
Draw the BITMAP into the Memory DC
*/
CHK(GpiSetBitmap(hpsMemory, (HBITMAP) hItem) != HBM_ERROR);
ptlOrigin.x = ptlOrigin.y = 0L;
CHK(WinDrawBitmap(hpsMemory, (HBITMAP) hItem, NULL,
&ptlOrigin, CLR_BLACK, CLR_BACKGROUND, DBM_NORMAL));
/*
Get information about the BITMAP
*/
CHK(GpiQueryBitmapParameters((HBITMAP) hItem,
(PBITMAPINFOHEADER) &bmp) == GPI_OK);
/*
Compute the size of the buffer, and allocate
Make sure that > 64K BITMAPs are handled
(this code is from LFFILE.C)
*/
cbBuffer = ( ((((ULONG)bmp.cBitCount*(ULONG) bmp.cx)+31L)/32L)
* 4L * (ULONG) bmp.cy * (ULONG) bmp.cPlanes );
CHK(!DosAllocMem (&pBuffer, cbBuffer, PAG_COMMIT | PAG_WRITE )) ;
/*
Compute the size of the BITMAPFILEHEADER + color table...
...then allocate it.
*/
cbHeader = (USHORT) (sizeof(BITMAPFILEHEADER)
+ (sizeof(RGB) << bmp.cBitCount));
CHK(!DosAllocMem(&pbfh, cbHeader, PAG_COMMIT | PAG_WRITE));
/*
Copy the BITMAP information from the BITMAPINFOHEADER
*/
pbfh->bmp.cbFix = 12;
pbfh->bmp.cx = bmp.cx;
pbfh->bmp.cy = bmp.cy;
pbfh->bmp.cPlanes = bmp.cPlanes;
pbfh->bmp.cBitCount = bmp.cBitCount;
/*
Get the actual BITMAP bits
*/
CHK(GpiQueryBitmapBits(hpsMemory, 0L, (LONG) bmp.cy,
(PBYTE) pBuffer, (PBITMAPINFO2) &(pbfh->bmp))
!= GPI_ALTERROR);
/*
Set up the file header
*/
pbfh->usType = BFT_BMAP;
pbfh->cbSize = cbHeader + cbBuffer;
pbfh->xHotspot = bmp.cx / 2; /* Anywhere will do */
pbfh->yHotspot = bmp.cy / 2;
pbfh->offBits = cbHeader;
/*
Blast the BITMAP to a file...
*/
/*
...first, the header...
*/
CHK(!DosWrite(hf, pbfh, cbHeader, &cbWritten));
/*
...then, the possibly large BITMAP itself
*/
CHK(!DosWrite(hf, pBuffer, cbBuffer, &cbWritten)) ;
/*
Clean up
Error codes are not checked here because the file has
already been saved.
*/
DosClose(hf);
DosFreeMem ( pbfh ) ;
DosFreeMem ( pBuffer ) ;
GpiSetBitmap(hpsMemory, NULL);
GpiDestroyPS(hpsMemory);
DevCloseDC(hdcMemory);
break;
case CF_METAFILE:
case CF_DSPMETAFILE:
/*
Save metafile
We close and delete the file, because GpiSaveMetaFile()
only allows the user to create a new file.
We copy the metafile because GpiSaveMetafile()
removes the data from the application's memory.
*/
DosClose(hf);
CHK(!DosDelete( dlf.szFileName ));
CHK((hmfCopy = GpiCopyMetaFile((HMF) hItem)) != GPI_ERROR);
CHK(GpiSaveMetaFile(hmfCopy, dlf.szFileName) != GPI_ERROR);
break;
default:
/*
It may be reasonable to add support for other formats
here, by saving a bitmap of the current window contents.
But for now, close the file and return an error message.
*/
DosClose(hf);
fSuccess = FALSE;
break;
}
}
} else
fSuccess = FALSE; /* Couldn't query the clipboard format! */
/*
Clean up
*/
WinCloseClipbrd(vhab);
return fSuccess;
}
BOOL SaveText(HFILE hf, PSZ pszText) {
/*
Save text format
Count the number of characters, then write them.
*/
PSZ pszCounter; /* Temporary to count chars in sel */
USHORT ulcch = 0; /* The number of characters */
ULONG cbWritten; /* No. of bytes actually written */
pszCounter = pszText;
while (*pszCounter++) ulcch++;
return(!DosWrite(hf, pszText, ulcch, &cbWritten));
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.