📄 sem2diag.c
字号:
*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 + -