Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8284573
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T11:09:19+00:00 2026-06-08T11:09:19+00:00

I write this simple code for saving bitmap to file (*.bmp) from HWND. #include

  • 0

I write this simple code for saving bitmap to file (*.bmp) from HWND.

#include <stdio.h>
#include <windows.h>

bool captureAndSave(const HWND& hWnd, int nBitCount, const char* szFilePath)
{
    if(!szFilePath || !strlen(szFilePath))
    {
        printf("bad function arguments\n");
        return false;
    }

    //calculate the number of color indexes in the color table
    int nColorTableEntries = -1;
    switch(nBitCount) 
    {
        case 1:
            nColorTableEntries = 2;
            break;
        case 4:
            nColorTableEntries = 16;
            break;
        case 8:
            nColorTableEntries = 256;
            break;
        case 16:
        case 24:
        case 32:
            nColorTableEntries = 0;
            break;
        default:
            nColorTableEntries = -1;
            break;
    }

    if(nColorTableEntries == -1)
    {
        printf("bad bits-per-pixel argument\n");
        return false;
    }

    HDC hDC = GetDC(hWnd);
    HDC hMemDC = CreateCompatibleDC(hDC);

    int nWidth = 0;
    int nHeight = 0;

    if(hWnd != HWND_DESKTOP)
    {
        RECT rect;
        GetClientRect(hWnd, &rect);
        nWidth = rect.right - rect.left;
        nHeight = rect.bottom - rect.top;
    }
    else
    {
        nWidth = ::GetSystemMetrics(SM_CXSCREEN);
        nHeight = ::GetSystemMetrics(SM_CYSCREEN);
    }


    HBITMAP hBMP = CreateCompatibleBitmap(hDC, nWidth, nHeight);
    SelectObject(hMemDC, hBMP);
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, hDC, 0, 0, SRCCOPY);

    int nStructLength = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries;
    LPBITMAPINFOHEADER lpBitmapInfoHeader = (LPBITMAPINFOHEADER)new char[nStructLength];
    ::ZeroMemory(lpBitmapInfoHeader, nStructLength);

    lpBitmapInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
    lpBitmapInfoHeader->biWidth = nWidth;
    lpBitmapInfoHeader->biHeight = nHeight;
    lpBitmapInfoHeader->biPlanes = 1;
    lpBitmapInfoHeader->biBitCount = nBitCount;
    lpBitmapInfoHeader->biCompression = BI_RGB;
    lpBitmapInfoHeader->biXPelsPerMeter = 0;
    lpBitmapInfoHeader->biYPelsPerMeter = 0;
    lpBitmapInfoHeader->biClrUsed = nColorTableEntries;
    lpBitmapInfoHeader->biClrImportant = nColorTableEntries;

    DWORD dwBytes = ((DWORD) nWidth * nBitCount) / 32;
    if(((DWORD) nWidth * nBitCount) % 32) {
        dwBytes++;
    }
    dwBytes *= 4;

    DWORD dwSizeImage = dwBytes * nHeight;
    lpBitmapInfoHeader->biSizeImage = dwSizeImage;

    LPBYTE lpDibBits = 0;
    HBITMAP hBitmap = ::CreateDIBSection(hMemDC, (LPBITMAPINFO)lpBitmapInfoHeader, DIB_RGB_COLORS,  (void**)&lpDibBits, NULL, 0);
    SelectObject(hMemDC, hBitmap);
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, hDC, 0, 0, SRCCOPY);
    ReleaseDC(hWnd, hDC);

    BITMAPFILEHEADER bmfh;
    bmfh.bfType = 0x4d42;  // 'BM'
    int nHeaderSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries;
    bmfh.bfSize = 0;
    bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries;    

    FILE *pFile = 0;
    fopen_s(&pFile, szFilePath, "wb");
    if(!pFile)
    {
        ::DeleteObject(hBMP);
        ::DeleteObject(hBitmap);
        delete[]lpBitmapInfoHeader;
        printf("can not open file\n");
        return false;   
    }

    DWORD nColorTableSize = 0;
    if (nBitCount != 24)
        nColorTableSize = (1 << nBitCount) * sizeof(RGBQUAD);
    else
        nColorTableSize = 0;


    fwrite(&bmfh, sizeof(BITMAPFILEHEADER), 1, pFile);
    fwrite(lpBitmapInfoHeader, nHeaderSize,1,pFile);

    if(nBitCount < 16)
    {
        int nBytesWritten = 0;
        RGBQUAD *rgbTable = new RGBQUAD[nColorTableEntries * sizeof(RGBQUAD)];
        //fill RGBQUAD table and write it in file
        for(int i = 0; i < nColorTableEntries; ++i)
        {
            rgbTable[i].rgbRed = rgbTable[i].rgbGreen = rgbTable[i].rgbBlue = i;
            rgbTable[i].rgbReserved = 0;

            fwrite(&rgbTable[i], sizeof(RGBQUAD), 1, pFile);
        }
        delete[]rgbTable;

        /*
        RGBQUAD rgb;
        for (DWORD i = 0; i < nColorTableEntries ; i++)
        {
            rgb.rgbBlue = rgb.rgbGreen = rgb.rgbRed = (BYTE)(i*(255/(nColorTableEntries-1)));
            nBytesWritten = fwrite(&rgb, 1, sizeof(rgb), pFile);
            if (nBytesWritten != sizeof(rgb)) 
            {
                printf("error while writing rgb header\n");
                fclose(pFile);

                ::DeleteObject(hBMP);
                ::DeleteObject(hBitmap);
                delete[]lpBitmapInfoHeader;

                return false;
            }
        }
        */
    }

    fwrite(lpDibBits, dwSizeImage, 1, pFile);

    fclose(pFile);

    ::DeleteObject(hBMP);
    ::DeleteObject(hBitmap);
    delete[]lpBitmapInfoHeader;
}

