⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sem2diag.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    *data = list->size;
    bytes = 4;
    ptr  += 4;

    presparam = list->head;

    for( presparam = list->head; presparam != NULL; presparam = presparam->next ) {
        // Presparam ID or name length
        if( !(presparam->Name->ord.fFlag == 0xFF) ) {       // Presparam has name
            len     = strlen( presparam->Name->name ) + 1;
            data    = (uint_32 *)ptr;
            *data++ = 0;    // First ULONG is 0 to indicate this isn't numeric ID
            *data   = len;  // Next is string len
            ptr    += 8;
            strcpy( ptr, presparam->Name->name );
            ptr    += len;
            data    = (uint_32 *)ptr;
            *data   = -1;   // Not sure what this is
            ptr    += 4;
            bytes  += len + 12;
        } else {
            data   = (uint_32 *)ptr;
            *data  = presparam->Name->ord.wOrdinalID;
            ptr   += 4;
            bytes += 4;
        }

        // Following is the size of presparam data
        data   = (uint_32 *)ptr;
        *data  = presparam->size;
        ptr   += 4;
        bytes += 4;

        for( travptr = presparam->dataList; travptr != NULL; travptr = travptr->next ) {
            for( i = 0; i < travptr->count; i++ ) {
                if( travptr->data[i].IsString ) {
                    len    = travptr->data[i].StrLen + 1;
                    strncpy( ptr, travptr->data[i].Item.String, len ); // String is next
                    ptr   += len;
                    bytes += len;
                } else {
                    data   = (uint_32 *)ptr;
                    *data  = travptr->data[i].Item.Num;
                    ptr   += 4;
                    bytes += 4;         // Data elements are ULONGs
                }
            }
        }
    }
    list->size = bytes;

    return( bytes );
}

static uint_16 SemOS2DumpCtlData( char *ptr, DataElemList *list )
/***************************************************************/
{
    DataElemList        *travptr;
    uint_16             bytes = 0;
    uint_16             *data;
    uint_16             len;
    int                 i;

    for( travptr = list; travptr != NULL; travptr = travptr->next ) {
        for( i = 0; i < travptr->count; i++ ) {
            if( travptr->data[i].IsString ) {
                len = travptr->data[i].StrLen + 1;
                strncpy( ptr, travptr->data[i].Item.String, len );
                bytes += len;
                ptr   += len;
            } else {
                data   = (uint_16*)ptr;
                *data  = (uint_16)travptr->data[i].Item.Num;
                bytes += 2;
                ptr   += 2;
            }
        }
    }

    return( bytes );
}

static int SemOS2CalcControlSize( FullDiagCtrlListOS2 *ctrls )
/************************************************************/
{
    FullDialogBoxControlOS2 *ctrl;
    DialogBoxControl        *control;
    int                     size = 0;

    for( ctrl = ctrls->head; ctrl != NULL; ctrl = ctrl->next ) {
        control = &(ctrl->ctrl);
        size += sizeof( DialogTemplateItemOS2 );
        if( !(control->ClassID->Class & 0x80) )  // Class name length if provided
            size += strlen( control->ClassID->ClassName ) + 1;
        if( control->Text != NULL )             // Conrol text if provided
            if( control->Text->ord.fFlag == 0xFF )          // We have ID
                size += 3;
            else
                size += strlen( control->Text->name ) + 1;  // We have name
        else
            size += 1;

        size += control->ExtraBytes;
        size += SemOS2CountBytes( ctrl->dataListHead );
        size += SemOS2CountPresParams( ctrl->presParams );

        if( ctrl->children != NULL )        // Add size of all children
            size += SemOS2CalcControlSize( ctrl->children );
    }

    return size;
}

static char *SemOS2BuildTemplateArray( char *ptr, FullDiagCtrlListOS2 *ctrls )
/****************************************************************************/
{
    FullDialogBoxControlOS2     *ctrl;
    DialogBoxControl            *control;
    DialogTemplateItemOS2       *tmpl;

    /* Create the DLGTITEM array and fill in whatever data
       we know at this point.
     */
    tmpl = (DialogTemplateItemOS2 *)ptr;
    for( ctrl = ctrls->head; ctrl != NULL; ctrl = ctrl->next ) {
        control = &(ctrl->ctrl);
        tmpl->fsItemStatus  = 0;
        tmpl->offClassName  = 0;
        tmpl->offText       = 0;
        tmpl->flStyle       = control->Style;
        tmpl->x             = control->Size.x;
        tmpl->y             = control->Size.y;
        tmpl->cx            = control->Size.width;
        tmpl->cy            = control->Size.height;
        tmpl->id            = control->ID;
        tmpl->offPresParams = -1;
        tmpl->offCtlData    = -1;

        if( !(control->ClassID->Class & 0x80) ) {
            tmpl->cchClassName = strlen( control->ClassID->ClassName );
        }
        else {
            tmpl->cchClassName = 0;
            tmpl->offClassName = control->ClassID->Class & 0x7F;
        }

        if( control->Text != NULL ) {
            if( control->Text->ord.fFlag == 0xFF )
                tmpl->cchText = 3;
            else
                tmpl->cchText = strlen( control->Text->name );
        }
        else
            tmpl->cchText = 0;

        ctrl->tmpl = tmpl;  // Save the pointer to DLGTITEM so we can update it later

        ptr += sizeof( *tmpl );
        if( ctrl->children != NULL ) {   // Process all children
            ptr = SemOS2BuildTemplateArray( ptr, ctrl->children );
            tmpl->cChildren = ctrl->children->numctrls;
        }
        else
            tmpl->cChildren = 0;

        tmpl = (DialogTemplateItemOS2 *)ptr;
    }

    return ptr;
}

