Click here to Skip to main content
12,358,777 members (62,235 online)
Click here to Skip to main content
Add your own
alternative version

Stats

68.2K views
2K downloads
44 bookmarked
Posted

Desktop Calendar

, 4 Mar 2004
Rate this:
Please Sign up or sign in to vote.
A nice desktop calendar that sits on your desktop.

Sample Image - Desktop_Calendar.jpg

Introduction

This article describes a simple calendar that sits on your desktop. I have created this application to just study about alpha blending, desktop wallpapers, and how a device context can be saved as a bitmap. I am planning to make a more refined version including a time scheduler and reminder also.

Using the code

Alpha Blending

HBITMAP Create24BPPDIBSection(HDC hDC, int iWidth, int iHeight)
{
    BITMAPINFO bmi;
    HBITMAP hbm;
    LPBYTE pBits;

    // Initialize header to 0s.
    ZeroMemory(&bmi, sizeof(bmi));

    // Fill out the fields you care about.
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = iWidth;
    bmi.bmiHeader.biHeight = iHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;

    // Create the surface.
    hbm = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS,(void **)&pBits, NULL, 0);
      
    return(hbm);
}

BOOL BitmapsCompatible(LPBITMAP lpbm1, LPBITMAP lpbm2)
{
    if (lpbm1->bmBitsPixel != lpbm2->bmBitsPixel) 
        return FALSE;
    if (lpbm1->bmPlanes    != lpbm2->bmPlanes)    
        return FALSE;
    if (lpbm1->bmWidth     != lpbm2->bmWidth)     
        return FALSE;
    if (lpbm1->bmHeight    != lpbm2->bmHeight)    
        return FALSE;
    return TRUE;
}

BOOL BlendImages(HBITMAP hbmSrc1, HBITMAP hbmSrc2, HBITMAP hbmDst, DWORD dwWeight1)
{
    BITMAP bmSrc1, bmSrc2, bmDst;
    RGBTRIPLE *lprgbSrc1, *lprgbSrc2, *lprgbDst;
    DWORD dwWidthBytes, dwWeight2;
    int x, y;
    
    // Only values between 0 and 255 are valid.
    if (dwWeight1 > 255) return FALSE;
    
    // Get weighting value for second source image.
    dwWeight2 = 255-dwWeight1;
    
    // Get information about the surfaces you were passed.
    if (!GetObject(hbmSrc1, sizeof(BITMAP), &bmSrc1)) return FALSE;
    if (!GetObject(hbmSrc2, sizeof(BITMAP), &bmSrc2)) return FALSE;
    if (!GetObject(hbmDst,  sizeof(BITMAP), &bmDst))  return FALSE;

    // Make sure you have data that meets your requirements.
    if (!BitmapsCompatible(&bmSrc1, &bmSrc2))
        return FALSE;
    if (!BitmapsCompatible(&bmSrc1, &bmDst))
        return FALSE;
    if (bmSrc1.bmBitsPixel != 24)
        return FALSE;
    if (bmSrc1.bmPlanes != 1)
        return FALSE;
    if (!bmSrc1.bmBits || !bmSrc2.bmBits || !bmDst.bmBits)
        return FALSE;

    dwWidthBytes = bmDst.bmWidthBytes;
    
    // Initialize the surface pointers.
    lprgbSrc1 = (RGBTRIPLE *)bmSrc1.bmBits; 
    lprgbSrc2 = (RGBTRIPLE *)bmSrc2.bmBits;  
    lprgbDst  = (RGBTRIPLE *)bmDst.bmBits;

    for (y=0; y<bmDst.bmHeight; y++) {
        for (x=0; x<bmDst.bmWidth; x++) {
            lprgbDst[x].rgbtRed   = 
              (BYTE)((((DWORD)lprgbSrc1[x].rgbtRed * dwWeight1) + 
              ((DWORD)lprgbSrc2[x].rgbtRed * dwWeight2)) >> 8);
            lprgbDst[x].rgbtGreen = 
              (BYTE)((((DWORD)lprgbSrc1[x].rgbtGreen * dwWeight1) + 
              ((DWORD)lprgbSrc2[x].rgbtGreen * dwWeight2)) >> 8);
            lprgbDst[x].rgbtBlue  = 
              (BYTE)((((DWORD)lprgbSrc1[x].rgbtBlue * dwWeight1) + 
              ((DWORD)lprgbSrc2[x].rgbtBlue * dwWeight2)) >> 8);
        }

        // Move to next scan line.
        lprgbSrc1 = (RGBTRIPLE *)((LPBYTE)lprgbSrc1 + dwWidthBytes);
        lprgbSrc2 = (RGBTRIPLE *)((LPBYTE)lprgbSrc2 + dwWidthBytes);
        lprgbDst  = (RGBTRIPLE *)((LPBYTE)lprgbDst  + dwWidthBytes);
    }

    return TRUE;
}

