⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 olepicture.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (i % 10 == 9) MESSAGE("\n");
    }
    MESSAGE("\n");
    break;
  }
  }
  This->bIsDirty = FALSE;

  /* FIXME: this notify is not really documented */
  if (hr==S_OK)
      OLEPicture_SendNotify(This,DISPID_PICT_TYPE);
  return hr;
}

static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength)
{
    int iSuccess = 0;
    HDC hDC;
    BITMAPINFO * pInfoBitmap;
    int iNumPaletteEntries;
    unsigned char * pPixelData;
    BITMAPFILEHEADER * pFileHeader;
    BITMAPINFO * pInfoHeader;

    pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
        sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));

    /* Find out bitmap size and padded length */
    hDC = GetDC(0);
    pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
    GetDIBits(hDC, hBitmap, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);

    /* Fetch bitmap palette & pixel data */

    pPixelData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pInfoBitmap->bmiHeader.biSizeImage);
    GetDIBits(hDC, hBitmap, 0, pInfoBitmap->bmiHeader.biHeight, pPixelData, pInfoBitmap, DIB_RGB_COLORS);

    /* Calculate the total length required for the BMP data */
    if (pInfoBitmap->bmiHeader.biClrUsed != 0) {
	iNumPaletteEntries = pInfoBitmap->bmiHeader.biClrUsed;
	if (iNumPaletteEntries > 256) iNumPaletteEntries = 256;
    } else {
	if (pInfoBitmap->bmiHeader.biBitCount <= 8)
	    iNumPaletteEntries = 1 << pInfoBitmap->bmiHeader.biBitCount;
	else
    	    iNumPaletteEntries = 0;
    }
    *pLength =
        sizeof(BITMAPFILEHEADER) +
        sizeof(BITMAPINFOHEADER) +
        iNumPaletteEntries * sizeof(RGBQUAD) +
        pInfoBitmap->bmiHeader.biSizeImage;
    *ppBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pLength);

    /* Fill the BITMAPFILEHEADER */
    pFileHeader = (BITMAPFILEHEADER *)(*ppBuffer);
    pFileHeader->bfType = 0x4d42;
    pFileHeader->bfSize = *pLength;
    pFileHeader->bfOffBits =
        sizeof(BITMAPFILEHEADER) +
        sizeof(BITMAPINFOHEADER) +
        iNumPaletteEntries * sizeof(RGBQUAD);

    /* Fill the BITMAPINFOHEADER and the palette data */
    pInfoHeader = (BITMAPINFO *)((unsigned char *)(*ppBuffer) + sizeof(BITMAPFILEHEADER));
    memcpy(pInfoHeader, pInfoBitmap, sizeof(BITMAPINFOHEADER) + iNumPaletteEntries * sizeof(RGBQUAD));
    memcpy(
        (unsigned char *)(*ppBuffer) +
            sizeof(BITMAPFILEHEADER) +
            sizeof(BITMAPINFOHEADER) +
            iNumPaletteEntries * sizeof(RGBQUAD),
        pPixelData, pInfoBitmap->bmiHeader.biSizeImage);
    iSuccess = 1;

    HeapFree(GetProcessHeap(), 0, pPixelData);
    HeapFree(GetProcessHeap(), 0, pInfoBitmap);
    return iSuccess;
}

