Click here to Skip to main content
15,885,953 members
Articles / Desktop Programming / Win32

Outlook add-in integrating Skype

Rate me:
Please Sign up or sign in to vote.
4.93/5 (32 votes)
28 May 2015CPOL20 min read 68.7K   2.4K   54  
Outlook add-in integration for Skype IM: Skype events, Outlook Skype ribbon, and more.
#include "Sdk.h"
#include "RcUtils.h"
#include "DllMgr.h"

BOOL
BitmapFromPNGResource(UINT pngResourceID, 
                      HBITMAP *phbm
) {
    HMODULE                 hinst               = DllMgr_GetObject()->Instance;
    HRSRC                   hResource           = NULL;
    HGLOBAL                 hImage              = NULL;
	LPVOID                  pImage              = NULL;
	DWORD                   dwSize              = 0;
    HGLOBAL                 gbuf                = NULL;
	LPVOID                  buf                 = NULL;

    HRESULT                 hr                  = S_FALSE;
    IStream*                pStream             = NULL;
    IWICBitmapDecoder*      pwicDecoder         = NULL;
    IWICBitmapSource*       pwicBitmap          = NULL;  
    IWICBitmapFrameDecode*  pwicFrame           = NULL;
    IWICBitmapSource*       pwicBitmapSource    = NULL;
    UINT                    nFrameCount         = 0;

    UINT                    bmpWidth            = 0;
    UINT                    bmpHeight           = 0;
    BITMAPINFO              bminfo              = {0};
    HDC                     hdcScreen           = NULL;
    void*                   pvImageBits         = NULL;
    UINT                    cbStride            = 0;
    UINT                    cbImage             = 0;

    HBITMAP                 hbm                 = NULL;

    BOOL    Result      = FALSE;

    __try {
        if(phbm == NULL) {
            __leave;
        }
        *phbm = NULL;

        //  RC stuff
        hResource = FindResourceW(hinst, 
                                  MAKEINTRESOURCE(pngResourceID), 
                                  L"PNG"
                                 );
        if(hResource == NULL) {
            __leave;
        }

        hImage = LoadResource(hinst, hResource);
		if(hImage == NULL) {
			__leave;
        }
		pImage = LockResource(hImage);
		if(pImage == NULL) {
			__leave;
        }
		dwSize = SizeofResource(hinst, hResource);
        if(dwSize == 0) {
            __leave;
        }
		gbuf = GlobalAlloc(GMEM_MOVEABLE, dwSize);
		if(gbuf == NULL) {
			__leave;
        }
		buf = GlobalLock(gbuf);
		if(buf == NULL) {
			__leave;
        }
        memmove(buf, pImage, dwSize);

        hr = CreateStreamOnHGlobal(gbuf, FALSE, &pStream);
        if(hr != S_OK) {
            __leave;
        }

        //  we have IStream; decoder stuff
        hr = CoCreateInstance(&CLSID_WICPngDecoder, 
                              NULL, 
                              CLSCTX_INPROC_SERVER, 
                              &IID_IWICBitmapDecoder, 
                              (void **)&pwicDecoder
                             );
        if(pwicDecoder == NULL) {
            __leave;
        }
        hr = IWICBitmapDecoder_Initialize(pwicDecoder, 
                                          pStream, 
                                          WICDecodeMetadataCacheOnLoad
                                         );
        if(FAILED(hr)) {
            __leave;
        }
        nFrameCount = 0;
        hr = IWICBitmapDecoder_GetFrameCount(pwicDecoder, 
                                             &nFrameCount
                                             );
        if(FAILED(hr)) {
            __leave;
        }
        if(nFrameCount != 1) {
            __leave;
        }
        hr = IWICBitmapDecoder_GetFrame(pwicDecoder, 
                                        0,
                                        &pwicFrame
                                        );
        if(pwicFrame == NULL) {
            __leave;
        }
        hr = IWICBitmapFrameDecode_QueryInterface(pwicFrame, 
                                                  &IID_IWICBitmapSource, 
                                                  (void **)&pwicBitmapSource
                                                 );
        if(pwicBitmapSource == NULL) {
            __leave;
        }
        hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppPBGRA, 
                                    pwicBitmapSource, 
                                    &pwicBitmap
                                   );
        if(FAILED(hr)) {
            __leave;
        }

        //  ok, we get IWICBitmapSource
        bmpWidth  = 0;
        bmpHeight = 0;
        hr = IWICBitmapSource_GetSize(pwicBitmap, 
                                      &bmpWidth, 
                                      &bmpHeight
                                     );
        if(FAILED(hr)) {
            __leave;
        }
        if(bmpWidth == 0 || bmpHeight == 0) {
            __leave;
        }
        memset(&bminfo, 0, sizeof(bminfo));
        bminfo.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
        bminfo.bmiHeader.biWidth        = bmpWidth;
        bminfo.bmiHeader.biHeight       = -((LONG)bmpHeight);
        bminfo.bmiHeader.biPlanes       = 1;
        bminfo.bmiHeader.biBitCount     = 32;
        bminfo.bmiHeader.biCompression  = BI_RGB;

        hdcScreen = GetDC(NULL);
        if(hdcScreen == NULL) {
            __leave;
        }
        hbm = CreateDIBSection(hdcScreen, 
                               &bminfo, 
                               DIB_RGB_COLORS, 
                               &pvImageBits, 
                               NULL, 
                               0
                              );
        if(hbm == NULL) {
            __leave;
        }

        cbStride = bmpWidth * 4;
        cbImage  = cbStride * bmpHeight;
        hr = IWICBitmapSource_CopyPixels(pwicBitmap, 
                                         NULL, 
                                         cbStride, 
                                         cbImage, 
                                         (BYTE *)pvImageBits
                                        );
        if(FAILED(hr)) {
            __leave;
        }

        *phbm = hbm;
        Result = TRUE;
    }
    __finally {
        if(hdcScreen != NULL) {
            ReleaseDC(NULL, hdcScreen);
        }

        if(pwicBitmapSource != NULL) {
            IWICBitmapSource_Release(pwicBitmapSource);
        }
        if(pwicFrame != NULL) {
            IWICBitmapFrameDecode_Release(pwicFrame);
        }
        if(pwicDecoder != NULL) {
            IWICBitmapDecoder_Release(pwicDecoder);
        }
        if(pwicBitmap != NULL) {
            IWICBitmapSource_Release(pwicBitmap);
        }

        if(pStream != NULL) {
            IStream_Release(pStream);
        }

        if(buf != NULL) {
            GlobalUnlock(buf);
        }
        if(gbuf != NULL) {
            GlobalFree(gbuf);
        }
    }

    return Result;
}

