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
可以如下方法获取:
double GetUnit()
{
    
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
->= 0.0;
        globalOrigin
->= 0.0;
        globalOrigin
->= 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.dhdr.props.b.l  改为 el.ehdr.locked;
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;
}

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 */
);

但是在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, 
164);
        mdlView_setLevelDisplayMask(outModelRefP, 
0, levelMask, TRUE); 
        mdlBitMask_free(
&levelMask);
    }

    
return status;
}