static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
{
	ICONINFO infoIcon;
	int iSuccess = 0;

	*ppBuffer = NULL; *pLength = 0;
	if (GetIconInfo(hIcon, &infoIcon)) {
		HDC hDC;
		BITMAPINFO * pInfoBitmap;
		unsigned char * pIconData = NULL;
		unsigned int iDataSize = 0;

        pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));

		/* Find out icon size */
		hDC = GetDC(0);
		pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
		GetDIBits(hDC, infoIcon.hbmColor, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
		if (1) {
			/* Auxiliary pointers */
			CURSORICONFILEDIR * pIconDir;
			CURSORICONFILEDIRENTRY * pIconEntry;
			BITMAPINFOHEADER * pIconBitmapHeader;
			unsigned int iOffsetPalette;
			unsigned int iOffsetColorData;
			unsigned int iOffsetMaskData;

			unsigned int iLengthScanLineColor;
			unsigned int iLengthScanLineMask;
			unsigned int iNumEntriesPalette;

			iLengthScanLineMask = ((pInfoBitmap->bmiHeader.biWidth + 31) >> 5) << 2;
			iLengthScanLineColor = ((pInfoBitmap->bmiHeader.biWidth * pInfoBitmap->bmiHeader.biBitCount + 31) >> 5) << 2;
/*
			FIXME("DEBUG: bitmap size is %d x %d\n",
				pInfoBitmap->bmiHeader.biWidth,
				pInfoBitmap->bmiHeader.biHeight);
			FIXME("DEBUG: bitmap bpp is %d\n",
				pInfoBitmap->bmiHeader.biBitCount);
			FIXME("DEBUG: bitmap nplanes is %d\n",
				pInfoBitmap->bmiHeader.biPlanes);
			FIXME("DEBUG: bitmap biSizeImage is %lu\n",
				pInfoBitmap->bmiHeader.biSizeImage);
*/
			/* Let's start with one CURSORICONFILEDIR and one CURSORICONFILEDIRENTRY */
			iDataSize += 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY) + sizeof(BITMAPINFOHEADER);
			pIconData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iDataSize);

			/* Fill out the CURSORICONFILEDIR */
			pIconDir = (CURSORICONFILEDIR *)pIconData;
			pIconDir->idType = 1;
			pIconDir->idCount = 1;

			/* Fill out the CURSORICONFILEDIRENTRY */
			pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
			pIconEntry->bWidth = (unsigned char)pInfoBitmap->bmiHeader.biWidth;
			pIconEntry->bHeight = (unsigned char)pInfoBitmap->bmiHeader.biHeight;
			pIconEntry->bColorCount =
				(pInfoBitmap->bmiHeader.biBitCount < 8)
				? 1 << pInfoBitmap->bmiHeader.biBitCount
				: 0;
			pIconEntry->xHotspot = pInfoBitmap->bmiHeader.biPlanes;
			pIconEntry->yHotspot = pInfoBitmap->bmiHeader.biBitCount;
			pIconEntry->dwDIBSize = 0;
			pIconEntry->dwDIBOffset = 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY);

			/* Fill out the BITMAPINFOHEADER */
			pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY));
			memcpy(pIconBitmapHeader, &pInfoBitmap->bmiHeader, sizeof(BITMAPINFOHEADER));

			/*	Find out whether a palette exists for the bitmap */
			if (	(pInfoBitmap->bmiHeader.biBitCount == 16 && pInfoBitmap->bmiHeader.biCompression == BI_RGB)
				||	(pInfoBitmap->bmiHeader.biBitCount == 24)
				||	(pInfoBitmap->bmiHeader.biBitCount == 32 && pInfoBitmap->bmiHeader.biCompression == BI_RGB)) {
				iNumEntriesPalette = pInfoBitmap->bmiHeader.biClrUsed;
				if (iNumEntriesPalette > 256) iNumEntriesPalette = 256; 
			} else if ((pInfoBitmap->bmiHeader.biBitCount == 16 || pInfoBitmap->bmiHeader.biBitCount == 32)
				&& pInfoBitmap->bmiHeader.biCompression == BI_BITFIELDS) {
				iNumEntriesPalette = 3;
			} else if (pInfoBitmap->bmiHeader.biBitCount <= 8) {
				iNumEntriesPalette = 1 << pInfoBitmap->bmiHeader.biBitCount;
			} else {
				iNumEntriesPalette = 0;
			}

			/*  Add bitmap size and header size to icon data size. */
			iOffsetPalette = iDataSize;
			iDataSize += iNumEntriesPalette * sizeof(DWORD);
			iOffsetColorData = iDataSize;
			iDataSize += pIconBitmapHeader->biSizeImage;
			iOffsetMaskData = iDataSize;
			iDataSize += pIconBitmapHeader->biHeight * iLengthScanLineMask;
			pIconBitmapHeader->biSizeImage += pIconBitmapHeader->biHeight * iLengthScanLineMask;
			pIconBitmapHeader->biHeight *= 2;
			pIconData = HeapReAlloc(GetProcessHeap(), 0, pIconData, iDataSize);
			pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
			pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY));
			pIconEntry->dwDIBSize = iDataSize - (3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY));

			/* Get the actual bitmap data from the icon bitmap */
			GetDIBits(hDC, infoIcon.hbmColor, 0, pInfoBitmap->bmiHeader.biHeight,
				pIconData + iOffsetColorData, pInfoBitmap, DIB_RGB_COLORS);
			if (iNumEntriesPalette > 0) {
				memcpy(pIconData + iOffsetPalette, pInfoBitmap->bmiColors,
					iNumEntriesPalette * sizeof(RGBQUAD));
			}

			/* Reset all values so that GetDIBits call succeeds */
			memset(pIconData + iOffsetMaskData, 0, iDataSize - iOffsetMaskData);
			memset(pInfoBitmap, 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
			pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
/*
            if (!(GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS)
				&& GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight,
					pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS))) {

                printf("ERROR: unable to get bitmap mask (error %lu)\n",
					GetLastError());

			}
*/
            GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
            GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight, pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS);

			/* Write out everything produced so far to the stream */
			*ppBuffer = pIconData; *pLength = iDataSize;
			iSuccess = 1;
		} else {
/*
			printf("ERROR: unable to get bitmap information via GetDIBits() (error %lu)\n",
				GetLastError());
*/
		}
		/*
			Remarks (from MSDN entry on GetIconInfo):

			GetIconInfo creates bitmaps for the hbmMask and hbmColor
			members of ICONINFO. The calling application must manage
			these bitmaps and delete them when they are no longer
			necessary.
		 */
		if (hDC) ReleaseDC(0, hDC);
		DeleteObject(infoIcon.hbmMask);
		if (infoIcon.hbmColor) DeleteObject(infoIcon.hbmColor);
		HeapFree(GetProcessHeap(), 0, pInfoBitmap);
	} else {
		printf("ERROR: Unable to get icon information (error %lu)\n",
			GetLastError());
	}
	return iSuccess;
}

