-1

I have a call to CreateDIBSection() which is returning 0. The documentation says that this means that "One or more of the input parameters is invalid" but there is no indication of which parameter is invalid.

I had a look that this SO question in which the question ends with "after CreateDIBSection I found the error code is 8, no enough resource" - this confused me - there is no mention of any error codes in the documentation. How did the the poster get this extra information?

EDIT: As requested, here is my code - I must apologise it is not complete - it is part of a huge program, and making a minimal winapi program is not trivial.

HDC hdcTemp;
BYTE* bitPointer;

hdcTemp = CreateCompatibleDC(hdc_desktop);

my_printf("GetDeviceCaps(hdcTemp,BITSPIXEL) = %d\n",GetDeviceCaps(hdcTemp,BITSPIXEL)); // this prints "32"

static BITMAPINFO bitmap;

bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = 280;
bitmap.bmiHeader.biHeight = height_to_check;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 32;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = 280 * 4 * height_to_check;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;

HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
Mick
  • 8,284
  • 22
  • 81
  • 173
  • Use GetLastError(). As a sidenote when I used this loooong time ago, this API is extremely unfriendly and unstable across windows versions. GDI+ was way nicer. – rAndom69 May 13 '19 at 16:23
  • 1
    GDI functions like CreateDIBSection do not set the last error code. So using GetLastError() is quite incorrect and you're liable to get an error code from a previous or internal winapi call. – Hans Passant May 13 '19 at 16:25
  • GetLastError() returns 0 anyway. – Mick May 13 '19 at 16:29
  • They are not documented as returning error, however on some failures they do change it. – rAndom69 May 13 '19 at 16:29
  • Seems that the issue of error codes with this function is a bit messy: see here https://stackoverflow.com/questions/40847415/createdibsection-return-value-vs-error – Mick May 13 '19 at 16:36
  • There would not be a way to get information which parameter is incorrect anyway. Those errors were in line of "Not enough resources/Invalid parameter/Fatal". Usually error IIRC was related to incompatible DC so I would experiment with color resolution or offscreen DC. – rAndom69 May 13 '19 at 16:44
  • See: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems). See also: [mcve]. – Jesper Juhl May 13 '19 at 17:01
  • Post your code. – jwezorek May 13 '19 at 17:14
  • Making a [mcve] is perfectly possible, it just requires a little more effort – David Heffernan May 13 '19 at 18:13
  • @jes: How is a debugger going to help here? All it can do is tell you what you already know: A library call failed, and that library doesn't report any additional error information. – IInspectable May 13 '19 at 18:56
  • @IInspectable with a debugger, you could step into the library call and work out what it trying to do internally, maybe find an internal function with known parameters that is the failure point, etc. – Remy Lebeau May 13 '19 at 20:43
  • @rem: The link posted refers to source level debugging only. Stepping into a library for which you do not have access to source code isn't even addressed in that Q&A. Sure, a debugger can help, but the link posted certainly doesn't. – IInspectable May 13 '19 at 21:58
  • 1
    What is the value of height_to_check? This seems to be related to bitmap size. Try using small bitmaps. – Strive Sun May 14 '19 at 07:30
  • @Strive Sun: that was the right answer - I found that it could sometimes be 0. When it was set to the correct value the (original) code worked just fine. Thank you. – Mick May 15 '19 at 13:34

2 Answers2

1

change to

BYTE* bitPointer;
HDC hdcScreen = GetDC(NULL);
static BITMAPINFO bitmap;

bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = 280;
bitmap.bmiHeader.biHeight = height_to_check;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 32;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = 280 * 4 * height_to_check;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;

HBITMAP hBitmap2 = CreateDIBSection(hdcScreen, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
ReleaseDC(NULL, hdcScreen);

i.e. don't pass an HDC returned from CreateCompatibleDC to CreateDIBSection; use the device context of the screen.

Calling CreateCompatibleDC creates the device context with a 1x1 monochrome bitmap associated with it no matter what HDC you passed in so when you create a bitmap or DIB section compatible to that HDC Win32 tries to be compatible with the monochrome bitmap which you dont want.

jwezorek
  • 8,592
  • 1
  • 29
  • 46
-1

At present, MSDN points out that "one or more input parameters are invalid" is reasonable. Tests show that if the bitmap size is too large or the input value is invalid, such as zero, NULL will be returned.

Strive Sun
  • 5,988
  • 1
  • 9
  • 26