Mdl应用程序在Microstatin升级到V8过后,很多程序也需要相应的调整才能够运行。
其中代码需要变动最大的就是ModelRef和Tcb变量相关的方面,下面将陆续收集在Mdl程序升级过程中碰到的各种问题的一些解决方法。
关于TCB变量的变更:
Active Level
tcb->ad1.params.actlev 不再存在,可以使用mdlLevel_getActive和mdlLevel_setActive来访问和修改。
Active Font...
其他一些设置当前参数的tcb变量如tcb->actfont等, 可以使用mdlParams_getActive和mdlParams_setActive去访问和修改。
tcb->subpermast 和tcb->uorpersub
可以如下方法获取:
tcb->globalorg
可以用如下方法去获取:
el.hdr.ehdr.xlow 改为 el.hdr.dhdr.range.xlowlim;
el.hdr.ehdr.ylow 改为 el.hdr.dhdr.range.ylowlim;
el.hdr.ehdr.xhigh 改为 el.hdr.dhdr.range.xhighlim;
el.hdr.ehdr.yhigh 改为 el.hdr.dhdr.range.yhighlim;
el.text_2d.dhdr.props.b.a 改为mdlElement_extractAttributes(&length,NULL,&el);
mdlView_fit
该函数接口有所变化,可以使用类似如下代码:
但是在V8中已经取消了levels mark参数,为了减少代码的改动,这里提供了一个和旧借口保持兼容的函数。
代码如下:
其中代码需要变动最大的就是ModelRef和Tcb变量相关的方面,下面将陆续收集在Mdl程序升级过程中碰到的各种问题的一些解决方法。
关于TCB变量的变更:
Active Level
tcb->ad1.params.actlev 不再存在,可以使用mdlLevel_getActive和mdlLevel_setActive来访问和修改。
Active Font...
其他一些设置当前参数的tcb变量如tcb->actfont等, 可以使用mdlParams_getActive和mdlParams_setActive去访问和修改。
tcb->subpermast 和tcb->uorpersub
可以如下方法获取:
double GetUnit()
{
double unit;
DgnModelRefP pModelRef;
pModelRef = mdlModelRef_getActive();
unit = mdlModelRef_getUorPerSub(pModelRef) * mdlModelRef_getSubPerMaster(pModelRef);
return unit;
}
{
double unit;
DgnModelRefP pModelRef;
pModelRef = mdlModelRef_getActive();
unit = mdlModelRef_getUorPerSub(pModelRef) * mdlModelRef_getSubPerMaster(pModelRef);
return unit;
}
tcb->globalorg
可以用如下方法去获取:
StatusInt GetGlobalOrigin(DPoint3d *globalOrigin)
{
DgnModelRefP pModelRef;
int status;
pModelRef = mdlModelRef_getActive();
status = mdlModelRef_getGlobalOrigin(pModelRef, globalOrigin);
if (status == ERROR) {
globalOrigin->x = 0.0;
globalOrigin->y = 0.0;
globalOrigin->z = 0.0;
}
return status;
}
{
DgnModelRefP pModelRef;
int status;
pModelRef = mdlModelRef_getActive();
status = mdlModelRef_getGlobalOrigin(pModelRef, globalOrigin);
if (status == ERROR) {
globalOrigin->x = 0.0;
globalOrigin->y = 0.0;
globalOrigin->z = 0.0;
}
return status;
}
MSElementUnion
关于MSElementUnion结构体也有一些变化,主要包括:
MSElementUnion el;
el.hdr.dhdr.symb.b.weight 改为 el.hdr.dhdr.symb.weight;
el.hdr.dhdr.symb.b.style 改为 el.hdr.dhdr.symb.style;
el.hdr.dhdr.symb.b.color 改为 el.hdr.dhdr.symb.color;
el.hdr.ehdr.xlow 改为 el.hdr.dhdr.range.xlowlim;
el.hdr.ehdr.ylow 改为 el.hdr.dhdr.range.ylowlim;
el.hdr.ehdr.xhigh 改为 el.hdr.dhdr.range.xhighlim;
el.hdr.ehdr.yhigh 改为 el.hdr.dhdr.range.yhighlim;
el.text_2d.dhdr.props.b.a 改为mdlElement_extractAttributes(&length,NULL,&el);
mdlView_fit
该函数接口有所变化,可以使用类似如下代码:
int FitCurrent(int view)
{
int status = TRUE;
DgnModelRefP modelRef;
DgnModelRefListP modelRefListP;
mdlModelRefList_create(&modelRefListP);
modelRef = mdlModelRef_getActive();
mdlModelRefList_add(modelRefListP, modelRef);
if (mdlView_fit(view, modelRefListP) != SUCCESS) {
status = FALSE;
}
mdlModelRefList_free(&modelRefListP);
return status;
}
{
int status = TRUE;
DgnModelRefP modelRef;
DgnModelRefListP modelRefListP;
mdlModelRefList_create(&modelRefListP);
modelRef = mdlModelRef_getActive();
mdlModelRefList_add(modelRefListP, modelRef);
if (mdlView_fit(view, modelRefListP) != SUCCESS) {
status = FALSE;
}
mdlModelRefList_free(&modelRefListP);
return status;
}
Set levels mark to view
在J或更低版本中,经常需要在参考文件时设置levels mark,函数原形如下:
void mdlRefFile_attachCoincident
(
char *filename, /* => name of file to attach */
char *logical, /* => logical name */
char *description, /* => description (optional) */
short levels[8][4], /* => level bit maps */
boolean snapLock, /* => initial state of snap lock */
boolean locateLock /* => initial state of locate lock */
);
(
char *filename, /* => name of file to attach */
char *logical, /* => logical name */
char *description, /* => description (optional) */
short levels[8][4], /* => level bit maps */
boolean snapLock, /* => initial state of snap lock */
boolean locateLock /* => initial state of locate lock */
);
但是在V8中已经取消了levels mark参数,为了减少代码的改动,这里提供了一个和旧借口保持兼容的函数。
代码如下:
//------------------------------------------------------------------------------------
// Convert level codes to level ids.
// Input levelCodes and output levelIds is a set of " " or "," delimited in a string.
// The string may contain ranges too. e.g. string: 1,10-15,3,20,25-28,31-35
//------------------------------------------------------------------------------------
void cnvLevelCodesToIds(char *levelCodes, char *levelIds, DgnModelRefP pModelRef)
{
char *token;
char *rangeDelimiter;
char tempStr[512];
int pos;
ULong i, levelCodeStart, levelCodeEnd;
ULong levelId = 0;
char seps[] = " ,";
if (levelCodes == NULL || levelIds == NULL)
return;
strcpy(tempStr, levelCodes);
levelIds[0] = '\0';
token = strtok(tempStr, seps);
while (token != NULL) {
rangeDelimiter = strchr(token, '-');
if (rangeDelimiter != NULL) {
pos = rangeDelimiter - token;
rangeDelimiter++;
token[pos] = '\0';
levelCodeStart = atol(token);
levelCodeEnd = atol(rangeDelimiter);
if (levelCodeStart > 0 && levelCodeEnd > levelCodeStart) {
for (i = levelCodeStart; i <= levelCodeEnd; i++) {
if (mdlLevel_getIdFromCode(&levelId, pModelRef, i) == SUCCESS)
sprintf(&levelIds[strlen(levelIds)], "%ld,\0", levelId);
}
}
}
else {
levelCodeStart = atol(token);
if (levelCodeStart > 0) {
if (mdlLevel_getIdFromCode(&levelId, pModelRef, levelCodeStart) == SUCCESS)
sprintf(&levelIds[strlen(levelIds)], "%ld,\0", levelId);
}
}
token= strtok (NULL, seps);
}
if (strlen(levelIds) > 0)
levelIds[strlen(levelIds) - 1] = '\0';
}
//------------------------------------------------------------------------------------
// attachFileCoincident.
// To keep old code reusable, using the old parameter: unsigned short levels[8][4]
//------------------------------------------------------------------------------------
StatusInt attachFileCoincident(char *refFile,
char *logical,
char *description,
unsigned short levels[8][4],
BoolInt snapLock,
BoolInt locateLock)
{
DgnModelRefP outModelRefP;
MSWChar wcLogName[128];
MSWChar wcDescription[128];
char levelCodes[512];
char levelIds[512];
StatusInt status;
BitMask *levelMask = NULL;
mdlCnv_convertMultibyteToUnicode(logical, -1, wcLogName, 128);
mdlCnv_convertMultibyteToUnicode(description, -1, wcDescription, 128);
status = mdlRefFile_attachCoincident(&outModelRefP, refFile, wcLogName, wcDescription,
REF_FILE_LEVEL_DISPLAY_DEFAULT, snapLock, locateLock);
if (status == SUCCESS && levels != NULL)
{
/* Only set level mast for view 0 */
mdlBitMask_createFromBitArray(&levelMask, 64, levels[0], 1);
mdlBitMask_getAsString(levelCodes, 512, levelMask, 1);
mdlBitMask_free(&levelMask);
levelMask = NULL;
cnvLevelCodesToIds(levelCodes, levelIds, outModelRefP);
mdlBitMask_create(&levelMask, 0);
mdlBitMask_setFromString(levelMask, levelIds, 1, 64);
mdlView_setLevelDisplayMask(outModelRefP, 0, levelMask, TRUE);
mdlBitMask_free(&levelMask);
}
return status;
}
// Convert level codes to level ids.
// Input levelCodes and output levelIds is a set of " " or "," delimited in a string.
// The string may contain ranges too. e.g. string: 1,10-15,3,20,25-28,31-35
//------------------------------------------------------------------------------------
void cnvLevelCodesToIds(char *levelCodes, char *levelIds, DgnModelRefP pModelRef)
{
char *token;
char *rangeDelimiter;
char tempStr[512];
int pos;
ULong i, levelCodeStart, levelCodeEnd;
ULong levelId = 0;
char seps[] = " ,";
if (levelCodes == NULL || levelIds == NULL)
return;
strcpy(tempStr, levelCodes);
levelIds[0] = '\0';
token = strtok(tempStr, seps);
while (token != NULL) {
rangeDelimiter = strchr(token, '-');
if (rangeDelimiter != NULL) {
pos = rangeDelimiter - token;
rangeDelimiter++;
token[pos] = '\0';
levelCodeStart = atol(token);
levelCodeEnd = atol(rangeDelimiter);
if (levelCodeStart > 0 && levelCodeEnd > levelCodeStart) {
for (i = levelCodeStart; i <= levelCodeEnd; i++) {
if (mdlLevel_getIdFromCode(&levelId, pModelRef, i) == SUCCESS)
sprintf(&levelIds[strlen(levelIds)], "%ld,\0", levelId);
}
}
}
else {
levelCodeStart = atol(token);
if (levelCodeStart > 0) {
if (mdlLevel_getIdFromCode(&levelId, pModelRef, levelCodeStart) == SUCCESS)
sprintf(&levelIds[strlen(levelIds)], "%ld,\0", levelId);
}
}
token= strtok (NULL, seps);
}
if (strlen(levelIds) > 0)
levelIds[strlen(levelIds) - 1] = '\0';
}
//------------------------------------------------------------------------------------
// attachFileCoincident.
// To keep old code reusable, using the old parameter: unsigned short levels[8][4]
//------------------------------------------------------------------------------------
StatusInt attachFileCoincident(char *refFile,
char *logical,
char *description,
unsigned short levels[8][4],
BoolInt snapLock,
BoolInt locateLock)
{
DgnModelRefP outModelRefP;
MSWChar wcLogName[128];
MSWChar wcDescription[128];
char levelCodes[512];
char levelIds[512];
StatusInt status;
BitMask *levelMask = NULL;
mdlCnv_convertMultibyteToUnicode(logical, -1, wcLogName, 128);
mdlCnv_convertMultibyteToUnicode(description, -1, wcDescription, 128);
status = mdlRefFile_attachCoincident(&outModelRefP, refFile, wcLogName, wcDescription,
REF_FILE_LEVEL_DISPLAY_DEFAULT, snapLock, locateLock);
if (status == SUCCESS && levels != NULL)
{
/* Only set level mast for view 0 */
mdlBitMask_createFromBitArray(&levelMask, 64, levels[0], 1);
mdlBitMask_getAsString(levelCodes, 512, levelMask, 1);
mdlBitMask_free(&levelMask);
levelMask = NULL;
cnvLevelCodesToIds(levelCodes, levelIds, outModelRefP);
mdlBitMask_create(&levelMask, 0);
mdlBitMask_setFromString(levelMask, levelIds, 1, 64);
mdlView_setLevelDisplayMask(outModelRefP, 0, levelMask, TRUE);
mdlBitMask_free(&levelMask);
}
return status;
}