static HRESULT WINAPI OLEPictureImpl_Save(
  IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
{
    HRESULT hResult = E_NOTIMPL;
    void * pIconData;
    unsigned int iDataSize;
    ULONG dummy;
    int iSerializeResult = 0;

  OLEPictureImpl *This = impl_from_IPersistStream(iface);

    switch (This->desc.picType) {
    case PICTYPE_ICON:
        if (This->bIsDirty) {
            if (serializeIcon(This->desc.u.icon.hicon, &pIconData, &iDataSize)) {
                if (This->loadtime_magic != 0xdeadbeef) {
                    DWORD header[2];

                    header[0] = This->loadtime_magic;
                    header[1] = iDataSize;
                    IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
                }
                IStream_Write(pStm, pIconData, iDataSize, &dummy);

                HeapFree(GetProcessHeap(), 0, This->data);
                This->data = pIconData;
                This->datalen = iDataSize;
                hResult = S_OK;
            } else {
                FIXME("(%p,%p,%d), unable to serializeIcon()!\n",This,pStm,fClearDirty);
                hResult = E_FAIL;
            }
        } else {
            if (This->loadtime_magic != 0xdeadbeef) {
                DWORD header[2];

                header[0] = This->loadtime_magic;
                header[1] = This->datalen;
                IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
            }
            IStream_Write(pStm, This->data, This->datalen, &dummy);
            hResult = S_OK;
        }
        break;
    case PICTYPE_BITMAP:
        if (This->bIsDirty) {
            switch (This->keepOrigFormat ? This->loadtime_format : 0x4d42) {
            case 0x4d42:
                iSerializeResult = serializeBMP(This->desc.u.bmp.hbitmap, &pIconData, &iDataSize);
                break;
            case 0xd8ff:
                FIXME("(%p,%p,%d), PICTYPE_BITMAP (format JPEG) not implemented!\n",This,pStm,fClearDirty);
                break;
            case 0x4947:
                FIXME("(%p,%p,%d), PICTYPE_BITMAP (format GIF) not implemented!\n",This,pStm,fClearDirty);
                break;
            default:
                FIXME("(%p,%p,%d), PICTYPE_BITMAP (format UNKNOWN, using BMP?) not implemented!\n",This,pStm,fClearDirty);
                break;
            }
            if (iSerializeResult) {
                /*
                if (This->loadtime_magic != 0xdeadbeef) {
                */
                if (1) {
                    DWORD header[2];

                    header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c;
                    header[1] = iDataSize;
                    IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
                }
                IStream_Write(pStm, pIconData, iDataSize, &dummy);

                HeapFree(GetProcessHeap(), 0, This->data);
                This->data = pIconData;
                This->datalen = iDataSize;
                hResult = S_OK;
            }
        } else {
            /*
            if (This->loadtime_magic != 0xdeadbeef) {
            */
            if (1) {
                DWORD header[2];

                header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c;
                header[1] = This->datalen;
                IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
            }
            IStream_Write(pStm, This->data, This->datalen, &dummy);
            hResult = S_OK;
        }
        break;
    case PICTYPE_METAFILE:
        FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty);
        break;
    case PICTYPE_ENHMETAFILE:
        FIXME("(%p,%p,%d),PICTYPE_ENHMETAFILE not implemented!\n",This,pStm,fClearDirty);
        break;
    default:
        FIXME("(%p,%p,%d), [unknown type] not implemented!\n",This,pStm,fClearDirty);
        break;
    }
    if (hResult == S_OK && fClearDirty) This->bIsDirty = FALSE;
    return hResult;
}

static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
  IPersistStream* iface,ULARGE_INTEGER*pcbSize)
{
  OLEPictureImpl *This = impl_from_IPersistStream(iface);
  FIXME("(%p,%p),stub!\n",This,pcbSize);
  return E_NOTIMPL;
}


/************************************************************************
 *    IDispatch
 */

/************************************************************************
 * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static HRESULT WINAPI OLEPictureImpl_IDispatch_QueryInterface(
  IDispatch* iface,
  REFIID     riid,
  VOID**     ppvoid)
{
  OLEPictureImpl *This = impl_from_IDispatch(iface);

  return IPicture_QueryInterface((IPicture *)This, riid, ppvoid);
}

/************************************************************************
 * OLEPictureImpl_IDispatch_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI OLEPictureImpl_IDispatch_AddRef(
  IDispatch* iface)
{
  OLEPictureImpl *This = impl_from_IDispatch(iface);

  return IPicture_AddRef((IPicture *)This);
}

/************************************************************************
 * OLEPictureImpl_IDispatch_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI OLEPictureImpl_IDispatch_Release(
  IDispatch* iface)
{
  OLEPictureImpl *This = impl_from_IDispatch(iface);

  return IPicture_Release((IPicture *)This);
}

/************************************************************************
 * OLEPictureImpl_GetTypeInfoCount (IDispatch)
 *
 * See Windows documentation for more details on IDispatch methods.
 */
static HRESULT WINAPI OLEPictureImpl_GetT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -