Jump to content
  • Advertisement
Sign in to follow this  

Windows Bitmap Problem

This topic is 4883 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Below is the code for a simple program I've put together. This is essentially the code Bricks1 from Petzold 5th edition. I also have a BMP file and a resource file referring to the BMP file. All the names for the BMP resource seem to be OK, however, I get an error every time I run this: "The specified resource name cannot be found in the image file." Any ideas?? -Kirk I added the contents of the resource file (Script1.rc). bitmap1.bmp is present in the project's base directory.
#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
				   PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName [] = TEXT ("TestBMP");
	HWND hwnd;
	MSG	msg;
	WNDCLASS wndclass;

	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc=WndProc;
	wndclass.cbClsExtra=0;
	wndclass.cbWndExtra=0;
	wndclass.hInstance=hInstance;
	wndclass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
	wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.lpszMenuName=NULL;
	wndclass.lpszClassName=szAppName;

	if (!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT("This program requires WinNT!"), szAppName, MB_ICONERROR);
		return 0;
	}
	hwnd=CreateWindow(szAppName, TEXT("Test Bitmap"),
					  WS_OVERLAPPEDWINDOW,
					  CW_USEDEFAULT, CW_USEDEFAULT,
					  CW_USEDEFAULT, CW_USEDEFAULT,
					  NULL, NULL, hInstance, NULL);

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);
	
	while (GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HBITMAP hBitmap;
	static int cxClient, cyClient, cxSource, cySource;
	BITMAP bitmap;
	HDC hdc, hdcMem;
	HINSTANCE hInstance;
	int x,y;
	PAINTSTRUCT ps;

	LPVOID lpMsgBuf;

	switch(message)
	{
	case WM_CREATE:
		hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
		hBitmap = LoadBitmap(hInstance, TEXT("TestBMP"));
		if (hBitmap == NULL) 
		{
			FormatMessage( 
							FORMAT_MESSAGE_ALLOCATE_BUFFER | 
							FORMAT_MESSAGE_FROM_SYSTEM | 
							FORMAT_MESSAGE_IGNORE_INSERTS,
							NULL,
							GetLastError(),
							0, // Default language
							(LPTSTR) &lpMsgBuf,
							0,
							NULL 
						);
			MessageBox (NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);

		}
		GetObject(hBitmap, sizeof(BITMAP), &bitmap);
		cxSource=bitmap.bmWidth;
		cySource=bitmap.bmHeight;
		return 0;

	case WM_SIZE:
		cxClient = LOWORD(lParam);
		cyClient = HIWORD(lParam);
		return 0;

	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		hdcMem = CreateCompatibleDC(hdc);
		SelectObject(hdcMem, hBitmap);
		for (y=0; y<cyClient; y+=cySource)
			for(x=0; x<cxClient; x+=cxSource)
			{
				BitBlt(hdc, x, y, cxSource, cySource, hdcMem, 0,0,SRCCOPY);
			}

		DeleteDC(hdcMem);
		EndPaint(hwnd, &ps);
		return 0;
	case WM_DESTROY:
		DeleteObject(hBitmap);
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}







Here's the resource file contents:
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//

TestBMP                 BITMAP  DISCARDABLE     "bitmap1.bmp"
#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED


[Edited by - kirkd on January 5, 2005 9:55:27 PM]

Share this post


Link to post
Share on other sites
Advertisement
I'm not sure what you mean by "a resource file referring to the BMP file". The BMP resource needs to be inserted into the resource file doesn't it?

Share this post


Link to post
Share on other sites
The resource file (*.rc) contains a line that references the bitmap file by name. I've inserted the Bitmap and named it through Visual Studio 6 SP5 as usual, but for some reason, the error always pops up.

-Kirk

Share this post


Link to post
Share on other sites
I fixed it.

1) The source file should contain #include "resource.h"

2) The following line:

hBitmap = LoadBitmap(hInstance, TEXT("TestBMP"));

was changed to

hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(TestBMP));


The include line makes sense. The other makes little sense to me.




-Kirk



Share this post


Link to post
Share on other sites
Resources created this way are not referenced by name by default, they are referenced by a 32bit integer value (you can give them a name though). TestBMP is #defined in "resource.h" to be the 32bit identifier of the resource.

LoadBitmap takes a string as its second parameter, the string is the name of the resource to load. Since the string is passed as a 32bit pointer, the LoadBitmap function checks the high word of the pointer value for 0, if it is zero, it treats the value as a resource identifier and not a pointer to a string; if it's not zero it treats the value as a pointer to a string. The MAKEINTRESOURCE is a macro that allows you to provide a 32bit integer identifier where a string is required without the compiler complaining about it.

Skizz

Share this post


Link to post
Share on other sites
Good you managed to fix it yourself (I was about telling you to have a look to your resource.h file anyway).

If you want to specify named resources then the resource.h file should not define the new resource.


// in resource.h : nothing
// in file.rc
SomeUniqueName BITMAP DISCARDABLE "bitmap1.bmp"
// the rc compiler will create a resource with the name "SOMEUNIQUENAME"


If your BITMAP is referenced with an ID - ie you have

// in resource.h
#define SomeUniqueName 100
// in file.rc
SomeUniqueName BITMAP DISCARDABLE "bitmap1.bmp"
// this is now equivalent to : 100 BITMAP DISCARDABLE "bitmap1.bmp"

Then you must use MAKEINRESOURCE() to tell LoadBitmap() that it is an ID - and not a string litteral.

Quote:
Original post by Skizz
Resources created this way are not referenced by name by default, they are referenced by a 32bit integer value (you can give them a name though). TestBMP is #defined in "resource.h" to be the 32bit identifier of the resource.


Exact - minus the fact that resource IDs are 16 bit values, not 32 bit ones (welcome back in the realm of backward compability).

HTH,

Share this post


Link to post
Share on other sites
Thank you both for the explanations. It is a bit contrived, I think, and doesn't make a lot of sense at this stage. Maybe one day, right??? 8^) I would think that the Petzold code would run, but the more I look the more I find that is not without problems.

-kirk

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!