How to get the label of a push button?

Hi, There,

There is a built-in MDL function mdlDialog_itemSetLabel documented. Is there a mdlDialog_itemGetLabel function. I need to retrieve pushbutton labels.

Any suggestions will be greatly appreciated.

Ken

  • Spelunking in the MDL header files

    The API is the best way to get information, but in this case it looks like Bentley decided that few people would want to retrieve an item's label. When the API falters, we have to dive into the MDL header files.

    The header that contains the struct definitions for dialogs, dialog items, and dialog messages is <dlogitem.h>. Some of those structs contain unions whose size makes them quite daunting at first sight, and at second sight too, for that matter.

    The struct that you're interested in is, unsurprisingly, dialogitem. What is surprising is that it doesn't seem to contain very much, and in particular it doesn't appear to contain what you are seeking, the item's label.

    All run-time items have data stored in a dynamically-allocated chunk of memory that you get at through the item's raw item header pointer …

    RawItemHdr *rawItemP;

    Raw Item Header

    Continue searching <dlogitem.h> to find the definition of rawitemhdr (large sections omitted here)…

    struct rawitemhdr
    {
        …
    char *labelP; /* items label or NULL; Obsolete in V8 */
        …
    /* MSWChar/Unicode Support --- */
    ValueDescr labelValue; /* item's label */
        …
    };

    The first thing you notice is that labelP is obsolete. In days of old, MicroStation supported only multibyte (i.e. char*) strings. Bentley Systems, wanting to ease the work of porting from V7 to V8, retained that field but declared it obsolete. Search further into the struct to find the labelValue, new for V8, which is what you want. labelValue is yet another struct, a ValueDescr.

    MDL ValueDescr

    ValueDescr is an MDL variant (a union of data types). You'll find its definition in header file <vartypes.h>. It contains a formatType member, which is one of the #defined values FMT_XXX. In this case we hope it's either FMT_MSWCHAR or FMT_STRING. Once you know the data type stored in the union, you know which member to interrogate: either charPFormat or wCharPFormat.

    How to Get an Item Label

    If you followed all that, you know now how to get an item label …

    1. Get a dialog item
    2. Follow the pointer to the raw item data
    3. Follow the pointer to the labelValue
    4. Determine the data type stored in the labelValue
    5. Copy the char* or MSWChar* string to your buffer

    Something like this (untested code) …

     #include <msdialog.fdf> // #includes <dlogitem.h>
    #include <msritem.fdf>
    DialogItem* item = mdlDialog_itemGetByXxx (...);
    // For V8.5, you can only follow the pointer
    RawItemHdr* innards = item->rawItemP;
    // For V8.9 and later, you can use
    // mdlDialog_itemGetRawItemHdr (item);

    ValueDescr* label = &innards->labelValue;
    int formatType = label->formatType;
    switch (formatType)
    {
       case FMT_STRING:
         strcpy (myMultiByteBuffer, label->value.charPFormat);
         break;
       case FMT_STRING:
         wcscpy (myUnicodeBuffer, label->value.wCharPFormat);
         break;
       default:
          // unexpected data type for item label
         break;
    }
    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • Hi,

    there are library functions to get the Label:

    Assuming you already have your dialog item (di):

    ValueDescr vd;

    RawItemHdr *rp=mdlDialog_itemGetRawItemHdr(di);

    if (mdlDialog_rItemLabelGet(rp,&vd)==SUCCESS) {

      printf("%s",vd.value.charPFormat);

    }

    Best regards,

    Stefan.

  • Hi, Stefan,

    Thanks for your reply. However, I could not fund this function in the MDL Programmer Guide. But I will try to use it see how it goes. This seems a easier way to get the label than Jon suggested.

    Best regards,

    Ken

  • Unknown said:
    I could not fund this function in the MDL Programmer Guide

    mdlDialog_itemGetRawItemHdr was introduced with MicroStation version 8.9.3.  You have posted to the 2004 Edition Forum, which is version 8.5: the function is not published for your version of MicroStation.

    Unknown said:
    This seems a easier way to get the label than Jon suggested

    Well, you have two choices:

    1. Wait until you've moved on to MicroStation version 8.9.3 or later, when the function is available
    2. Use the pointer dereferencing approach I've posted.  You may be reassured by this comment in the documentation for that function: "Code that can use C data structures does not need this. This function is provided to support languages such as VBA that can not use complicated C data structures"

     
    Regards, Jon Summers
    LA Solutions

  • Hi, Jon,

    Thanks for your reply. I did not realized that this function is only available on V8i.

    Best Regards,

    Ken

  • Hi, Jon,

    The following is my function to get the label of dialogue box item. This function can be called from a hook function easily. Thanks for you help in making all MDL programmers life much more enjoyable:

    void myDialog_getItemLabel

    (

       DialogItemMessage *dimP

    )

    {

    ValueUnion value;

    DialogItem      *diP = NULL;

    RawItemHdr* innards = NULL;

    ValueDescr* label = NULL;

    int formatType;

    char myMultiByteBuffer[254];

    MSWChar myUnicodeBuffer[254];

    diP = dimP->dialogItemP;

    innards = diP->rawItemP;

    // For V8.9 and later, you can use // mdlDialog_itemGetRawItemHdr (item);

    label = &innards->labelValue;

    formatType = label->formatType;

    switch (formatType)

    {

       case FMT_STRING:

         strcpy (myMultiByteBuffer, label->value.charPFormat);

       break;

       case FMT_MSWCHAR:

           wcscpy (myUnicodeBuffer, label->value.wCharPFormat);

       break;

       default:

       // unexpected data type for item label

       break;

       }                

    }   // end of myDialog_getItemLabel()

    Regards,

    Ken