Search code examples
cbitmapscreenshottakesscreenshot

Invalid initializer when creating a BITMAP in C


I am trying to make a program that takes a screen shot and saves it, till now it only saves it into a variable (hbCapture). Although the code seems write and I've read several times the documentation, it gives me a invalid initializer error in the creation of the BITMAP.

#include <stdlib.h>
#include <windows.h>
#include <stdbool.h>
#include <wingdi.h>
#include <winuser.h>

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef unsigned long long u64;

void getScreen()
{
    u16 screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    u16 screenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);

    HDC hdc = GetDC(NULL); //get a desktop dc (NULL for entire screen)
    HDC hDest = CreateCompatibleDC(hdc); //create a dc for capture

    BITMAP hbCapture = CreateCompatibleBitmap(hdc, screenWidth, screenHeight);
    SelectObject(hDest, hbCapture);

    //Copy screen to bitmap
    BitBlt(hDest, 0, 0, screenWidth, screenHeight, hdc, 0, 0, SRCCOPY);

    //Clean up
    ReleaseDC(NULL, hdc);
    DeleteDC(hDest);
}

This is the header where the function goes

And here is the main.c

#include "main.h"

int main()
{
    getScreen();

    return 0;
}

--------------------------I've also tryed this and doesn't work--------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <stdbool.h>
#include <wingdi.h>
#include <winuser.h>

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef unsigned long long u64;

void getScreen()
{
    u16 screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    u16 screenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);

    HDC hdc = GetDC(NULL); //get a desktop dc (NULL for entire screen)
    HDC hDest = CreateCompatibleDC(hdc); //create a dc for capture

    //test
    ReleaseDC(NULL, hdc);
    //DeleteDC(hdc);
    //test

    BITMAP bCapture = CreateCompatibleBitmap(hdc, screenWidth, screenHeight);
    HBITMAP hbCapture = CreateBitmapIndirect(&bCapture);
    SelectObject(hDest, hbCapture);

    //Copy screen to bitmap
    BitBlt(hDest, 0, 0, screenWidth, screenHeight, hdc, 0, 0, SRCCOPY);

    //Clean up
    ReleaseDC(NULL, hdc);
    DeleteDC(hDest);
}


Solution

  • See documentation for CreateCompatibleBitmap

    It says the return value is HBITMAP, not BITMAP

    Change to:

    HBITMAP hbCapture = CreateCompatibleBitmap(hdc, screenWidth, screenHeight);
    

    Remove CreateBitmapIndirect

    You then need to GetDIBits to save the bitmap header and pixels in to file.

    Also include DeleteObject(hbCapture) at the end of the code for cleanup.