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