I've tried to clean down this code so that it will demonstrate my problem but
contains little else. Just enough to make a window. This code will compile on
"BCC32" or "cl". I can't figure out why I get an "Invalid handle error" when
trying to create a DIB. I'm running AMD, XP pack 1. I've included a little
snippet that will show you the returned handle. For me, it's always "0". I'm
missing some point but I can't see what.

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

    HDC hDC;
    void *ppvBits;
    HWND hwnd;
    MSG msg;
    WNDCLASS wc;
    HDC hDCDIB;

// ***********START********PROTOTYPES*****

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow);
LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);

// ***********END**********PROTOTYPES*****

   int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    (void)UNREFERENCED_PARAMETER(hPrevInstance);
    (void)UNREFERENCED_PARAMETER(lpCmdLine);
    (void)UNREFERENCED_PARAMETER(nCmdShow);


    wc.lpfnWndProc = (WNDPROC) WndProc;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon((HINSTANCE) NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszClassName = "DIB";

    if(!RegisterClass(&wc))
         return FALSE;

    hwnd = CreateWindowEx(NULL,wc.lpszClassName,"",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,
                        CW_USEDEFAULT, CW_USEDEFAULT,(HWND)0,(HMENU)0,hInstance,(LPVOID)0);
    if(!hwnd)
        return FALSE;
    
    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);
     
    while(GetMessage(&msg, (HWND)0, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }             

    return msg.wParam;
}                            // ********************* END WINMAIN

   LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)

{                            // ********************* START WNDPROC 1

   switch(message)
      {                        // ******************* START SWITCH

    case WM_CREATE:
     {

//--------------------------------- BITMAPINFO Page 370
   CONST BITMAPINFO *bmi; 
   BITMAPINFOHEADER bmiHeader;
   RGBQUAD bmiColors[1];
//---------------------------------- BITMAPINFOHEADER Page 364
   DWORD  biSize = (sizeof(BITMAPINFOHEADER)); 
   LONG   biWidth = 340; 
   LONG   biHeight = 255; 
   WORD   biPlanes = 1; 
   WORD   biBitCount = 24; 
   DWORD  biCompression = BI_RGB; 
   DWORD  biSizeImage; 
   LONG   biXPelsPerMeter; 
   LONG   biYPelsPerMeter; 
   DWORD  biClrUsed; 
   DWORD  biClrImportant;

   HBITMAP DIBFile;
   HDC hDC;
   void *ppvBits;

       hDC = GetDC(hwnd);

       DIBFile = CreateDIBSection(hDC,bmi,DIB_RGB_COLORS,&ppvBits,0,0);

                        char Mystring[4];
                        _snprintf (Mystring,6,"%X",DIBFile);
                   MessageBox(hwnd,Mystring,"MBOX1",MB_OK);

         break;
     }

    case WM_CLOSE:
    {
        PostQuitMessage(0);
        DestroyWindow(hwnd);
        return 0;
    } 

    default:
    return DefWindowProc(hwnd, message, wparam, lparam);
     }                                    // ****************** END SWITCH
    return (0);
}          // *********************************************** END WINPROC 1

/* ------------------------------------------ TESTING SUPPLIES
                        char Mystring[4];
                        _snprintf (Mystring,6,"%X",DIBFile);
                   MessageBox(hwnd,Mystring,"MBOX1",MB_OK);

    LPTSTR lpMsgBuf;
    FormatMessage( 
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR)(&lpMsgBuf),0,NULL);
    MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );  */

Recommended Answers

All 5 Replies

Please, please, use [[I][/I]code[I][/I]] blocks to post. Anything else leaves unreadable and difficult to cut/paste stuff. Also, this is the C++ forum, not C.

You misunderstand a few basic concepts.

1
Anything with const in front of it cannot be modified. You don't need it here, especially since you intend to modify the value (after all, you want to create a bitmap you can edit in memory, right?).

2
Anything that looks like foo *bar; creates a pointer to something. That something doesn't exist until you use malloc() to create it. In this case, you don't need it to be a pointer. Just say:

BITMAPINFO bmi;

Since the BITMAPINFO structure contains a BITMAPINFOHEADER, there is absolutely no need to create another.

3
Anything that looks like foo bar = baz; is a variable declaration and a variable assignment combined into one. That is, it is equivalent to the two statments: foo bar; (Create a variable named "bar" of type "foo") bar = baz; (Assign the value "baz" to the variable "bar")
You need to say:

bmi.bmiHeader.biSize  = sizeof( BITMAPINFOHEADER );
bmi.bmiHeader.biWidth = 340;
...

This begins assigning values to the various fields inside the BITMAPINFOHEADER struct of the BITMAPINFO variable.

4
CreateDIBSection() does not create a file. It creates a bitmap (in memory). If you want to write the bitmap to file, I recommend you to this article I googled.

5
Watch the types of your arguments. You should say my_dib = CreateDIBSection(hDC,[B]&bmi[/B],DIB_RGB_COLORS,&ppvBits,0,0); Hope this helps.

