I am still learning to program Native Windows and the GDI. I am wanting to make a simple picture viewer. Here is what I have. These two cases are in seperate switch statements. I didn't want to post the whole program for obvious reasons.
@ rajenipcv should you call the invalidate function while you are in the middle of handling a WM_PAINT message?
The WM_PAINT message is sent in response to one or more calls to the invalidation functions. If you immediately invalidate what you just drew, you'll only put your application into a time-consuming cycle of constant repainting.
I don't actually see anything wrong with your painting. At the end of the OPEN_FILE case you properly call InvalidateRect() and even UpdateWindow() (though the second isn't strictly necessary --but don't take it out ;-)
The problem comes from the use of LoadBitmap(). That function only loads resources linked into the executable. It won't load files. :-O Yep. Only linked resources. Hence, the resource fails to load and any attempt to draw NULL in WM_PAINT fails.
Probably the simplest fix is to use the LoadImage() function. However, it doesn't work on Windows NT, so I'll recommend you take the effort to load it properly. (It also has a bug or two involving transparent colors.) You would think that the Win32 API would provide a function to do this for us...
Basically you have to extract and assemble the bitmap yourself. Unfortunately there isn't a whole lot of straight-forward information about this on the internet, so here's a little function to do it for you.
HBITMAP BMPLoadFromFile( LPCTSTR filename )
HBITMAP result = 0;
/* Open the bitmap file */
f = CreateFile(
NULL, /* no security attributes: handle cannot be inherited */
FILE_FLAG_SEQUENTIAL_SCAN, /* optimize for how we'll use the file */
if (f == INVALID_HANDLE_VALUE) return 0;
/* Read and validate the bitmap file header */
ok = ReadFile( f, (LPVOID)&bmFH, sizeof( BITMAPFILEHEADER ), &count, NULL );
if (!ok || (count != sizeof( BITMAPFILEHEADER )) || (bmFH.bfType != 0x4D42))
/* Get the size of the bitmap structure */
size = GetFileSize( f, NULL );
if (size == 0xFFFFFFFF) goto done_file;
size -= sizeof( BITMAPFILEHEADER );
/* And try to allocate and load it */
g = GlobalAlloc( GHND, size );
if (g == NULL) goto done_file;
p = GlobalLock( g );
if (p == NULL) goto done_global;
ok = ReadFile( f, p, size, &count, NULL );
if (!ok || (count != size)) goto done_global;
/* OK, now we can get down to business and turn our data into an HBITMAP */
dc = GetDC( NULL );
if (dc == NULL) goto done_global;
result = CreateDIBitmap(
(LPVOID)((CHAR*)p +bmFH.bfOffBits), /* don't assume packed .bmp */
ReleaseDC( NULL, dc );
done_global: GlobalFree( g );
done_file: CloseHandle( f );
If it fails to load you'll get back NULL. Otherwise be sure to dispose of the HBITMAP you get from this using DeleteObject(). And of course you are linking with libgdi32, right?
Thirdly, if you want to take issue with something, don't just whine and complain. Either suggest something better and correct or link to something that does.
It appears that the latest MSDN LoadImage documentation has removed the caveat about LR_LOADFROMFILE (see http://msdn.microsoft.com/en-us/library/ms648045.aspx ) and a quick check with Google advised me that some people report that NT versions as old as 3.51 work just fine with it. Given the MSDN info, I suspect that Microsoft may have fixed it with a service pack.
> Probably the simplest fix is to use the LoadImage() function. However, it doesn't work on Windows NT,
What is this Bullshit ?
Sadly, Thats a typical unhelpful response I would expect from him Duoas. It's entirely feasible someone is doing work on WindowsNT at a university or polytechnic somewhere. Or even an in organisation (banks are shockers for old OS's).
That's funny because I have a fairly extensive collection of Microsoft's own help files on my harddisk. The danger with MSDN is that Microsoft is notorious for modifying their documentation to represent the current state of things without any respect for past states.
It has always worked on NT >= 3.51, for 13 years...
If some past employee on the Redmond documentation team felt it noteworthy to indicate that LoadImage() cannot do LR_LOADFROMFILE on Windows NT, then it is better to code against the possibility that someone, somewhere may have an ancient, unpatched, dysfunctional version of NT where LoadImage() will fail to load a BMP from file --no matter how many instances can be found where it works without problem. Anectdotal evidence is not proof of anything.
I have not personally experienced any problems with LoadImage( ... LR_LOADFROMFILE ) either. But then again, I have never used NT. If the OP can guarantee that his target audience is using 4.7x or greater then there isn't any problem. But if he can't, then he should code appropriately. That's all.