In the simplest case, an application can create a resource and add it to a resource file simply by defining the resource as a structure in the application's local memory, initializing it, and finally adding it using mdlResource_add. This method (demonstrated below) does not demonstrate how to handle variable sized arrays, which must be buffered before being added to a resource file.
The following function also shows the incoming resource being updated to reflect the date last accessed via the time function and then being rewritten to the resource file.
Working with resources containing variable sized arrays means that the application is required to know where in the resource structure it is at all times, or needs to calculate the proper position using mdlDialog_fixResourceAddress as described above.Once you know how to traverse a structure and how the structure is put together, modifying and creating the structure becomes relatively straightforward.
The key areas to be concerned about when doing this are:
-
Once mdlDialog_fixResourceAddress is required, it must continue to be used from that point forward.
-
Remember that variable sized arrays are stored as a long length N followed by N instances of the array entry.Note that variable sized character arrays are always NULL terminated.This means that every variable sized character array has a length of 1 plus the number of characters in the array - an empty array has a length of 1 and a single entry set to 0.
-
When creating new resources, allocate a memory area that will be large enough to contain the whole resource structure.
-
When resizing resources, do the same as above, copy the resource into the new area, resize the resource, and then copy the data back into the resized resource.
The following sample function performs both the modification and creation of a text item.
-----------------------------------------------------------------+
| |
| name updateAndCreateTextRsc |
| |
| This
function will update a text resource which was passed
in |
| and also create a new text resource |
| |
| author BSI 10/92 |
| |
| typedef struct ditem_textrsc |
| { |
| long synonymsId; |
| long itemHookId; |
| long itemHookArg; |
| char formatToDisplay[16];
| from internal
| char formatToInternal[16];
| display str
| char minimum[16];
| char maximum[16];
| #if defined (resource) |
| char label[]; |
| char accessStr[]; |
| #else |
| long labelLength; |
| char label[1]; |
| #endif |
| |
+------------------------------------------------------------
Public void updateAndCreateTextRsc
(
long rscId,
void *rsrcP
)
{
long baseRscSize, itemRscSize;
void *rscP;
void *tmpRscP, *auxInfoP;
long sAuxInfo;
if (rsrcP)
{
sAuxInfo = *((long *) tmpRscP) + sizeof(long);
auxInfoP = malloc((int) sAuxInfo);
memcpy(auxInfoP, tmpRscP, (int) sAuxInfo);
(
char *) nrsrcP->
label + strlen(dialogP->text) + 1,
sizeof(long)) - rsrcP);
(char *) (baseRscSize + sAuxInfo), sizeof(long));
if (!nrsrcP)
{
sprintf(dialogP->text, "Error on resize (temp): %d",
}
nrsrcP->
attributes = dialogP->itemAttributes & 0x0ffff;
nrsrcP->
mask = dialogP->mask;
nrsrcP->
maxSize = dialogP->textAttrs.maxSize & 0x0ff;
newdiRP->itemArg = dialogP->itemArg;
if (!dialogP->textAttrs.max[0])
{
if (dialogP->textAttrs.min[0])
strcpy(dialogP->textAttrs.max,
dialogP->textAttrs.min);
}
else
{
if (!dialogP->textAttrs.min[0])
strcpy(dialogP->textAttrs.min,
dialogP->textAttrs.max);
}
strcpy(nrsrcP->
minimum, dialogP->textAttrs.min);
strcpy(nrsrcP->
maximum, dialogP->textAttrs.max);
if (strlen(dialogP->text))
strcpy(nrsrcP->
label, dialogP->text);
else
sizeof(long));
memcpy(rscP, auxInfoP, sAuxInfo);
free(auxInfoP);
}
baseRscSize =
(
char *) nrsrcP->
label + nrsrcP->labelLen + strlen(
"-New"),
sizeof(long)) - nrsrcP);
(char *) (baseRscSize + sizeof(long) + 1,
sizeof(long));
the resource file
if (newTextRscP = malloc(itemRscSize))
{
memset(newTextRscP, 0, itemRscSize);
newdiRP->itemArg =
NOARG;
newTextRscP->
labelLength = nrsrcP->labelLen + strlen(
"-New");
strcat(newTextRscP->
label,
"-New");
((char *) newTextRscP,
(
char *) newTextRscP->
label +
(long *) rscP = 1L;
newTextRscP, itemRscSize,
NULL);
}
}