BOOL DoAlphaBlend(
  HDC hdcDest,                 // Handle to destination DC.
  int nXOriginDest,            // X-coord of upper-left corner.
  int nYOriginDest,            // Y-coord of upper-left corner.
  int nWidthDest,              // Destination width.
  int nHeightDest,             // Destination height.
  HDC hdcSrc,                  // Handle to source DC.
  int nXOriginSrc,             // X-coord of upper-left corner.
  int nYOriginSrc,             // Y-coord of upper-left corner.
  int nWidthSrc,               // Source width.
  int nHeightSrc,              // Source height.
  DWORD dwSourceWeight)        // Source weighting (between 0 and 255).
{
    HDC      hdcSrc1 = NULL;
    HDC      hdcSrc2 = NULL;
    HDC      hdcDst  = NULL;
    HBITMAP  hbmSrc1 = NULL;
    HBITMAP  hbmSrc2 = NULL;
    HBITMAP  hbmDst  = NULL;
    BOOL     bReturn;

    // Create surfaces for sources and destination images.
    hbmSrc1 = Create24BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
    if (!hbmSrc1) goto HANDLEERROR;

    hbmSrc2 = Create24BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
    if (!hbmSrc2) goto HANDLEERROR;

    hbmDst  = Create24BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
    if (!hbmDst) goto HANDLEERROR;

    
    // Create HDCs to hold our surfaces.
    hdcSrc1 = CreateCompatibleDC(hdcDest);
    if (!hdcSrc1) goto HANDLEERROR;
    
    hdcSrc2 = CreateCompatibleDC(hdcDest);
    if (!hdcSrc2) goto HANDLEERROR;
    
    hdcDst  = CreateCompatibleDC(hdcDest);
    if (!hdcDst) goto HANDLEERROR;

    
    // Prepare the surfaces for drawing.
    SelectObject(hdcSrc1, hbmSrc1);
    SelectObject(hdcSrc2, hbmSrc2);
    SelectObject(hdcDst,  hbmDst);
    SetStretchBltMode(hdcSrc1, COLORONCOLOR);
    SetStretchBltMode(hdcSrc2, COLORONCOLOR);

    
    // Capture a copy of the source area.
    if (!StretchBlt(hdcSrc1, 0,0,nWidthDest,nHeightDest,
                    hdcSrc,  nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, 
                    SRCCOPY))
         goto HANDLEERROR;
    
    // Capture a copy of the destination area.
    if (!StretchBlt(hdcSrc2, 0,0,nWidthDest,nHeightDest,
                    hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 
                    SRCCOPY))
         goto HANDLEERROR;

                  
    // Blend the two source areas to create the destination image.
    bReturn = BlendImages(hbmSrc1, hbmSrc2, hbmDst, dwSourceWeight);

    
    // Clean up objects you do not need any longer.
    // You cannot delete an object that's selected into an
    // HDC so delete the HDC first. 
    DeleteDC(hdcSrc1);
    DeleteDC(hdcSrc2);
    DeleteObject(hbmSrc1);
    DeleteObject(hbmSrc2);

    
    // Display the blended (destination) image to the target HDC.
    if (bReturn) {
        BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 
               hdcDst, 0,0, SRCCOPY);
    }

    
    // Clean up the rest of the objects you created.
    DeleteDC(hdcDst);
    DeleteObject(hbmDst);

    return bReturn;

HANDLEERROR:

    if (hdcSrc1) DeleteDC(hdcSrc1);
    if (hdcSrc2) DeleteDC(hdcSrc2);
    if (hdcDst)  DeleteDC(hdcDst);
    if (hbmSrc1) DeleteObject(hbmSrc1);
    if (hbmSrc2) DeleteObject(hbmSrc2);
    if (hbmDst)  DeleteObject(hbmDst);

    return FALSE;
}

Save Device Context into an uncompressed bitmap

