Мастер классов в VS2013 не создает методы атрибутов для управления OCX

У меня есть устаревшее приложение, которое было построено с VC++6.0 и использует элемент управления OCX. Я обновил приложение для сборки с VS2013. Первоначально я получил его для сборки и запуска успешно, но когда я попытался восстановить файлы ocx.h и ocx.cpp с помощью мастера классов

  1. Щелкните правой кнопкой мыши проект в обозревателе решений.
  2. Выбор Добавить: Класс:MFCClass Из элемента управления ActiveX
  3. Кнопка [Добавить]
  4. Выберите OCX из списка зарегистрированных элементов управления
  5. Выберите интерфейс для копирования
  6. Кнопка [Готово]

В сгенерированных выходных файлах h и cpp отсутствуют все методы Attribute

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

Я также попытался дать Class Wizard файл OCX напрямую, а не использовать реестр, но у меня были те же результаты. Я прибегнул к ручному редактированию файлов ocx.h и ocx.cpp, чтобы добавить недостающие методы атрибутов, но не понимаю, почему Class Wizard их не генерирует. Я подумал вернуться к версии VC++6.0, чтобы посмотреть, будет ли он правильно генерировать файлы, но мне неясно, как использовать 6.0 для генерации файлов ocx.h и ocx.cpp, поскольку те же опции меню недоступны.

Добавлено 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)
. . .

===== FILE: SigPlusImage.cpp ====

short CSigPlusCtrl::GetImageFileFormat() 
{
    return ImageFileFormat;
}

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

И вот что мне пришлось добавить в сгенерированные файлы.h и.cpp в проекте контейнера, чтобы использовать этот отсутствующий атрибут. Я скопировал этот код из исходных файлов OCX .h и.cpp в приложении-контейнере, прежде чем пытался восстановить их с помощью VS2013. Поскольку я не смог восстановить эти файлы с помощью 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 я попытался открыть файл ocx в Visual Studio 2013, чтобы проверить TYPELIB. Но когда я раскрываю папку TYPELIB, она показывает только дамп HEX.

Глядя на интерфейс OCX TypeLib с помощью OLE/COM Object Viewer, я вижу отсутствующие свойства, перечисленные в разделе "Свойства", но не вижу явных объявлений методов 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 Viewer для методов 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

Я посмотрел #import, упомянутый @HansPassart в комментарии. Эта директива Microsoft является альтернативой использованию Class Wizard. Я удалил из проекта созданные Class Wizard файлы 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 в качестве родительского класса, где Class Wizard использовал CWnd, и при компиляции существуют следующие неразрешенные чистые виртуальные методы, исходящие от IUnknown, который является родителем 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 ответов

Другие вопросы по тегам