int main(int argc, char **argv)
{
    captureAndSave(HWND_DESKTOP, 1,  "1.bmp");
    captureAndSave(HWND_DESKTOP, 4,  "4.bmp");
    captureAndSave(HWND_DESKTOP, 8,  "8.bmp");
    captureAndSave(HWND_DESKTOP, 16, "16.bmp");
    captureAndSave(HWND_DESKTOP, 24, "24.bmp");
    captureAndSave(HWND_DESKTOP, 32, "32.bmp");

    return 0;
}

Images are saved properly for 32, 24 and 16 bits per pixel. But for 8, 4 and 1 bits per pixel image contains only black pixels.

Please tell me what I’m doing wrong.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T11:09:20+00:00Added an answer on June 8, 2026 at 11:09 am

    When GDI copies images to an indexed surface, it needs to map the colors it has on the source to colors available on the destination.

    Until, and unless, you create and select a palette into the destination DC, GDI won’t know what colors are available, and will map the colors using the default palette, which will define black and white only.

    The could be quite a lot involved in this – ideally you’d want to scan the source image, create a map of all the colors used and their freqencies and use that to compute an ideal palette.

    Or, just use CreateHalfTonePalette.

    In your case, you are blitting onto a DIBSection with the required bit depth, so you need to initialize the DIBSections color-table before performing the blit.
    iirc, When blitting to a DIB Section, having the DIBSections color table setup is more important than selecting an HPALETTE into the DC – but you can use the palette created by CreateHalfTonePalette, and extract the resulting color table.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to write a simple tool using Shoes. This will indent code
I'm trying to retrieve folders name from a zip file. I wrote this simple
I wrote this simple C code and compiled it using Visual Studio 2010, with
I've wrote this simple piece of code. And I have a slight problem with
Can someone write some sample code to explain this concept? I know what a
I want to load this simple something into my Editor: Write:-repeat,write(hi),nl,fail. So that it
This is for Play! Framework 2.0. I'm trying to write a simple test case
I usually write java code using a simple text editor and .bat files to
I am tinkering with the code for this new notification I'm trying to write.
I want to use the SaveFileDialog in the code behind to write a file

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.