I am trying to mimic the behavior of CString::LoadString(HINSTANCE hInst, DWORD id, WORD langID)
without introducing a dependency on MFC into my app. So I walked through the source. The first thing it does is to immediately call AtlGetStringResourceImage(hInst, id, langID)
, and then this in turn contains the following line of code:
hResource = ::FindResourceExW(hInst, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((id>>4)+1), langID);
(It's not verbatim like this, but I trimmed out some unimportant stuff).
What is the meaning of shifting the ID by 4 and adding 1? According to the documentation of FindResourceEx, you should pass in MAKEINTRESOURCE(id)
, and I can't find any example code that is manipulating the id before passing it to MAKEINTRESOURCE
. At the same time, if I make my code call MAKEINTRESOURCE(id)
then it doesn't work and FindResourceEx
returns null, whereas if I use the above shift + add, then it does work.
Can anyone explain this?
From the STRINGTABLE resource documentation:
RC allocates 16 strings per section and uses the identifier value to determine which section is to contain the string. Strings whose identifiers differ only in the bottom 4 bits are placed in the same section.
The code you are curious about locates the section a given string identifier is stored in by ignoring the low 4 bits.