VS2013中的类向导不会为OCX控件创建属性方法

时间:2018-03-03 04:30:34

标签: c++ visual-studio activex ocx classwizard

我有一个使用VC ++ 6.0构建的遗留应用程序,它使用OCX控件。我已经使用VS2013升级了应用程序。最初我得到它来构建并成功运行但当我尝试使用类向导重新生成ocx.h和ocx.cpp文件时

  1. 右键单击解决方案资源管理器中的项目
  2. 选择添加:类:来自ActiveX控件的MFCClass
  3. [添加]按钮
  4. 从已注册控件列表中选择OCX
  5. 选择要复制的界面
  6. [完成]按钮
  7. 生成的h和cpp输出文件缺少所有属性方法

            // Attributes
    public:
            // Operations
    public:
            void ClearTablet()
        { . . .
    

    我还尝试直接向Class Wizard提供OCX文件而不是使用注册表,但结果相同。我使用手动编辑ocx.h和ocx.cpp文件来添加缺少的属性方法,但不明白为什么类向导不生成它们。我想回到VC ++ 6.0版本看它是否能正确生成文件,但我不清楚如何使用6.0生成ocx.h和ocx.cpp文件,因为相同的菜单选项不可用。 / p>

    在回应Hans评论时添加了3-5-2018

    以下是原始OCX项目中缺少的属性之一

    ===== FILE:SigPlusCtl.h =========

    class CSigPlusCtrl : public COleControl
    {
        DECLARE_DYNCREATE(CSigPlusCtrl)
    
        DECLARE_INTERFACE_MAP()
        . . .
        // Dispatch maps
        //{{AFX_DISPATCH(CSigPlusCtrl)
        afx_msg short GetImageFileFormat();
        afx_msg void SetImageFileFormat(short nNewValue);
        . . .
    

    ===== FILE:SigPlusCtl.cpp =========

    // Dispatch map
    BEGIN_DISPATCH_MAP(CSigPlusCtrl, COleControl)
    //{{AFX_DISPATCH_MAP(CSigPlusCtrl)
    DISP_PROPERTY_EX(CSigPlusCtrl, "ImageFileFormat", GetImageFileFormat, SetImageFileFormat, VT_I2)
    . . .
    

    =====文件:SigPlusImage.cpp ====

    short CSigPlusCtrl::GetImageFileFormat() 
    {
        return ImageFileFormat;
    }
    
    void CSigPlusCtrl::SetImageFileFormat( short nNewValue) 
    {
        if ( ( nNewValue >= 0 ) && ( nNewValue <= 11 ) )
        {
            ImageFileFormat = nNewValue;
        }
        SetModifiedFlag();
    } 
    . . .
    

    以下是我必须添加到容器项目中生成的.h和.cpp文件以使用此缺少的属性。在我尝试使用VS2013重新生成它们之前,我从容器应用程序中的原始OCX .h和.cpp文件中复制了此代码。由于我无法使用VC ++ 6.0重新生成这些文件(请参阅下面的第一条评论),我不知道这个复制的代码最初是由VC ++ 6.0向导创建的,还是原始程序员也编辑了这些头文件。

    ====== FILE:sigplus =====

    // Attributes
    public:
        short GetImageFileFormat();
        void SetImageFileFormat(short);
    . . .
    

    ====== FILE:sigplus.cpp =============

    // CSigPlus properties
    
    short CSigPlus::GetImageFileFormat()
    {
        short result;
        GetProperty(0x1, VT_I2, (void*)&result);
        return result;
    }
    
    void CSigPlus::SetImageFileFormat(short propVal)
    {
        SetProperty(0x1, VT_I2, propVal);
    }
    . . .
    

    我不知道是否对类向导很重要,但方法位置有些不同寻常,因为OCX控件方法的实现分散在多个.cpp文件中,而不是全部位于SigPlusCtl.cpp文件中

    已添加3-20-18

    继汉斯3-20的评论之后,我试图用Visual Studio 2013打开ocx文件来检查TYPELIB。但是,当我展开TYPELIB文件夹时,它只向我显示一个HEX转储。 enter image description here

    使用 OLE / COM Object Viewer 查看OCX TypeLib接口我看到“属性”下列出了缺少的属性,但我没有看到Get和Set方法的显式声明。例如,有一个属性 ImageFileFormat ,但没有 GetImageFileFormat SetImageFileFormat 。在OCX控件的源代码中有这些Get / Set方法的明确定义。

    SigPlusCtl.cpp: DISP_PROPERTY_EX(CSigPlusCtrl, "ImageFileFormat", GetImageFileFormat, SetImageFileFormat, VT_I2)
    SigPlusCtl.h:     afx_msg short GetImageFileFormat();
    SigPlusImage.cpp: short CSigPlusCtrl::GetImageFileFormat() 
    SigPlus.map:  0001:00012ed0       ?GetImageFileFormat@CSigPlusCtrl@@IAEFXZ 10013ed0 f   SigPlusImage.obj
    

    我是否希望在方法下的OLE查看器中看到Get和Set方法的显式列表?

        dispinterface _DSigPlus {
            properties:
                [id(0x00000001)            
    ]
                short ImageFileFormat;
                [id(0x00000002)            
    ]
                short ImageXSize;
                [id(0x00000003)            
    ]
                short ImageYSize;
                [id(0x00000004)            
    ]
                o o o 
    ]
                BSTR TabletGraphicFile;
                [id(0x00000042)            
    ]
                long TabletTimer;
                [id(0xfffffe0b), bindable, requestedit            
    ]
                OLE_COLOR BackColor;
                [id(0xfffffdff), bindable, requestedit            
    ]
                OLE_COLOR ForeColor;
            methods:
                [id(0x00000043)]
                void ClearTablet();
                [id(0x00000044)]
                o o o
    

    已添加3-20-18 17:00PDT

    我在评论中查找了@HansPassart提到的 #import 。此Microsoft特定指令似乎是使用类向导的替代方法。我从项目中删除了类向导生成的文件sigplus.h和sigplus.cpp,并添加了

    #import "file:SigPlus.tlb" 
    

    到主头文件。编译时, #import 指令生成sigplus.TLH和sigplus.TLI(头文件和实现)文件,然后包含sigplus.TLH,然后显式包含TLI文件。编译时,#import会生成这两个文件,然后包含生成的“Release / sigplus.tlh”。这些生成的文件确实包含缺少的Get / Set方法,但它们不能编译。 TLH文件为OCX类_DSigPlus使用不同的名称,并将其放在命名空间中。但即使考虑到这些差异,TLH文件中的类声明使用IDispatch作为类向导使用CWnd的父类,并且在编译时,还有来自IUCnknown的以下未解析的纯虚方法,它是IDispatch的父类。

    c:\demoocx\DemoOCXDlg.h(24): error C2259: 'SIGPLUSLib::_DSigPlus' : cannot instantiate abstract class
              due to following members:
              'HRESULT IUnknown::QueryInterface(const IID &,void **)' : is abstract
              C:\Program Files (x86)\Windows Kits\8.1\Include\um\unknwnbase.h(114) : see declaration of 'IUnknown::QueryInterface'
              'ULONG IUnknown::AddRef(void)' : is abstract
              C:\Program Files (x86)\Windows Kits\8.1\Include\um\unknwnbase.h(118) : see declaration of 'IUnknown::AddRef'
              'ULONG IUnknown::Release(void)' : is abstract
              C:\Program Files (x86)\Windows Kits\8.1\Include\um\unknwnbase.h(120) : see declaration of 'IUnknown::Release'
              'HRESULT IDispatch::GetTypeInfoCount(UINT *)' : is abstract
              c:\program files (x86)\windows kits\8.1\include\um\oaidl.h(2187) : see declaration of 'IDispatch::GetTypeInfoCount'
              'HRESULT IDispatch::GetTypeInfo(UINT,LCID,ITypeInfo **)' : is abstract
              c:\program files (x86)\windows kits\8.1\include\um\oaidl.h(2190) : see declaration of 'IDispatch::GetTypeInfo'
              'HRESULT IDispatch::GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID *)' : is abstract
              c:\program files (x86)\windows kits\8.1\include\um\oaidl.h(2195) : see declaration of 'IDispatch::GetIDsOfNames'
              'HRESULT IDispatch::Invoke(DISPID,const IID &,LCID,WORD,DISPPARAMS *,VARIANT *,EXCEPINFO *,UINT *)' : is abstract
              c:\program files (x86)\windows kits\8.1\include\um\oaidl.h(2202) : see declaration of 'IDispatch::Invoke'
    

0 个答案:

没有答案