How Can I Add an "ATL Simple Object" to Old ATL DLL Project Upgraded to VS 2010?
Asked Answered
L

2

7

We have a DLL project which has existed for a long time (maybe as far back as Visual Studio 6) which has been updated for each new version of VS. The project contains a number COM classes implemented using ATL.

After upgrade to VS 2010, the project still builds fine. However, if I try to right-click the project and choose Add -> Class... -> ATL Simple Object, I get an error box that says this:

ATL classes can only be added to MFC EXE and MFC Regular DLL projects or projects with full ATL support.

This worked in VS 2008.

When I look at the project properties, Use of MFC was set to Use Standard Windows Libraries and Use of ATL was set to Not Using ATL. I changed these to Use MFC in a Shared DLL and Dynamic Link to ATL respectively, but still get the same error.

I know how to add new ATL objects without using the wizard, and I could try to recreate the project from scratch using VS 2010 to make it happy. But does anyone know of any easy way to get VS to allow me to use the ATL Simple Object wizard with a project that it doesn't recognize as a project "with full ATL support"?

Loath answered 21/12, 2011 at 18:54 Comment(0)
G
10

Check this thread out.

It seems that adding this fragment info your ATL C++ code make it work. You don't need to actually build the project, just remove this stuff away after you are done with the wizard (provided that solution works for you).

// Added fake code begins here

class CAppModule : 
    public CComModule
{
};

// Added fake code ends here, below is regular ATL project stuff

CAppModule _Module;

This is where it all comes from, in $(VisualStudio)\VC\VCWizards\1033\common.js:

/******************************************************************************
Description: Returns a boolean indicating whether project is ATL-based.
oProj: Project object
******************************************************************************/
function IsATLProject(oProj)
{
    try
    {
        var oCM = oProj.CodeModel;
        oCM.Synchronize();
        // look for global variable derived from CAtlModuleT
        var oVariables = oCM.Variables;
        for (var nCntr = 1; nCntr <= oVariables.Count; nCntr++)
        {
            var oVariable = oVariables(nCntr);
            var strTypeString = oVariable.TypeString;
            if (strTypeString == "ATL::CComModule" || strTypeString == "ATL::CAutoThreadModule")
            {
                return true;
            }
Gallant answered 21/12, 2011 at 19:19 Comment(4)
I thought later that an edit function IsATLProject(oProj) { return true; } is even more reliable, but it would take one to go searching for that wizard script... And the first trick is just with the project source.Gallant
FWIW, I was able to pare down the needed code to a single line: "class CDummyModule: public CComModule {} DummyModule;" This also prevents any errors due to the existing _Module definition. And make sure to delete it or comment it out before building the project, to prevent problems caused by having multiple CComModule-derived objects.Loath
I think there is some predefined macro (cpp appwiz something?) that can also be used to isolate fake code to only AppWziard and exclude it from real binary.Gallant
I just used this today in VS2019 and it worked perfectly. I wrapped the 'fake code' inside #if false / #endif so I don't even need to worry about adding/removing it for use of the ClassWizards. Thanks for sharing @RomanR!Amand
A
3

Same problem here, but the project source already had CComModule _Module; Fixed it, based on the IsATLProject script shown above, by changing it to **ATL::**CComModule _Module;

Attaboy answered 26/2, 2013 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.