I have to admit I haven't mastered the method you guys want when including code. I back lit all the code and hit the button "Wrap code tags around code" found above. Last button on the right. Clue me in as to what other way to do it.

I didn't understand why you felt my code was in "C". It was written using Win32 API's in C++.

There is a Microsoft supplied item called WinHelp. In it there is about a thousand functions using the Win32 API functions. All of my functions and structures were pulled from there. I saw you placed "&bmi" in the CreateDIBSection function. That works if the structure does not have BITMAPINFO *bmp: BCC32 will let you know if you don't have the syntax right. Also, I copied the "CONST" from the WinHelp stuff. I've tried it with and without the "CONST" and still I don't get a good handle.

I haven't tried to allocate memory before calling CreateDIBSection. WinHelp gave me the impression that if I don't allocate, the system will allocate it for me. I'll give that a try tommorrow.

I almost forgot. If I use "bmi.bmiHeader.biWidth", BCC32 will fail. It will complain that bmi has already been declared. It also adds an error saying a structure must be left of a "." or a "->".

For code blocks. It is watermarked behind the text edit you get when posting.

Windows was written in C. Its API is in C. Every bit of your code is C. Most C++ compilers have windows header files (like <windows.h>) set up so that they can be use by both C and C++ programs, so even if you are compiling with C++ you are still only using C.
Since you have not used any C++ at all, I assumed that you were using C.

I know what the hell WinHelp is. I use it every day. I also have just about every piece of documentation about windows and the Win32 API. I suspect I have a fair deal better idea what is in there than you do. Further, I'm no C++ weenie. If you want help, you might want to consider that the people responding might know something about how to use the language.
If you had followed my instructions your compiler wouldn't have complained about &bmi. You have created a pointer to something, but that something does not exist. Until you create it, it never will. For what you want to do, you do not need to use a pointer.

The CreateDIBSection() function only allocates memory for the pixel data. It will not allocate your BITMAPINFO structure. Rather, it expects you to have one already, which it uses to properly allocate your pixel data.

Finally, I know something about C/C++ compiler error messages. I am glad to see you tried to compile your changes and took a look at them, but you have mis-read them. BCC32 will not fail if you don't declare bmi as a pointer. The error message you got is trying to tell you that since you declared bmi as a pointer, you must access its members with the pointer dereference operator: bmi->bmiHeader.biWidth .

I don't know of anyone here who likes to spend their time to un-help others. Please try to curb the bitumen if you are still having trouble. You'll be much more likely to get good help that way.

Prior to sending such a large block of code, I re-read the thread on
enclosing my code in code and /code. When back lighting my code
and hitting the provided button which I assumed would complete the
job, I did not back light the [] items which I had typed in. I later
deleted those since the code was in yellow blocks.
Would backlighting them and leaving them in have done the job?

For folks that are not familiar with what you want, a nice step by
step would help. One other time that I sent a small piece of code,
I did not do it right and one of the narrators said, back light the
code and hit "#". Some time has passed since then. I didn't see a "#"
button, but the tool help message read, "Wrap code tags around code"
which appeared to be what you wanted. I guess it wasn't.

Incidently, I just used the word "code" with [] and learned how to put
the yellow backing behind code. (The reason for this edit.)

It seems I stepped on your toes explaining that I got some of my
code from WinHelp. We're even. You explained to me that
CreateDIBSection creates a bitmap, not a file. My typedef for the
name I chose for my CreateDIBSection clearly reads (HBITMAP DIBFile;).
I just grabbed a name off the top of my head for that one. Sorry
I confused you. DIBBitmap seemed a bit long at the time.

I haven't yet allocated memory for my bitmap. I used the time to
reply to this exchange instead. I have a gut feeling that it
will be the answer. In searching for where I got the "*bmi" from in my
code, I stumbled across "Opening and displaying a bitmap file" in
WinHelp. They do allocate memory for the bitmap in that.

Before I ask for help when having a problem, I search for code
others have written to see how they have done things. I thought
I had set up my BITMAPINFO structure verbatum from WinHelp. I didn't.
I must have copied *bmi" from some code I read on line.

I have long struggled understanding how to use "->" in my code.
Your explanation did help make it clearer why BCC32
keeps rejecting my use of this operator.

Hey there toolmanx, sorry to have responded so angrily. I was going to post and ask if you'd figure it out but I see you've marked it 'solved'.

C (and C++) is a weird and multi-headed beast. It is often easy to shoot yourself in places you didn't know you had --especially when looking through the MS documentation.

Since you were having trouble with pointers and structures, you might want to google "c pointers" and "c struct" for lots of good reading.

For C++, a couple of my favorite sites are:
C++ FAQ Lite
Incompatabilities Between ISO C and ISO C++
The second is useful if you really want to know how things work inside the language.

I hope I haven't driven you away from DaniWeb and you still feel you can post here for help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.