static 
const int kReadFileChunk = 16384;

BOOL
BitmapFromJPGFile(
    LPCWSTR     JPGFile, 
    HBITMAP     *phbm, 
    IPicture    **ppPicture
) {
    HANDLE                  hJpgFile            = NULL;
	DWORD                   dwSize              = 0;
    HGLOBAL                 gbuf                = NULL;
	LPBYTE                  buf                 = NULL;
    DWORD                   cbToRead            = 0;
    DWORD                   cbBytesRead         = 0;
    DWORD                   cbJpgSize           = 0;

    HRESULT                 hr                  = S_FALSE;
    IStream*                pStream             = NULL;
    HBITMAP                 hbm                 = NULL;
    IPicture                *pPicture           = NULL;
    SHORT                   picType             = PICTYPE_UNINITIALIZED;

    HDC                     hdcScreen           = NULL;
    HDC                     hdcMem              = NULL;
//    HBITMAP                 hbmMem              = NULL;
//    HBITMAP                 hbmMemOld           = NULL;
//    OLE_XSIZE_HIMETRIC      cx                  = 0;
//    OLE_XSIZE_HIMETRIC      cy                  = 0;
//    int                     nWidth              = 0;
//    int                     nHeight             = 0;

    BOOL    Result      = FALSE;

    __try {
        if(JPGFile == NULL) {
            __leave;
        }
        if(phbm == NULL) {
            __leave;
        }
        *phbm = NULL;

        if(ppPicture != NULL) {
            *ppPicture = NULL;
        }

        //  RC stuff
        hJpgFile = CreateFileW(JPGFile, 
                               FILE_READ_DATA, 
                               FILE_SHARE_READ, 
                               NULL, 
                               OPEN_EXISTING, 
                               FILE_ATTRIBUTE_NORMAL, 
                               NULL
                              );
        if(hJpgFile == INVALID_HANDLE_VALUE) {
            __leave;
        }

		dwSize = GetFileSize(hJpgFile, NULL);
        if(dwSize == INVALID_FILE_SIZE) {
            __leave;
        }
		gbuf = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, dwSize);
		if(gbuf == NULL) {
			__leave;
        }
		buf = (LPBYTE)GlobalLock(gbuf);
		if(buf == NULL) {
			__leave;
        }
        cbToRead = kReadFileChunk;
        while(ReadFile(hJpgFile, (LPVOID)buf, cbToRead, &cbBytesRead, NULL)) {
            if(cbBytesRead == 0) {
                break;
            }

            cbJpgSize += cbBytesRead;
            buf += cbBytesRead;
        }
        GlobalUnlock(buf);

        hr = CreateStreamOnHGlobal(gbuf, FALSE, &pStream);
        if(hr != S_OK) {
            __leave;
        }

        hr = OleLoadPicture(pStream, 
                            0, 
                            FALSE, 
                            &IID_IPicture, 
                            (void **)&pPicture
                           );
        if(hr != S_OK) {
            __leave;
        }

        if(ppPicture != NULL) {
            IPicture_QueryInterface(pPicture, 
                                    &IID_IPicture, 
                                    (void **)ppPicture
                                   );
        }

        hr = IPicture_get_Type(pPicture, &picType);
        if(hr != S_OK) {
            __leave;
        }

        if(picType != PICTYPE_BITMAP) {
            __leave;
        }

        hr = IPicture_get_Handle(pPicture, (OLE_HANDLE *)&hbm);
        if(hr != S_OK) {
            __leave;
        }
#if 0
        hr = IPicture_get_Width(pPicture, &cx);
        if(hr != S_OK) {
            __leave;
        }
        hr = IPicture_get_Height(pPicture, &cy);
        if(hr != S_OK) {
            __leave;
        }

        hdcScreen = GetDC(NULL);
        if(hdcScreen == NULL) {
            __leave;
        }

        nWidth  = MulDiv(cx, GetDeviceCaps(hdcScreen, LOGPIXELSX), HIMETRIC_INCH);
        nHeight = MulDiv(cy, GetDeviceCaps(hdcScreen, LOGPIXELSY), HIMETRIC_INCH);

        nWidth  *= 1;
        nHeight *= 1;

        hdcMem = CreateCompatibleDC(hdcScreen);
        if(hdcMem == NULL) {
            __leave;
        }
        hbmMem = CreateCompatibleBitmap(hdcMem, nWidth, nHeight);
        if(hbmMem == NULL) {
            __leave;
        }
        hbmMemOld = (HBITMAP)SelectObject(hdcMem, (HGDIOBJ)hbmMem);

        hr = IPicture_Render(pPicture, 
                             hdcMem, 
                             0, 
                             0, 
                             nWidth, 
                             -nHeight, 
                             0, 
                             0, 
                             cx, 
                             -cy, 
                             NULL
                            );
        SelectObject(hdcMem, (HGDIOBJ)hbmMemOld);
        if(hr != S_OK) {
            __leave;
        }

        *phbm = hbmMem;
#else
        *phbm = hbm;
#endif
        Result = TRUE;
    }
    __finally {
        if(hdcMem != NULL) {
            DeleteDC(hdcMem);
        }
        if(hdcScreen != NULL) {
            ReleaseDC(NULL, hdcScreen);
        }

        if(pPicture != NULL) {
            IPicture_Release(pPicture);
        }

        if(pStream != NULL) {
            IStream_Release(pStream);
        }

        if(buf != NULL) {
            GlobalUnlock(buf);
        }
        if(gbuf != NULL) {
            GlobalFree(gbuf);
        }

        if(hJpgFile != INVALID_HANDLE_VALUE) {
            CloseHandle(hJpgFile);
        }
    }

    return Result;
}

