Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Assuming you do not want to use LoadString() this should help...</p> <p>Strings and string tables are indeed treated differently when using FindResource() and FindResourceEx(). From <a href="http://support.microsoft.com/kb/q196774/" rel="noreferrer">this KB</a> article:</p> <blockquote> <p>String resources are stored as blocks of strings. Each block can have up to sixteen strings and represents the smallest granularity of string resource that can be loaded/updated. Each block is identified by an identifier (ID), starting with one (1). We use this ID when calling the FindResource, LoadResource and UpdateResource functions.</p> <p>A string with ID, nStringID, is located in the block with ID, nBlockID, given by the following formula:</p> <p>nBlockID = (nStringID / 16) + 1; // Note integer division.</p> </blockquote> <p>The lower 4 bits of nStringID indicates which entry in the block contains the actual string. Once you have calculated the block ID to pass to FindResource() and the index in the block where the string exists you have to scan through it's contents to find the string you are looking for.</p> <p>The following code should get you started.</p> <pre><code>const WCHAR *stringPtr; WCHAR stringLen; // Get the id of the string table block containing the target string const DWORD blockID = (nID &gt;&gt; 4) + 1; // Get the offset of teh target string in the block const DWORD itemID = nID % 0x10; // Find the resource HRSRC hRes = FindResourceEx( hInst, RT_STRING, MAKEINTRESOURCE(blockID), wLanguage); if (hRes) { HGLOBAL hBlock = LoadResource(hInst, hRes); const WCHAR *tableDataBlock = reinterpret_cast&lt;LPCWSTR&gt;(LockResource(hBlock)); const DWORD tableBlockSize = SizeofResource(hInst, hRes); DWORD searchOffset = 0; DWORD stringIndex = 0; // Search through the section for the appropriate entry. // The first two bytes of each entry is the length of the string // followed by the Unicode string itself. All strings entries // are stored one after another with no padding. while(searchOffset &lt; tableBlockSize) { if (stringIndex == itemID) { // If the string has size. use it! if (tableDataBlock[searchOffset] != 0x0000) { stringPtr = &amp;tableDataBlock[searchOffset + 1]; stringLen = tableDataBlock[searchOffset]; } // Nothing there - else { stringPtr = NULL; stringLen = 0; } // Done break; } // Go to the next string in the table searchOffset += tableDataBlock[searchOffset] + 1; // Bump the index stringIndex++; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload