1
votes

I'm having an issue where the MAKEINTRESOURCE macro always seems to return a bad pointer whenever I pass it my MFC resource ID's. The resource ID's are all listed in Resource.h and they match up with what the ID's are set to in the resource properties.

I'm new to MFC so I'm not entirely sure I understand how the resources & their ID's work, but it seems to me that the bad pointers would indicate that my resources aren't being stored in the correct place in memory? This is an old project that I'm trying to add something new to, and I checked anf when I try doing MAKEINTRESOURCE with older resources (that are definitely working, they show up and are functional when I run the application) I also get bad pointers.

What could be causing this?

edit: the project is using the unicode character set as well, if that makes any difference

1
Please be specific what you mean by "bad pointers." MAKEINTRESOURCE encodes an integer inside a pointer. It's not a pointer you can dereference; the only thing you can do with it is pass it to a resource function.Raymond Chen
When I run the program in debug and mouse over the return values it will say "<Bad Ptr> CXX0030Error: Expression cannot be evaluated" Is that expected? Whenever I try to load a resource using the returned value from MAKEINTRESOURCE it fails to locate the resource, and I thought perhaps the <Bad Ptr> was why.Marzipan
Yes that is expected, because it's not a pointer to anything and cannot be dereferenced.Raymond Chen
It is instructional to look at what the macro actually does: Include\WinUser.h:150:#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))i_am_jorf

1 Answers

2
votes

If by "bad pointers" you mean "pointers that don't point to resource objects in memory", then MAKEINTRESOURCE() is working correctly. The thing is that in order to pass either strings or integer IDs using the same function parameter, the Windows API functions make a weird pointer conversion which is detected by the function as a "oh wait, this is not a pointer, it's a resource ID".

This is documented behavior. For example, in the documentation for LoadBitmap(), it says:

lpBitmapName [in]:

A pointer to a null-terminated string that contains the name of the bitmap resource to be loaded. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can be used to create this value.

Creating an invalid pointer by re-interpreting an arbitrary integer value is a legal C++ construct, but dereferencing the invalid pointer is undefined behavior.

In this case, the function receiving the argument checks if the high-order word is 0 and if so, uses the low-order word as an integer and never dereferences the pointer.

Note: If this feels like a nasty hack, it's because it is a nasty hack.