static char *SemOS2DumpTemplateData( char *base, char *ptr,
                                     FullDiagCtrlListOS2 *ctrls )
/***************************************************************/
{
    FullDialogBoxControlOS2     *ctrl;
    DialogBoxControl            *control;
    DialogTemplateItemOS2       *tmpl;

    /* Dump all strings etc. into the resource image and update the
       offsets as appropriate.
     */
    for( ctrl = ctrls->head; ctrl != NULL; ctrl = ctrl->next ) {
        control = &(ctrl->ctrl);
        tmpl    = ctrl->tmpl;

        // Write out class name if provided
        if( !(control->ClassID->Class & 0x80) ) {
            strcpy( ptr, control->ClassID->ClassName );
            tmpl->offClassName = ptr - base;
            ptr += tmpl->cchClassName + 1;
        }

        // IBM's RC always stores at least one character of text
        // even if no text is provided; it could be a buglet but we'll
        // do the same for compatibility.
        tmpl->offText = ptr - base;
        if( control->Text != NULL ) {
            if( control->Text->ord.fFlag == 0xFF ) {
                memcpy( ptr, control->Text->name, 3 );
                ptr += 3;
            }
            else {
                strcpy( ptr, control->Text->name );
                ptr += tmpl->cchText + 1;
            }
        }
        else {
            *ptr = '\0';
            ptr++;
        }

        // Write out class data if provided
        if( control->ExtraBytes ) {
            memcpy( ptr, &ctrl->framectl, sizeof( uint_32 ) );
            tmpl->offCtlData = ptr - base;
            ptr += control->ExtraBytes;
            // Write out class data if provided
            ptr += SemOS2DumpCtlData( ptr, ctrl->dataListHead );
        }
        else {
            if( ctrl->dataListHead ) {
                tmpl->offCtlData = ptr - base;
                ptr += SemOS2DumpCtlData( ptr, ctrl->dataListHead );
            }
        }

        if( ctrl->presParams ) {
            tmpl->offPresParams = ptr - base;
            ptr += SemOS2DumpPresParams( ptr, ctrl->presParams );
        }

        if( ctrl->children != NULL )    // Process all children
            ptr = SemOS2DumpTemplateData( base, ptr, ctrl->children );
    }

    return ptr;
}

/* The OS/2 dialog templates present us with a problem because the
   template items contain a number of offsets that are not known until
   the template is processed; this means we cannot just start spitting
   the data into a file. Instead we build an in-memory image of the
   resource (the size must be < 64K) and then dump the entire resource
   into the file - which certainly shouldn't hurt performance either.
*/
extern void SemOS2WriteDialogTemplate( WResID *name, ResMemFlags flags,
                                       uint_32 codepage,
                                       FullDiagCtrlListOS2 *ctrls )
/*********************************************************************/
{
    ResLocation              loc;
    int                      err_code;
    int                      error;
    int                      size;
    DialogHeaderOS2          *head = NULL;
    char                     *tmpl;
    char                     *ptr;

    size = sizeof( DialogHeaderOS2 ) + SemOS2CalcControlSize( ctrls );
    if( size > 65536 ) {
        // TODO: Error, template is too big
    }

    tmpl = RcMemMalloc( size );

    head = (DialogHeaderOS2 *)tmpl;
    InitOS2DialogBoxHeader( head, codepage );
    head->Size = size;
    ptr = tmpl + sizeof( DialogHeaderOS2 );

    // Create the DLGTITEM array in memory
    ptr = SemOS2BuildTemplateArray( ptr, ctrls );

    // Dump all other data into memory and update the offsets
    SemOS2DumpTemplateData( tmpl, ptr, ctrls );

    // Write the resource to file
    loc.start = SemStartResource();

    error = ResOS2WriteDlgTemplate( tmpl, size, CurrResFile.handle );
    if( error ) {
        err_code = LastWresErr();
        goto OutputWriteError;
    }

    RcMemFree( tmpl );

    loc.len = SemEndResource( loc.start );
    SemAddResourceFree( name, WResIDFromNum( OS2_RT_DIALOG ), flags, loc );

    SemOS2FreeDiagCtrlList( ctrls );

    return;

OutputWriteError:
    RcError( ERR_WRITTING_RES_FILE, CurrResFile.filename,
                strerror( err_code )  );
    ErrorHasOccured = TRUE;
    SemOS2FreeDiagCtrlList( ctrls );
    return;
} /* SemOS2WriteDialogTemplate */


