Thanks for the reply.
My module is set correctly. Your code works because you hard-coded 65535 which is converted by the compiler to 0x0000ffff. My code is actually getting a menu entry from CMenu and it returns a UNIT. The menu item is a submenu and so its menu ID is actually 0xffffffff (not 0x0000ffff). That is making the difference. I now see that the code that calls FindResourceW in ATL::AtlGetStringResourceImage is doing this to the ID:
MAKEINTRESOURCEW(((id>>4)+1) & static_cast<WORD>(~0)) )
If I call with the hard coded 65536, the result is 0x1000 and that is a valid resource handle. Hence, MFC continues on an can load the string from the handle.
But the system is running on UINTS (menu IDs that are essentially command IDs). But this is for a submenu entry in my case. So, what is actually getting passed in is the ID of a submenu - 0xffffffff.
0xffffffff >> 4 = 0x0fffffff
0x0fffffff+1 = 0x10000000
0x10000000 & 0x0FFFF = 0x00000000
So, FindResourceW is passed 0x0 and fails to find the string.
Quite revealing as I originally examined the string table for the module handle in question and found in the table (resource editor) the value is 65535. But by the time it actually works its way to the CString code, it is not 0x0000ffff but rather 0xffffffff. I am actually using the Windows LoadString API and was looking at CStringT and found it failed to find a string in this case.
Basically we are getting menu entries from a menu resource and looking up the command string using the menu entry. Looks like we should be masking off the upper 16 bits. This isn't a menu we are eventually showing. It's a menu converted to a set of controls for all that fancy ribbon stuff apps now use in place of the old menus and toolbars. All the code is using UINTS. If I don't use MFC and instead use the OS LoadString API and pass in 0xffffffff, the string is returned. Apparently LoadString is more forgiving that the code CString is using.