1

I am trying to implement a String Table in resource file .rc and then load specific string using function CString::LoadStringW(). This is the code main.cpp:

#ifndef _AFXDLL
#define _AFXDLL
#endif
#include <afx.h>
#include <stdio.h>
#include "resource.h"

int main()
{
    printf("Code Example: Load resource file data\n");

    CString sentence;
    sentence.LoadStringW(IDS_STRING101);
    printf("Sentence: %s", sentence);

    getchar();
    return 0;
}

There are already good links with description, how to use resource files as:

http://www.cplusplus.com/forum/windows/119338/

http://www.winprog.org/tutorial/resources.html

The problem is when I compile the code and then try to run, it does not read the string. When debuging, the line with LoadStringW() function throws an assertion error:

Debug Assertion Failed!

Program: C:\WINDOWS\SYSTEM32\mfc140ud.dll
File: f:\dd\vctools\vc7libs\ship\atlmfc\include\afxwin1.inl
Line: 24

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

In the end of the first URL I provided is (as last step) to link compiled resource file .rc and my source file main.cpp. I am not sure how to do this and perhaps this is why my program does not work as expected.

Please, do you have any recommendations?

I am trying on MSVS 2015 / 2017.

Thanks.

  • 1
    What does your resource file look like? Which line causes the assertion? Why do you have `_AFXDLL` defined at the top? – user7860670 Sep 26 '17 at 22:21
  • assertion is caused by line `sentence.LoadStringW(IDS_STRING101);`. I use `_AFXDLL` because I am using MFC and Runtime Library option /MDd. I just sutisfied compiler error. But removal of this definition and using /MT does not change described problem. I will simplify resource file and provide it here in short time... – Jakub Pilka Sep 26 '17 at 22:32
  • Assertion is actually triggered by some code inside of `LoadStringW`. Maybe it displays a proper stack trace with real assertion spot (that is `assert(...)`) so failed assertion condition can be determined? Also what is the value of `IDS_STRING101`? 101? – user7860670 Sep 26 '17 at 22:38
  • ok, I really simplified the resource file for this demonstrative purpose. The problem still keeps to be there. Resource.rc:`#include "resource.h" STRINGTABLE BEGIN IDS_STRING101 "My Resource Sentence" END` – Jakub Pilka Sep 26 '17 at 22:40
  • yes. this is the resource.h file: `#define IDS_STRING101 101` – Jakub Pilka Sep 26 '17 at 22:44
  • `_AFXDLL` does not mean what you think it does. https://stackoverflow.com/a/40419091/17034 – Hans Passant Sep 27 '17 at 00:09
  • Thank You Hans for input. I still don't completely understand the purpose of `_AFXDLL` yet. But I removed it from project for now. Currently, I found exact line which throws assertion in afxwin1.inl: `ASSERT(afxCurrentResourceHandle != NULL)`. So the problem cause is that function has no resource handle. Since `LoadStringW` function is overloaded also with only one input argument `(UINT nID)` I presume there should be default handle provided within the function. Question is, why there is a NULL handle? – Jakub Pilka Sep 27 '17 at 11:33

1 Answers1

0

After a while, I am still not able to explain why code posted in question does not work. However for reading a string resource from String Table I used different function LoadString() and finally made it work which is actually NOT part of CString class.

The problem with NULL resource handler is solved by getting a handle to the running .exe file which contains these resources (good tool to verify which resources are included is e.g. Resource Hacker) - done with GetModuleHandle(NULL)

Below is the working code snippet.

main.cpp:

#include <afx.h>
#include <stdio.h>
#include "resource.h"
#define BUF_SIZE 50

int main(void)
{
    printf("Code Example: Load resource file data\n");

    wchar_t buffer[BUF_SIZE];

    if (!LoadString(GetModuleHandle(NULL), IDS_STRING104, buffer, BUF_SIZE))
    {
        printf("Error Loading String: IDS_STRING104\n");
    }
    else
    {
        printf("resource string: %ls\n", buffer);
    }

    getchar();
    return 0;
}

resource.h:

#define IDS_STRING103                   103
#define IDS_STRING104                   104

Resource.rc:

#include "resource.h"

STRINGTABLE
BEGIN
    IDS_STRING103           "Resource 103 sentence"
    IDS_STRING104           "Resource 104 sentence"
END

Here are some references, which were useful to me:

How to get my own code's module handle?

https://msdn.microsoft.com/en-gb/library/windows/desktop/ms647486.aspx