RWICOCUR.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:13k
源码类别:
Windows编程
开发平台:
Visual C++
- /****************************************************************************/
- /* */
- /* Copyright (C) 1987-1996 Microsoft Corp. */
- /* All Rights Reserved */
- /* */
- /****************************************************************************/
- /****************************** Module Header *******************************
- * Module Name: rwicocur.c
- *
- * Routines to read and write icon and cursor files.
- *
- * History:
- *
- ****************************************************************************/
- #include "imagedit.h"
- #include <io.h>
- #include <fcntl.h> // For NT fstat().
- #include <systypes.h> // For fstat() types.
- #include <sysstat.h> // For fstat() function.
- /************************************************************************
- * LoadIconCursorFile
- *
- * Loads the specified icon or cursor file. It reads the images into
- * a list, then prompts for which one to open initially.
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- BOOL LoadIconCursorFile(
- PSTR pszFullFileName,
- BOOL fIcon)
- {
- HFILE hf;
- INT i;
- PIMAGEINFO pImage;
- LPBITMAPINFO lpBitmapInfo;
- HANDLE hDIB; // Handle to DIB bits.
- OFSTRUCT OfStruct;
- struct stat FileStatus;
- ICOCURSORHDR hdr; // Header structure of icon/cursor file.
- INT nImages;
- PICOCURSORDESC aIcoCurDesc; // Array of ico/cur descriptors.
- DWORD dwFilePos;
- DWORD dwFileSize;
- INT iType;
- if ((hf = (HFILE)OpenFile(pszFullFileName, (LPOFSTRUCT)&OfStruct, OF_READ))
- == (HFILE)-1) {
- Message(MSG_CANTOPEN, pszFullFileName);
- return FALSE;
- }
- fstat((INT)_open_osfhandle((long)(hf), (int)(O_RDONLY)), &FileStatus);
- dwFileSize = (DWORD)FileStatus.st_size;
- ImageLinkFreeList();
- if (fIcon)
- iType = FT_ICON;
- else
- iType = FT_CURSOR;
- /*
- * Read the Icon/Cursor File header.
- */
- if (!MyFileRead(hf, (LPSTR)&hdr, sizeof(ICOCURSORHDR),
- pszFullFileName, iType))
- goto Error1;
- if (hdr.iReserved != 0) {
- Message(MSG_BADICOCURFILE, pszFullFileName);
- goto Error1;
- }
- /*
- * Get number of images in the file.
- */
- nImages = hdr.iResourceCount;
- if (!nImages || nImages > MAXIMAGES) {
- Message(MSG_BADICOCURFILE, pszFullFileName);
- goto Error1;
- }
- if (hdr.iResourceType != 1 && hdr.iResourceType != 2) {
- Message(MSG_BADICOCURFILE, pszFullFileName);
- goto Error1;
- }
- /*
- * Allocate room for the descriptor records.
- */
- if (!(aIcoCurDesc = (PICOCURSORDESC)MyAlloc(
- sizeof(ICOCURSORDESC) * nImages)))
- goto Error1;
- /*
- * Read in the descriptor records.
- */
- if (!MyFileRead(hf, (LPSTR)aIcoCurDesc, sizeof(ICOCURSORDESC) * nImages,
- pszFullFileName, iType))
- goto Error2;
- /*
- * Get the current file position (after the descriptors). This
- * should be the start of the DIB's.
- */
- dwFilePos = (DWORD)SetFilePointer((HANDLE)hf, 0, NULL, (DWORD)1);
- /*
- * Validate the descriptor records.
- */
- for (i = 0; i < nImages; i++) {
- /*
- * Make sure the DIB's are sequential (not overlapping)
- * and they all fit within the file.
- */
- if (aIcoCurDesc[i].DIBOffset != dwFilePos ||
- dwFilePos + aIcoCurDesc[i].DIBSize > dwFileSize) {
- Message(MSG_BADICOCURFILE, pszFullFileName);
- goto Error2;
- }
- /*
- * Jump to the next DIB.
- */
- dwFilePos += aIcoCurDesc[i].DIBSize;
- }
- for (i = 0; i < nImages; i++) {
- pImage = ImageLinkAlloc(NULL, 0, 0,
- aIcoCurDesc[i].iHotspotX, aIcoCurDesc[i].iHotspotY,
- (aIcoCurDesc[i].iColorCount == (BYTE)8) ?
- aIcoCurDesc[i].iColorCount : 0);
- if (!pImage)
- goto Error3;
- /*
- * Allocate space for the DIB for this image.
- */
- if (!(hDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
- (DWORD)aIcoCurDesc[i].DIBSize))) {
- Message(MSG_OUTOFMEMORY);
- goto Error3;
- }
- pImage->DIBSize = aIcoCurDesc[i].DIBSize;
- pImage->DIBhandle = hDIB;
- pImage->DIBPtr = (LPSTR)GlobalLock(hDIB);
- }
- for (pImage = gpImageHead; pImage != NULL; pImage = pImage->pImageNext) {
- if (!MyFileRead(hf, pImage->DIBPtr, (DWORD)pImage->DIBSize,
- pszFullFileName, iType))
- goto Error3;
- lpBitmapInfo = (LPBITMAPINFO)pImage->DIBPtr;
- if (!IsValidDIB(lpBitmapInfo, pImage->DIBSize, TRUE)) {
- Message(MSG_BADICOCURFILE, pszFullFileName);
- goto Error3;
- }
- /*
- * Fill the x and y size fields in image node from
- * information in the DIB header.
- */
- pImage->cx = (INT)lpBitmapInfo->bmiHeader.biWidth;
- pImage->cy = (INT)lpBitmapInfo->bmiHeader.biHeight / 2;
- if (pImage->nColors == 0)
- pImage->nColors = (1 << lpBitmapInfo->bmiHeader.biBitCount);
- pImage->pDevice = DeviceLinkFind(
- fIcon ? gpIconDeviceHead : gpCursorDeviceHead,
- pImage->nColors, pImage->cx, pImage->cy);
- }
- _lclose((HFILE)hf);
- fFileDirty = FALSE;
- SetFileName(pszFullFileName);
- giType = iType;
- gnImages = nImages;
- /*
- * Update the PropBar and the Toolbox so that they show
- * information about the opened file. We do this now just
- * in case the user cancels out of the Image Select Dialog.
- */
- PropBarUpdate();
- ToolboxUpdate();
- /*
- * Open up an image. If there are multiple images in the file,
- * show the Image Select dialog. We also show the Image Select
- * dialog if the file only has one image but it is not for a known
- * device.
- */
- if (gnImages > 1 || !gpImageHead->pDevice)
- ImageSelectDialog();
- else
- ImageOpen2(gpImageHead);
- return TRUE;
- Error3:
- ImageLinkFreeList();
- Error2:
- MyFree(aIcoCurDesc);
- Error1:
- _lclose((HFILE)hf);
- return FALSE;
- }
- /************************************************************************
- * IsValidDIB
- *
- * This function determines if the given DIB is valid or not. It does
- * this without touching memory outside the bounds of the cbDIBSize
- * passed in or the size of a BITMAPINFOHEADER, whichever is smaller.
- * Note that even if the DIB is valid, however, the current image
- * editor might not be able to edit it (the size might be too big, for
- * instance).
- *
- * Arguments:
- * LPBITMAPINFO pDIB - Points to the DIB.
- * DWORD cbDIBSize - The size of the DIB.
- * BOOL fIcoCur - TRUE if this is an icon or cursor. This effects
- * whether an AND mask is expected to be in the DIB.
- *
- * History:
- *
- ************************************************************************/
- BOOL IsValidDIB(
- LPBITMAPINFO pDIB,
- DWORD cbDIBSize,
- BOOL fIcoCur)
- {
- DWORD cbANDMask;
- DWORD cbXORMask;
- DWORD cbColorTable;
- DWORD nHeight;
- if (cbDIBSize < sizeof(BITMAPINFOHEADER))
- return FALSE;
- if (pDIB->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
- return FALSE;
- if (pDIB->bmiHeader.biPlanes != 1)
- return FALSE;
- if (pDIB->bmiHeader.biBitCount != 1 &&
- pDIB->bmiHeader.biBitCount != 4 &&
- pDIB->bmiHeader.biBitCount != 8 &&
- pDIB->bmiHeader.biBitCount != 24)
- return FALSE;
- if (fIcoCur) {
- nHeight = pDIB->bmiHeader.biHeight / 2;
- cbANDMask = (((pDIB->bmiHeader.biWidth + 31) & 0xffffffe0) >> 3) *
- nHeight;
- }
- else {
- nHeight = pDIB->bmiHeader.biHeight;
- cbANDMask = 0;
- }
- cbColorTable = (1 << pDIB->bmiHeader.biBitCount) * sizeof(RGBQUAD);
- cbXORMask = ((((pDIB->bmiHeader.biWidth * pDIB->bmiHeader.biBitCount) +
- 31) & 0xffffffe0) >> 3) * nHeight;
- /*
- * Check the size field in the header. This must be either zero
- * or a valid size.
- */
- if (pDIB->bmiHeader.biSizeImage &&
- pDIB->bmiHeader.biSizeImage != cbXORMask + cbANDMask)
- return FALSE;
- if (cbDIBSize != sizeof(BITMAPINFOHEADER) + cbColorTable +
- cbXORMask + cbANDMask)
- return FALSE;
- return TRUE;
- }
- /************************************************************************
- * SaveIconCursorFile
- *
- *
- *
- * Arguments:
- *
- * Returns:
- * TRUE if successful, FALSE otherwise.
- *
- * History:
- *
- ************************************************************************/
- BOOL SaveIconCursorFile(
- PSTR pszFullFileName,
- INT iType)
- {
- ICOCURSORHDR IcoCurHdr; // Header structure of icon/cursor file.
- ICOCURSORDESC IcoCurDesc; // Icon/cursor descriptor struct.
- HCURSOR hcurOld; // Handle to old cursor.
- PIMAGEINFO pImage; // Pointer to node in image list.
- DWORD iBitsOffset; // Offset of the actual DIB bits for image.
- HFILE hf;
- OFSTRUCT OfStruct;
- hcurOld = SetCursor(hcurWait);
- /*
- * Save the bits of the current image.
- */
- ImageSave();
- /*
- * Open the file for writing.
- */
- if ((hf = (HFILE)OpenFile(pszFullFileName, &OfStruct, OF_CREATE | OF_READWRITE))
- == (HFILE)-1) {
- Message(MSG_CANTCREATE, pszFullFileName);
- goto Error1;
- }
- /*
- * This is crucial since this helps distinguish a 3.0 icon/cursor
- * from an old, old (2.1 format) icon/cursor, which has meaningful
- * information in this WORD.
- */
- IcoCurHdr.iReserved = (WORD)0;
- if (iType == FT_ICON)
- IcoCurHdr.iResourceType = 1; // Icon type.
- else
- IcoCurHdr.iResourceType = 2; // Cursor type.
- IcoCurHdr.iResourceCount = (WORD)gnImages;
- /*
- * Write the header to disk.
- */
- if (!MyFileWrite(hf, (LPSTR)&IcoCurHdr, sizeof(ICOCURSORHDR),
- pszFullFileName))
- goto Error2;
- /*
- * Write all the descriptors.
- */
- iBitsOffset = sizeof(ICOCURSORHDR) + (gnImages * sizeof(ICOCURSORDESC));
- for (pImage = gpImageHead; pImage; pImage = pImage->pImageNext) {
- IcoCurDesc.iWidth = (BYTE)pImage->cx;
- IcoCurDesc.iHeight = (BYTE)pImage->cy;
- IcoCurDesc.iColorCount = (giType == FT_ICON) ?
- (BYTE)pImage->nColors : (BYTE)0;
- IcoCurDesc.iUnused = 0;
- IcoCurDesc.iHotspotX = (WORD)pImage->iHotspotX;
- IcoCurDesc.iHotspotY = (WORD)pImage->iHotspotY;
- IcoCurDesc.DIBSize = pImage->DIBSize;
- IcoCurDesc.DIBOffset = iBitsOffset;
- if (!MyFileWrite(hf, (LPSTR)&IcoCurDesc, sizeof(ICOCURSORDESC),
- pszFullFileName))
- goto Error2;
- iBitsOffset += IcoCurDesc.DIBSize;
- }
- /*
- * Now write the DIB's.
- */
- for (pImage = gpImageHead; pImage; pImage = pImage->pImageNext) {
- if (!MyFileWrite(hf, (LPSTR)pImage->DIBPtr,
- (DWORD)pImage->DIBSize, pszFullFileName))
- goto Error2;
- }
- _lclose((HFILE)hf);
- fFileDirty = FALSE;
- SetFileName(pszFullFileName);
- SetCursor(hcurOld);
- return TRUE;
- Error2:
- _lclose((HFILE)hf);
- Error1:
- SetCursor(hcurOld);
- return FALSE;
- }