Is there an easier way to display the struct fields and their corresponding values in RichEdit control?
This is what I am doing now:
<
There is no way to iterate the members of a struct unless you build your own metadata to describe the struct. The C++ compiler simply doesn't emit the information you would need automatically.
However, with a bit of macro magic, you can build the metadata you would need pretty easily. I wrote some code to do this (actually a full blown Windows custom control) many years ago and I still use it all the time.
The basic trick is to use a bit macro magic of get the compiler to help you build the metadata.
// this is the structure I want to iterate
typedef struct {
int foo;
char bar[16];
} StructIWantToIterate;
// this is the metadata I need for each field of the structure
typedef struct {
char * pszFieldName;
size_t oFieldOffset;
size_t cbFieldSize;
int eType;
} MyStructMeta;
// these are the field types I need to handle.
enum {
type_is_int,
type_is_char,
};
// these macros help to emit the metadata
#define NUMELMS(ary) (sizeof(ary)/(sizeof(ary)[0]))
#define FIELDOFF(tag,fld) ((size_t)&(((tag *)0)->fld))
#define FIELDSIZ(tag,fld) sizeof(((tag *)0)->fld)
#define STDFLD(tag,fld,as) #fld, FIELDOFF(tag,fld), FIELDSIZ(tag,fld), as
// now we declare the metadata for the StructIWantToIterate structure
#undef MYFLD
#define MYFLD(fld,as) STDFLD(StructIWantToIterate,fld,as)
static const MyStructMeta aMeta[] = {
MYFLD(foo, type_is_int), // expands to "foo", 0, sizeof(int), type_is_int
MYFLD(bar, type_is_char),// expands to "bar", sizeof(int), 16, type_is_char
};
// and when we want to do the iteration, assume ptr is a pointer to an instance
// of StructIWantToIterate
for (int ii = 0; ii < NUMELMS(aMeta); ++ii)
{
char szLine[100]; // pick your own worst case line size.
// get a pointer to the current field within the struct
void * pfld = ((byte*)ptr) + aMeta[ii].oFieldOffset;
// print out the field data based on the type_is_xxx information
switch (aMeta[ii].eType)
{
case type_is_int:
sprintf(szLine, "%s : %d", aMeta[ii].pszFieldName, *(int*)pfld);
break;
case type_is_char:
sprintf(szLine, "%s : %*s",
aMeta[ii].pszFieldName,
aMeta[ii].cbFieldSize,
pfld);
break;
}
// send it to the richedit control
RichEdit1->Lines->Append(asLine);
}