我已经接管了C ++中传统MFC OCX控件的维护。该项目现在在VS2013。我正在尝试了解DoPropExchange方法的功能。这个方法似乎是为控件中的几乎所有数据成员调用PX _ ?????(成员)????是类型(Bool,Short,Long ...)我的理解是为了提供持久存储属性而调用它们。但是根据我对OCX控件操作的理解,没有持久性属性。是否还有其他理由要拨打PX _ ????对于DoPropExchange中的所有数据成员而不是支持持久属性?我也试图了解这些持久属性的加载/存储位置。用于加载/存储指定的持久属性值的序列化文件在哪里?
以下是DoPropExchange的来源
// CSigPlusCtrl::DoPropExchange - Persistence support
void CSigPlusCtrl::DoPropExchange(CPropExchange* pPX)
{
DWORD Version;
long BaudRate;
short ComPort;
BOOL Rv;
LOG(("DoPropExchange Entry"));
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
Version = pPX->GetVersion();
if (pPX->IsLoading())
{
LoadDefaultProperties();
LoadIniParameters();
}
if ((Version & 0xFFFF0000) == (DWORD)MAKELONG(0, _wVerMajor))
{
Rv = PX_Short(pPX, _T("ImageFileFormat"), ImageFileFormat, 0);
Rv = PX_Short(pPX, _T("ImageXSize"), ImageXSize, 0);
Rv = PX_Short(pPX, _T("ImageYSize"), ImageYSize, 0);
Rv = PX_Short(pPX, _T("ImagePenWidth"), ImagePenWidth, 1);
. . .
Rv = PX_Short(pPX, _T("ZoomY"), ZoomY, 0);
Rv = PX_Short(pPX, _T("ZoomPower"), ZoomPower, 1);
if (pPX->IsLoading())
{
if (SigBlob != NULL)
{
GlobalFree(SigBlob);
SigBlob = NULL;
}
}
else
{
if (SigBlob == NULL)
{
SigBlobType* SigBlobPtr;
SigBlob = GlobalAlloc(GMEM_MOVEABLE, sizeof(DWORD));
SigBlobPtr = (SigBlobType*)GlobalLock(SigBlob);
SigBlobPtr->Size = 0;
GlobalUnlock(SigBlob);
}
}
if ((Version & 0xFFFF) == Version223)
{
Rv = PX_Blob(pPX, _T("SigBlob"), SigBlob, NULL);
}
if ((Version & 0xFFFF) >= Version224)
{
CString SigStr;
if (!pPX->IsLoading())
{
SigStr = BlobToString();
}
Rv = PX_String(pPX, _T("SigStringStored"), SigStr, _T(""));
if (pPX->IsLoading())
{
BlobFromString(SigStr);
}
}
}
else
{
SigMessageBox("Warning Incompatable Versions of SigPlus Control");
}
LoadTabletParameters();
LOG(("DoPropExchange Exit"));
}
编辑已添加6-21-2018
在调试器中运行我观察到,当调用DoPropExchange时,VS2013会向堆栈显示一条消息,表明下面的堆栈帧可能不正确。上面的一个框架,调用DoPropExchange,来自mfc120d.dll,它没有符号文件可用mfc120d.i386.pdb。
这Microsoft Forum Post似乎表明符号文件不适用于VS2015,我想知道VS2013的情况是否也是如此。到目前为止,我还没有找到下载MFC120符号进行调试的地方。
今天开始获得赏金,找到可以解释通常为OLE控件序列化的属性和位置的人,以及用于指定序列化数据存储位置/媒体的方法。这是值得关注的,因为此控件在终端感知程序中的Citrix ZenDesk网络环境中运行,如果属性存储在某处,则每个客户端都需要指定该客户端唯一的位置。
答案 0 :(得分:0)
DoPropExchange主要用于在设计和运行时之间实现控件属性的持久性。实际的目标接收器由OCX的客户端传递。
在VC中,设置存储在RC文件中,而在VB中则存储在frm和frx文件中。如果在记事本中打开FRM,则可能会看到包含此控件属性的部分。 附带说明一下,如果控件用于HTML且HTML本身具有内联设置,则有类似的实现。
除非您的VB客户端通过直接调用Property bag函数将设置保存在外部,否则在这里不太可能出现问题,因为上述属性未在运行时存储。