extern FullDialogBoxControlOS2 *SemOS2SetControlData( ResNameOrOrdinal *name,
                    uint_32 id, DialogSizeInfo size, ResNameOrOrdinal *ctlclassname,
                    IntMask style, FullDiagCtrlListOS2 *childctls,
                    PresParamListOS2 *presparams )
/**********************************************************************************/
{
    FullDialogBoxControlOS2     *control;

    control = SemOS2InitDiagCtrl();

    control->ctrl.ID         = id;
    control->ctrl.Size       = size;
    control->ctrl.Text       = name;
    control->ctrl.ClassID    = ResNameOrOrdToControlClass( ctlclassname );
    control->ctrl.Style      = style.Value;
    control->children        = childctls;
    control->ctrl.ExtraBytes = 0;
    control->presParams      = presparams;
    RcMemFree( ctlclassname );

    return( control );
}

extern FullDialogBoxControlOS2 *SemOS2SetWindowData( FullDiagCtrlOptionsOS2 opts,
                    IntMask framectl, PresParamListOS2 *presparams,
                    FullDiagCtrlListOS2 *childctls, uint_16 token )
/*******************************************************************************/
{
    FullDialogBoxControlOS2 *control;
    uint_32                 style;
    uint_32                 defstyle;
    uint_32                 style_mask; /* for the style of the control */
    uint_32                 style_value;

    control = SemOS2InitDiagCtrl();

    if( token == Y_FRAME ) {
        defstyle = OS2_WS_VISIBLE;
    } else {
        /* it's gotta be a Y_DIALOG */
        defstyle = OS2_WS_CLIPSIBLINGS | OS2_WS_SAVEBITS | OS2_FS_DLGBORDER;
    }
    style_mask  = opts.Style.Mask;
    style_value = opts.Style.Value;
    style = (style_mask & style_value) | (~style_mask & defstyle);

    /* IBM's RC is trying to be clever */
    if( framectl.Value & OS2_FCF_SIZEBORDER )
        style &= ~OS2_FS_DLGBORDER;

    control->ctrl.ID         = opts.ID;
    control->ctrl.Size       = opts.Size;
    control->ctrl.Text       = opts.Text;
    control->ctrl.ClassID    = ResNumToControlClass( OS2_WC_FRAME );
    control->ctrl.Style      = style;
    control->children        = childctls;
    control->ctrl.ExtraBytes = 4;   // Frame control data
    control->framectl        = framectl.Value;
    control->presParams      = presparams;

    return( control );
}

extern void SemOS2AddDlgincResource( WResID *name, char *filename )
/*****************************************************************/
{
    ResLocation loc;
    int         error, err_code;

    loc.start = SemStartResource();
    error = ResWriteString( filename, FALSE, CurrResFile.handle );
    if( error ) {
        err_code = LastWresErr();
        goto OutputWriteError;
    }
    loc.len = SemEndResource( loc.start );
    SemAddResourceFree( name, WResIDFromNum( OS2_RT_DLGINCLUDE ),
                        MEMFLAG_DISCARDABLE | MEMFLAG_MOVEABLE | MEMFLAG_PURE,
                        loc );
    RcMemFree( filename );
    return;

OutputWriteError:
    RcError( ERR_WRITTING_RES_FILE, CurrResFile.filename,
             strerror( err_code ) );
    ErrorHasOccured = TRUE;
    RcMemFree( filename );
    return;
}

extern PresParamListOS2 *SemOS2NewPresParamList( PresParamsOS2 presparam )
/************************************************************************/
{
    PresParamListOS2    *newlist;

    newlist = RcMemMalloc( sizeof( PresParamListOS2 ) );
    newlist->head = NULL;
    newlist->tail = NULL;
    return( SemOS2AppendPresParam( newlist, presparam ) );
}

extern PresParamListOS2 *SemOS2AppendPresParam( PresParamListOS2 *list,
                                                 PresParamsOS2 presparams )
/*************************************************************************/
{
    PresParamsOS2       *params;

    params = RcMemMalloc( sizeof( PresParamsOS2 ) );
    *params = presparams;
    ResAddLLItemAtEnd( (void **)&(list->head), (void **)&(list->tail), params );
    return( list );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -