Solved

AfxLoadString failure

Posted on 2000-04-21
20
739 Views
Last Modified: 2013-11-20
Apparently something has gotten foobar-ed in my program with regards to the system resource strings.  The specific place that I am having a problem is with DDV.

We have an edit box with double validation ranging from 0.01 to 10000.  When I enter an invalid value everything seems proceed appropriately into _AfxFailMinMaxRead, then to generate the error dialog, it tries to find the format string, proceeding into AfxFormatString2, then AfxFormatStrings.  In this particular case AfxLoadString is called with ID 61715 or 0xf113.  This fails.
Obviously these resources are part of MFC, so what are we doing wrong?  Did we stomp the system ID's somehow?
This is not localized to my machine.  It happens on NT4 sp5, sp6, Win2000.  We are using VC6 sp3.
0
Comment
Question by:sosedada
  • 9
  • 8
  • 2
  • +1
20 Comments
 
LVL 1

Author Comment

by:sosedada
ID: 2738590
As far as I can tell, afxres.rc and afxres.h are included properly.
0
 
LVL 1

Author Comment

by:sosedada
ID: 2738596
Adjusted points from 100 to 200
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2738638
Are you building to use MFC statically?  If so, your inclusion of AFXRES.RC should bring the MFC resources (including String 0xF113) into your app's image. You should load your executable in the IDE and snoop the resources to see if they're actually included or not.

If you're building to use MFC in a shared library, then the resources should be coming from MFC itself; they should be built into MFC42.DLL (or MFC42D.DLL in a debug build).  MFC should walk a module list in AfxLoadString() (or a subordinate function) to find the string in whichever module it lives.

..B ekiM

0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 1

Author Comment

by:sosedada
ID: 2738702
I am using the shared library.  I just made a quick dialog app, and the validation works correctly there.

Other strings in afxres.rc seem to be loaded correctly.

Here's the include of afxres.rc from EtAnalysis.rc:
3 TEXTINCLUDE DISCARDABLE
BEGIN
    "#define _AFX_NO_OLE_RESOURCES\r\n"
    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
    "\r\n"
    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
    "#ifdef _WIN32\r\n"
    "LANGUAGE 9, 1\r\n"
    "#pragma code_page(1252)\r\n"
    "#endif\r\n"
    "#include ""res\\EtAnalysis.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
    "#include ""afxres.rc""         // Standard components\r\n"
    "#include ""afxprint.rc""       // printing/print preview resources\r\n"
    "#endif\r\n"
      "\0"
END
0
 
LVL 1

Author Comment

by:sosedada
ID: 2738728
I take back my comment about correctly using other strings in afxres.rc, I don't see any others that I would be using.
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2738757
You need to trace into AfxLoadString() and figure out what's happening.

Are any DLLs that you've written involved in this application?

..B ekiM
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2738776
Are you calling SetResourceHandle() anwhere in your app or its DLLs?

What if you add

   CString str;
   str.LoadString(0xF113);

to your InitInstance() ? Does it work?

Does this happen in retail builds, debug builds, or both?

Have you been fooling around with any "AFX_NO_SOMETHING"-style defines?

..B ekiM
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2738781
Or do you just want to send me your project and have me figure it out for you?

..B ekiM
0
 
LVL 1

Author Comment

by:sosedada
ID: 2738844
For some reason it won't let me step into AfxLoad string.  We aren't using any of our own dll's.  The only third party one we are using has been used with other programs with no problems.

There is no call to SetResourceHandle.  LoadString as above fails also.  And we have the problem in both debug and release builds.

The only AFX_NO_*'s are OLE_RESOURCES, TRACKER_RESOURCES, and PROPERTY_RESOURCES.
0
 
LVL 1

Author Comment

by:sosedada
ID: 2738866
The only other funky thing I can think of is that we are compiling with (Debug) Multithreaded under Code Generation in the Project Settings.  Does that include MFC?

0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2739131
> Does that include MFC?

That's what you're supposed to be using, yes.

 > For some reason it won't let me step into AfxLoad string.  

That usually means your MFC DLLs don't match your PDBs.  You need to remedy that situation so you can debug the call and figure out what's going on.

..B ekiM
0
 
LVL 9

Expert Comment

by:cdesigner
ID: 2740242
\VC98\MFC\SRC\WINSTR.CPP
look at this
afxloadstring placed in this file:

#ifndef _AFXDLL
int AFXAPI AfxLoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf)
{
      ASSERT(AfxIsValidAddress(lpszBuf, nMaxBuf*sizeof(TCHAR)));
#ifdef _DEBUG
      // LoadString without annoying warning from the Debug kernel if the
      //  segment containing the string is not present
      if (::FindResource(AfxGetResourceHandle(),
         MAKEINTRESOURCE((nID>>4)+1), RT_STRING) == NULL)
      {
            lpszBuf[0] = '\0';
            return 0; // not found
      }
#endif //_DEBUG
      int nLen = ::LoadString(AfxGetResourceHandle(), nID, lpszBuf, nMaxBuf);
      if (nLen == 0)
            lpszBuf[0] = '\0';
      return nLen;
}
#endif