BOOL
BitmapFromJPGFile2(
    LPCWSTR     JPGFile, 
    HBITMAP     *phbm
) {
//  HMODULE                 hinst               = DllMgr_GetObject()->Instance;
//  HRSRC                   hResource           = NULL;
//  HGLOBAL                 hImage              = NULL;
//	LPVOID                  pImage              = NULL;
	DWORD                   dwSize              = 0;
    HGLOBAL                 gbuf                = NULL;
	LPBYTE                  buf                 = NULL;

    HANDLE                  hJpgFile            = NULL;
    DWORD                   cbToRead            = 0;
    DWORD                   cbBytesRead         = 0;
    DWORD                   cbJpgSize           = 0;

    HRESULT                 hr                  = S_FALSE;
    IStream*                pStream             = NULL;
    IWICBitmapDecoder*      pwicDecoder         = NULL;
    IWICBitmapSource*       pwicBitmap          = NULL;  
    IWICBitmapFrameDecode*  pwicFrame           = NULL;
    IWICBitmapSource*       pwicBitmapSource    = NULL;
    UINT                    nFrameCount         = 0;

    UINT                    bmpWidth            = 0;
    UINT                    bmpHeight           = 0;
    BITMAPINFO              bminfo              = {0};
    HDC                     hdcScreen           = NULL;
    void*                   pvImageBits         = NULL;
    UINT                    cbStride            = 0;
    UINT                    cbImage             = 0;

    HBITMAP                 hbm                 = NULL;

    BOOL    Result      = FALSE;

    __try {
        if(phbm == NULL) {
            __leave;
        }
        *phbm = NULL;

        if(JPGFile == NULL) {
            __leave;
        }
        if(phbm == NULL) {
            __leave;
        }
        *phbm = NULL;

        //  RC stuff
        hJpgFile = CreateFileW(JPGFile, 
                               FILE_READ_DATA, 
                               FILE_SHARE_READ, 
                               NULL, 
                               OPEN_EXISTING, 
                               FILE_ATTRIBUTE_NORMAL, 
                               NULL
                              );
        if(hJpgFile == INVALID_HANDLE_VALUE) {
            __leave;
        }

		dwSize = GetFileSize(hJpgFile, NULL);
        if(dwSize == INVALID_FILE_SIZE) {
            __leave;
        }
		gbuf = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, dwSize);
		if(gbuf == NULL) {
			__leave;
        }
		buf = (LPBYTE)GlobalLock(gbuf);
		if(buf == NULL) {
			__leave;
        }
        cbToRead = kReadFileChunk;
        while(ReadFile(hJpgFile, (LPVOID)buf, cbToRead, &cbBytesRead, NULL)) {
            if(cbBytesRead == 0) {
                break;
            }

            cbJpgSize += cbBytesRead;
            buf += cbBytesRead;
        }
        GlobalUnlock(buf);

        hr = CreateStreamOnHGlobal(gbuf, FALSE, &pStream);
        if(hr != S_OK) {
            __leave;
        }

        //  we have IStream; decoder stuff
        hr = CoCreateInstance(&CLSID_WICJpegDecoder, 
                              NULL, 
                              CLSCTX_INPROC_SERVER, 
                              &IID_IWICBitmapDecoder, 
                              (void **)&pwicDecoder
                             );
        if(pwicDecoder == NULL) {
            __leave;
        }
        hr = IWICBitmapDecoder_Initialize(pwicDecoder, 
                                          pStream, 
                                          WICDecodeMetadataCacheOnLoad
                                         );
        if(FAILED(hr)) {
            __leave;
        }
        nFrameCount = 0;
        hr = IWICBitmapDecoder_GetFrameCount(pwicDecoder, 
                                             &nFrameCount
                                             );
        if(FAILED(hr)) {
            __leave;
        }
        if(nFrameCount != 1) {
            __leave;
        }
        hr = IWICBitmapDecoder_GetFrame(pwicDecoder, 
                                        0,
                                        &pwicFrame
                                        );
        if(pwicFrame == NULL) {
            __leave;
        }
        hr = IWICBitmapFrameDecode_QueryInterface(pwicFrame, 
                                                  &IID_IWICBitmapSource, 
                                                  (void **)&pwicBitmapSource
                                                 );
        if(pwicBitmapSource == NULL) {
            __leave;
        }
        hr = WICConvertBitmapSource(&GUID_WICPixelFormat24bppBGR, 
                                    pwicBitmapSource, 
                                    &pwicBitmap
                                   );
        if(FAILED(hr)) {
            __leave;
        }

        //  ok, we get IWICBitmapSource
        bmpWidth  = 0;
        bmpHeight = 0;
        hr = IWICBitmapSource_GetSize(pwicBitmap, 
                                      &bmpWidth, 
                                      &bmpHeight
                                     );
        if(FAILED(hr)) {
            __leave;
        }
        if(bmpWidth == 0 || bmpHeight == 0) {
            __leave;
        }
        memset(&bminfo, 0, sizeof(bminfo));
        bminfo.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
        bminfo.bmiHeader.biWidth        = bmpWidth;
        bminfo.bmiHeader.biHeight       = -((LONG)bmpHeight);
        bminfo.bmiHeader.biPlanes       = 1;
        bminfo.bmiHeader.biBitCount     = 24;
        bminfo.bmiHeader.biCompression  = BI_RGB;
        {
            int nWidth  = MulDiv(bmpWidth, GetDeviceCaps(hdcScreen, LOGPIXELSX), HIMETRIC_INCH);
            int nHeight = MulDiv(bmpHeight, GetDeviceCaps(hdcScreen, LOGPIXELSY), HIMETRIC_INCH);

            bminfo.bmiHeader.biXPelsPerMeter = nWidth;
            bminfo.bmiHeader.biYPelsPerMeter = nHeight;
        }

        hdcScreen = GetDC(NULL);
        if(hdcScreen == NULL) {
            __leave;
        }
        hbm = CreateDIBSection(hdcScreen, 
                               &bminfo, 
                               DIB_RGB_COLORS, 
                               &pvImageBits, 
                               NULL, 
                               0
                              );
        if(hbm == NULL) {
            __leave;
        }

        cbStride = bmpWidth * 4;
        cbImage  = cbStride * bmpHeight;
        hr = IWICBitmapSource_CopyPixels(pwicBitmap, 
                                         NULL, 
                                         cbStride, 
                                         cbImage, 
                                         (BYTE *)pvImageBits
                                        );
        if(FAILED(hr)) {
            __leave;
        }

        *phbm = hbm;
        Result = TRUE;
    }
    __finally {
        if(hdcScreen != NULL) {
            ReleaseDC(NULL, hdcScreen);
        }

        if(pwicBitmapSource != NULL) {
            IWICBitmapSource_Release(pwicBitmapSource);
        }
        if(pwicFrame != NULL) {
            IWICBitmapFrameDecode_Release(pwicFrame);
        }
        if(pwicDecoder != NULL) {
            IWICBitmapDecoder_Release(pwicDecoder);
        }
        if(pwicBitmap != NULL) {
            IWICBitmapSource_Release(pwicBitmap);
        }

        if(pStream != NULL) {
            IStream_Release(pStream);
        }

        if(buf != NULL) {
            GlobalUnlock(buf);
        }
        if(gbuf != NULL) {
            GlobalFree(gbuf);
        }
    }

    return Result;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader BitDefender
Romania Romania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions