Thread: CreateDIBSection() returning NULL

  1. #1
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203

    Question CreateDIBSection() returning NULL

    Don't know what happened... But it WORKS NOW Thanks.
    The CreateDIBSection() function that I'm learning is not working. I have tried to closely follow the codes in many tutorials
    and Peztold but its not working. May be I'm missing something.
    Here is the error and a reduced version showing the same problem.
    Code:
    Error got from 'GetLastError()' :The specified image type cannot be found in the image file.
    But I'm not using any image file ! Am I missing something ?
    I tried many webpages on CreateDIBSection() and tried to closely follow them.
    Code:
    #include<windows.h>
    
    const unsigned long WIDTH = 384, HEIGHT = 256;        //dimensions of the bitmap.
    
    inline void GetLastErrorMessage(){          //Formats GetLastError() value.
        LPVOID lpMsgBuf;
    
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
            NULL, GetLastError(),
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
            (LPTSTR) &lpMsgBuf, 0, NULL
        );
    
        // Display the string.
        MessageBox( NULL, (const char*)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
    
        // Free the buffer.
        LocalFree( lpMsgBuf );
    
    }
    
    LRESULT CALLBACK MainProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){
    static HBITMAP hBitmap;
    static BITMAPINFOHEADER bmiHeader;
    static HDC hMem;
    static void *bits;                         //holds bitmap pixels.
    static bool EveryThingIsRight = true;
    
        switch(Msg){
            case WM_CREATE:
            {
                GetLastErrorMessage();      //To make sure NO error happned before.
    
                //a memory device context compatible with the screen to select the bitmap for BitBlting.
                hMem = CreateCompatibleDC(NULL);
    
                if( !hMem ){
                    MessageBox(hWnd, "Memory Device Context could not be Created !",
                               "ERROR", MB_ICONERROR | MB_OK);
                    EveryThingIsRight = false;
                    GetLastErrorMessage();
                }
    
                bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                bmiHeader.biWidth  = WIDTH;
                bmiHeader.biHeight = HEIGHT;
                bmiHeader.biPlanes = 1;
                bmiHeader.biBitCount    = 24;
                bmiHeader.biCompression = BI_RGB;
                bmiHeader.biSize          = 0;
                bmiHeader.biXPelsPerMeter = 0;
                bmiHeader.biYPelsPerMeter = 0;
                bmiHeader.biClrUsed       = 0;
                bmiHeader.biClrImportant  = 0;
    
    
                hBitmap = CreateDIBSection(hMem, (BITMAPINFO*)&bmiHeader,
                                           DIB_RGB_COLORS,
                                           &bits, NULL, 0);
                if( !hBitmap ){
                    MessageBox(hWnd, "DIB section could not be created !",
                               "ERROR", MB_ICONERROR | MB_OK);
                    EveryThingIsRight = false;
                    GetLastErrorMessage();
                }
    
                if( !SelectObject(hMem, hBitmap) ){
                    MessageBox(hWnd, "DIB section could not be Selected !",
                               "ERROR", MB_ICONERROR | MB_OK);
                    EveryThingIsRight = false;
                    GetLastErrorMessage();
                }
            }
            break;
    
            case WM_PAINT:
            {
                //if( ! EveryThingIsRight )         //If HDc && hBitmap is allright.
                    //break;
                PAINTSTRUCT ps;
                RECT sc;
    
                GetClientRect(hWnd, &sc);
                HDC hdc = BeginPaint(hWnd, &ps);
    
                BitBlt(hdc, 0, 0, sc.right, sc.bottom, hMem, 0, 0, SRCPAINT);
    
                EndPaint(hWnd, &ps);
                return 0;
            }
            break;
    
            case WM_DESTROY:
                DeleteDC(hMem);
                DeleteObject(hBitmap);
    
                PostQuitMessage(0);
            break;
        }
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPI, LPSTR CmdL, int nCmdS)
    {
        WNDCLASSEX WndCls;
    
        WndCls.cbSize = sizeof(WNDCLASSEX);
        WndCls.style  = 0;
        WndCls.lpfnWndProc = MainProc;
        WndCls.cbClsExtra  = 0;
        WndCls.cbWndExtra  = 0;
        WndCls.hInstance   = hInstance;
        WndCls.hIcon   = LoadIcon(NULL, IDI_WINLOGO);
        WndCls.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
        WndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
        WndCls.hbrBackground = HBRUSH( COLOR_3DFACE + 1);
        WndCls.lpszMenuName  = NULL;
        WndCls.lpszClassName = "MainClass";
    
        if( !RegisterClassEx(&WndCls) ){
            return 1;
        }
    
        HWND hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, "MainClass", "Preview Window",
                                   WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                                   CW_USEDEFAULT, CW_USEDEFAULT,
                                   500, 500,
                                   NULL, NULL, hInstance, NULL);
        if( !hWnd ){
            return 1;
        }
    
        MSG Msg;
    
        while( GetMessage(&Msg, NULL, 0, 0) > 0 ){
            if( IsDialogMessage(hWnd, &Msg) )
                continue;
    
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
    
    return 0;
    }
    MSDN says that CreateDIBSection() returns only one type of error:
    May be I should concentrate on that and proceed.
    Code:
    Windows NT/2000/XP: To get extended error information, call GetLastError. This can be the following value.
    Value 	Meaning
    ERROR_INVALID_PARAMETER 	One or more input parameters is invalid.
    Last edited by arjunajay; 07-25-2006 at 10:55 PM.

  2. #2
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Code:
    static void *bits
    This needs to hold some sort of data (ARGB Data) before you make a DIB out of it.
    Founder and avid member of the Internationsl Typo Associateion

  3. #3
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Code:
               bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                bmiHeader.biWidth  = WIDTH;
                bmiHeader.biHeight = HEIGHT;
                bmiHeader.biPlanes = 1;
                bmiHeader.biBitCount    = 24;
                bmiHeader.biCompression = BI_RGB;
                bmiHeader.biSizeImage          = 0;
                bmiHeader.biXPelsPerMeter = 0;
                bmiHeader.biYPelsPerMeter = 0;
                bmiHeader.biClrUsed       = 0;
                bmiHeader.biClrImportant  = 0;
    When you are manipulating the bits of your dib section, remember that a 24bit bitmap is DWORD padded. For this reason, you may consider using a 32bit dib section as indexing is easier.

  4. #4
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203

    Unhappy

    Quote Originally Posted by Mastadex
    Code:
    static void *bits
    This needs to hold some sort of data (ARGB Data) before you make a DIB out of it.
    But the book and the pages say that the OS returns a pointer to allocated data.
    And some code I found in peztold's and many web pages don't allocate memory themselves.

    And as for 32 bits, this was just an example. It is the user who supplies the source bitmap. and I will later change it to 32bits. Besides that I work with very large bitmaps so 24 vs 32 provides a large size difference.

  5. #5
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203

    Unhappy

    Quote Originally Posted by anonytmouse
    Code:
               bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                bmiHeader.biWidth  = WIDTH;
                bmiHeader.biHeight = HEIGHT;
                bmiHeader.biPlanes = 1;
                bmiHeader.biBitCount    = 24;
                bmiHeader.biCompression = BI_RGB;
                bmiHeader.biSizeImage          = 0;
                bmiHeader.biXPelsPerMeter = 0;
                bmiHeader.biYPelsPerMeter = 0;
                bmiHeader.biClrUsed       = 0;
                bmiHeader.biClrImportant  = 0;
    When you are manipulating the bits of your dib section, remember that a 24bit bitmap is DWORD padded. For this reason, you may consider using a 32bit dib section as indexing is easier.
    The page that you linked gives unallocated null pointer unlike mastadex said
    My brain hurts... <

    ************EDIT**************
    This isn't fair. I copied and pated the code in that link and IT WORKS!
    Except for some minor differences, I can't find anything that is REALLY different.
    Code:
    BITMAPINFO bmp   = { 0 };     // changed this to Zeromemory later because this gave a warning.
        DWORD*     pBits = NULL;   // in my code this was void*
        HBITMAP    hBmp  = NULL;
        HDC        hdcMem = NULL;
    
        bmp.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
        bmp.bmiHeader.biWidth       = WIDTH;
        bmp.bmiHeader.biHeight      = HEIGHT;
        bmp.bmiHeader.biPlanes      = 1;
        bmp.bmiHeader.biBitCount    = 32;
        bmp.bmiHeader.biCompression = BI_RGB;
    
        hBmp = CreateDIBSection(NULL, &bmp, DIB_RGB_COLORS, &pBits, NULL, 0);
        hdcMem = CreateCompatibleDC(NULL);
        SelectObject(hdcMem, hBmp);
    Last edited by arjunajay; 07-25-2006 at 08:39 PM.

  6. #6
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Code:
    bmiHeader.biBitCount = 24;
    I always had a problem with 24 bit bitmaps. I tried for days on end to get it working...try 32 bit just for testing purposes?
    Founder and avid member of the Internationsl Typo Associateion

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. "Virtual Printer" or "Moving Printjobs"
    By extasic in forum Windows Programming
    Replies: 12
    Last Post: 06-30-2011, 08:33 AM
  2. Global Variables
    By Taka in forum C Programming
    Replies: 34
    Last Post: 11-02-2007, 03:25 AM
  3. Compiling 3rd party code problem me too
    By siavoshkc in forum C Programming
    Replies: 1
    Last Post: 09-12-2007, 05:55 AM
  4. . . . . . . - . . . - -
    By The Brain in forum C++ Programming
    Replies: 17
    Last Post: 05-17-2005, 04:01 AM
  5. Replies: 3
    Last Post: 03-04-2005, 02:46 PM