0
 
LVL 3

Expert Comment

by:SamHobbs
ID: 2740452
You say you "are compiling with (Debug) Multithreaded". Is it possible you might be compiling some other part of the project to use a different library? That would cause problems.

0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2740818

Your comment is irrelevant, cdesigner.  The code you've quoted is not compiled if _AFXDLL is defined. Since sosedada said he was using MFC in a shared DLL, _AFXDLL certainly _is_ defined. Therefore, we're certain this code isn't the routine that's executing on his machine.

What was the point of your post, anyway?  You threw the code into the discussion, but made no comment.

..B ekiM
0
 
LVL 9

Expert Comment

by:cdesigner
ID: 2741301
2 mikeblas:
;)
Im only want to say path to this function in mfc sources, if you have some problems - it's you problems ;)
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2741754
> Im only want to say path to this function in mfc sources,

But you picked the wrong function. The function that we're actually talking about here is around line 290 of MFC\SRC\DLLINIT.CPP.  The snippet you've shown doesn't include the suspect code.

..B ekiM
0
 
LVL 1

Author Comment

by:sosedada
ID: 2743658
Well I'm back and lets see where things stand.

Debug Multithreaded / Multithreaded:  My question was if this overrides the "Use MFC in a Shared DLL" option since (Debug) Multithreaded DLL is the default.

I am able to step into AfxLoadString, but its not going into the function in DLLINIT.CPP, its going into WINSTR.CPP.  When I try to set a break in DLLINIT.CPP its not valid.

Now that I go back and read the comments again, I see that selecting Multithreaded over Multithreaded DLL does include MFC.  And this is verified by the fact that we do not show the MFC dlls being loaded at runtime.  So, after leading this wild goose chase, how do I snoop the resources in the exe to see if they got loaded?
0
 
LVL 11

Accepted Solution

by:
mikeblas earned 200 total points
ID: 2743869
I thought your build was in good shape--you didn't say you were monkeying with build settings that you didn't fully understand. Further, you told me originally that you were using MFC in a DLL; now you say you're not.

So, we must sort this out and put it beyond question before we can get any further. Because it directly affects the answer your get--it directly affects the way the code you're writing is supposed to work.

If you have the "use MFC in a shared DLL" setting, you _must_ be using the "Debug multithreadded DLL" or "multithreadded DLL" settings for the runtime library.  If you have the "use MFC in a static library", you _must_ use "Debug Multithreaded" or "Multithreaded" settings for the runtimes.

You'll find that changing the MFC setting causes the build system in the IDE to automatically change the runtime library setting.

The runtime libraries option is independent of MFC in that it doesn't "include MFC", as you asked. However, the settings I've outlined above are the only MFC-compatible settings.  What includes MFC or not is you: if you touch the AFX.H or AFXWIN.H include files from your app, your app will link to MFC. That mechanism tries to assure that you're using the right libraries, so if you botch the settting in the IDE you should get an error message from the linker when you build.

There's also other settings, like predefining the "_AFXDLL" preprocessor symbol. If you've fooled with those settings, you're in trouble, too.  Do you see the "/D "_AFXDLL"" option in the "project options" window on the C/C++ tab when you look at your project?

 > how do I snoop the resources in the exe to see if they got loaded?

 1) Close everything in the IDE.
 2) Use the "Open" command in the "File" menu
 3) Set the "Open as" dropdown to "resources"
 4) Set the "Files of type" dropdown to "executableS"
 5) Find and open your project's EXE.

NOTE: Do not use the "Open Workspace" command in step #2.

If you're not running under NT, you'll get a warning about not being able to save modified resources.  Then, you'll see something that looks like the resources pane in the regular IDE. You can explore it to see what resources are in your app.

If you open the string table, you should see all of the stock MFC resources... with string ID numbers greater than 0xF000, especially including the one you're failing to load.

 > The only AFX_NO_*'s are OLE_RESOURCES, TRACKER_RESOURCES,
 > and PROPERTY_RESOURCES.

Does that mean you've gone and set these #define's yourself?

..B ekiM
0
 
LVL 1

Author Comment

by:sosedada
ID: 2744182
Well, I wouldn't have had to monkey with settings I didn't understand if they were documented or if it was possible to use the C++ Standard Library in a static library without monkeying with the settings.

In any case, I changed the project to use MFC in a Static Library and everything appears to be copacetic.
0
 
LVL 1

Author Comment

by:sosedada
ID: 2744197
As far as having a good build goes, I guess I should consider myself lucky that this is the only problem I've had since I switched to Multithreaded rather than Multithreaded DLL 8 months ago.  

And, if you know of any other way to use static libraries and the Standard Library without linking MFC statically I'd love to hear it.  I can ask another question if you want.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Error on moodle after upgrade 3 140
Change owner from userA to server Local Administrators 7 66
ffmpeg - "rtsp://...... Operation not permitted" 4 86
fix34  challenge 9 141
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question