// Function to save bitmap
BOOL SaveBitmap(HDC hDC,HBITMAP hBitmap,CString szPath)
{
    FILE * fp= NULL;
    fp = fopen(szPath.GetBuffer(1),"wb");
    if(fp == NULL)
        return false;
    
    BITMAP Bm;
    BITMAPINFO BitInfo;
    ZeroMemory(&BitInfo, sizeof(BITMAPINFO));
    BitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    BitInfo.bmiHeader.biBitCount = 0;

    if(!::GetDIBits(hDC, hBitmap, 0, 0, NULL, &BitInfo, DIB_RGB_COLORS))
        return (false);

    Bm.bmHeight = BitInfo.bmiHeader.biHeight;
    Bm.bmWidth  = BitInfo.bmiHeader.biWidth;

    BITMAPFILEHEADER    BmHdr;
    
    BmHdr.bfType        = 0x4d42;   // 'BM' WINDOWS_BITMAP_SIGNATURE
    BmHdr.bfSize        = (((3 * Bm.bmWidth + 3) & ~3) * Bm.bmHeight) 
                          + sizeof(BITMAPFILEHEADER) 
                          + sizeof(BITMAPINFOHEADER);
    BmHdr.bfReserved1    = BmHdr.bfReserved2 = 0;
    BmHdr.bfOffBits      = (DWORD) sizeof(BITMAPFILEHEADER) 
                          + sizeof(BITMAPINFOHEADER);
    
    BitInfo.bmiHeader.biCompression = 0;
    // Writing Bitmap File Header ////
    fwrite(&BmHdr,sizeof(BITMAPFILEHEADER),1,fp);

    fwrite(&BitInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);

    BYTE *pData = new BYTE[BitInfo.bmiHeader.biSizeImage + 5];
    if(!::GetDIBits(hDC, hBitmap, 0, Bm.bmHeight, 
                 pData, &BitInfo, DIB_RGB_COLORS))
        return (false);
    if(pData != NULL)
        fwrite(pData,1,BitInfo.bmiHeader.biSizeImage,fp);

    fclose(fp);
    delete (pData);

    return (true);
}

// here is how to use the above function

//Get the device context
HDC hDC = ::GetDC(hWnd);
// Create a memory device context
HDC hMemDC = ::CreateCompatibleDC(hDC);
// Create a compatible bitmap 
HBITMAP hBitmap = CreateCompatibleBitmap(hDC, 
                 nScreenWidth,nScreenHeight);
// Select the bitmap into the memory context
::SelectObject(hMemDC,hBitmap);    
// Do what ever drawing you want into the Device Context
...
...
SaveBitmap(hMemDC, hBitmap,"Sample.bmp");

Points of Interest

SetStretchBltMode(hDC,HALFTONE)

Try out this function, this improves the quality of StretchBlt(). I think with our using this mode, SretchBlt() function cannot give you the required quality if you are dealing with big bitmaps.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Arun krishnan
Software Developer (Senior) Tata Elxsi Ltd
India India
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionHow to display Window 7? Pin
dinh_vu_vt200523-Feb-11 20:54
memberdinh_vu_vt200523-Feb-11 20:54 
AnswerRe: How to display Window 7? Pin
goriofab20098-Jan-14 1:50
membergoriofab20098-Jan-14 1:50 
RantHelp Pin
Steve Noll18-Aug-10 0:49
memberSteve Noll18-Aug-10 0:49 
GeneralRe: Help Pin
Arun krishnan20-Aug-10 7:10
memberArun krishnan20-Aug-10 7:10 
QuestionHow can i put the month and a year? Pin
allan paglinawan14-Mar-09 3:32
memberallan paglinawan14-Mar-09 3:32 
QuestionThe code does not support unicode ? Pin
To Quang Hiep5-Oct-08 6:16
memberTo Quang Hiep5-Oct-08 6:16 
GeneralSaveBitmap Function NOTWorking Pin
Gaurang Shah 03331-Aug-07 19:31
memberGaurang Shah 03331-Aug-07 19:31 
GeneralRe: SaveBitmap Function NOTWorking Pin
Arun krishnan1-Sep-07 16:24
memberArun krishnan1-Sep-07 16:24 
QuestionSaveBitmap Pin
Member #7468617-Mar-07 10:33
memberMember #7468617-Mar-07 10:33 
AnswerRe: SaveBitmap Pin
Arun krishnan17-Aug-07 6:11
memberArun krishnan17-Aug-07 6:11 
GeneralmEMORYYY Pin
mircea13131324-Aug-06 7:08
membermircea13131324-Aug-06 7:08 
Generalnice one Pin
seishin6663-Jun-06 0:32
memberseishin6663-Jun-06 0:32 
GeneralPlease give me some directions about advanced functions Pin
u852100127-Jan-05 16:23
memberu852100127-Jan-05 16:23 
GeneralHighlighting Current Date... Pin
Vali_Ali22-Aug-04 20:04
memberVali_Ali22-Aug-04 20:04 
GeneralVery cool code Pin
DanYELL17-May-04 16:19
memberDanYELL17-May-04 16:19 
Generaldifferent language Pin
CuriousInCrossLanguageDeveloper19-Mar-04 20:43
sussCuriousInCrossLanguageDeveloper19-Mar-04 20:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160621.1 | Last Updated 5 Mar 2004
Article Copyright 2004 by Arun krishnan
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid