The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Win API AfxGetMainWnd() no longer working in VC7

So I tried recompiling this old project we have, with Visual Studio .NET 2003 and the call to AfxGetMainWnd() now returns NULL!

as in:
AfxGetMainWnd()->PostMessage(WM_LOG_MSG, (WPARAM) pCStr);

It crashes of course.

It is in a plain old C-function so I am at a loss to where I can find the application object or any member-variable containing the window reference.

Why does this work fine when compiling with Visual C++ 6 but not in 2003?  Please does anyone know what's going on?
Friday, January 06, 2006
Try with LoadLibrary() + GetProcAddress()?
Friday, January 06, 2006
Friday, January 06, 2006
You sure that's in the Win32 API?
Ben Dyson
Sunday, January 08, 2006
No maybe not.  Just trying to figure out what the difference is, it works when compiling with Visual Studio 6 like I said but not VC7. Anyhow, the program is a bit strange.  "Our" program sets up a window and occasionally some non-modal dialogs as well, but what is happening when the problem occurs: looking at the call log, the call is coming from external DLL:s.  OK, backtracking a bit here.  What you need to do is set up a set of pointers to callback functions (plain old C functions) and pass it to this other application's external API (over which I have no control, it's just a published API and that's the way to interact with it). The other application's DLLs are calling back to "our" functions, part of our GUI application, and when they do at some point this AfxGetMainWnd no longer available through AfxGetMainWnd.  Again, this is with VC7.  With VC6 it works fine. 

Could it be possible that the other application's DLLs are compiled with VC6 and if so is it not possible to link against them with VC7?  But why would that cause this behavior?  The actual function and callbacks work apart from this...
Sunday, January 08, 2006
The Afx* funs are MFC, and in this case it calls GetMainWnd for the current thread. I'd look up that function on MSDN if I were you. My WAG is that you are either in a thread that doesn't have a window (so how did it work before?), or more likely, if this is near the beginning of the application, things are getting initialised in a different order in the latest version of the compiler/linker (static objects?) or MFC (ask MS or go digging).

Monday, January 09, 2006
Thanks for the info guys.!  I had looked it up on MSDN but got mostly the same info, that it returns either the current value of the member variable m_pMainWnd of the application object or something to do with OLE containers which I don't think applies, or the main window for the calling thread.

Problem is, as noted above, the call stack jumps through some hoops (another external application involved) and ends up in a pure C-function called through a function pointer (callback), so it is not clearly related to "our" application object.  To put it simply I'm not sure which thread I am in, to be honest :-) 

The main window does exist since long ago so the m_pMainWnd is probably initialized in whatever app object but I am guessing the external application doing the callback is maybe a different unrelated thread with no associated window, in which case the program is probably incorrect quite simply.  Strange that it worked with vstudio 6 though.

Is there something that would give me info about the current thread, or better yet the current application object (if that makes sense)?

In the end I might just end up changing it and keeping track (storing) the pointer to the correct window through some external means instead of worrying more about this.

In general though, are there known problems when calling functions between VC6 compiled DLLs/programs and VC7 compiled?
Monday, January 09, 2006
ATL 7 and MFC 7 are not compatible with DLLs compiled with VC 6.  However, I'd expect a link time problem rather than a runtime problem, but you never know.  Microsoft has never been very good at documenting interoperation issues with binaries from different compiler versions.

Here's an excerpt from the docs:

The ATL and MFC DLL files shipping as part of Visual C++ .NET 2002 have been renamed to ATL70.dll and MFC70.dll, respectively.

The Visual C++ .NET ATL and MFC classes are not binary compatible with the same classes from previous releases, and therefore any source code built using mfc42.dll must be rebuilt with Visual Studio .NET. Any DLL or LIB files used by your application must also be rebuilt with Visual Studio .NET.

For example, a library containing an exported function taking CString as a parameter that has been built using Visual C++ 6.0 will give an unresolved external during linking with a Visual C++ .NET project
Monday, January 09, 2006
Looks like your application loads MFC70.DLL and the external DLL loads MFC42.DLL. Application object will only be constructed in the mfc dll loaded by your application, but not in the mfc dll loaded by external dll.

Perhaps it can by fixed by explicitly loading MFC42.DLL and setting the m_pMainWnd field of application object to correct value manually. Source code and custom-built MFC might help. It is a bit of hackery.
Andrei Send private email
Wednesday, January 11, 2006

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz