Строковое представление значений enum (C++ Builder)
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 10.06.03 13:47
Оценка: 21 (5)
Давненько я сюда не писал

Итак, как всегда, очередное изобретение велосипеда родилось вот из-за какой надобности:

1. Допустим, есть у меня в программе (под С++ Builder) такой вот enum:

typedef enum
 {
  One,
  Two,
  Three,
  Four 

 } TSomeEnum;


Естественно, во многих случаях работать с таким перечислением удобнее, чем с отдельным набором констант. Поехали дальше:

2. Этот самый enum — это одна из настроек моей программы (например, кол-во одновременно обрабатываемых файлов).

3. И мне нужно вывести список всех возможных значений (в строковом виде, а именно "One", "Two" etc.) этого enum'а в TListBox, например. Про возможности .NET — поручик, молчать!

Естественно, можно и ручками. А ну как я добавлю еще один элемент в enum (например, Five)? Каждый раз дописывать код

В общем, о полезности нижеприведенного решения вывод я еще не сделал , но, думаю, пригодится на досуге. Единственное НО: работает, если не указывать инициализирующее значение для элементов enum'а (т.е. писать так, как выше привел, без конструкций типа One=20).


Сырец (сорри за #define — из песни слова выкинуть не получилось):

//---------------------------------------------------------------------------
#include <Typinfo.hpp>
//---------------------------------------------------------------------------
#define IMPLEMENT_ENUM_INFO(EnumType) \
class _##EnumType : public TObject \
{ \
EnumType Fx; \
__published: \
__property EnumType X = {read=Fx}; \
public: \
 __fastcall _##EnumType() {}; \
 __fastcall ~_##EnumType() {}; \
}; \
void __fastcall EnumerateEnum(Classes::TStrings* Strings, EnumType enumType) \
{\
PTypeInfo pTypeInfo = *(GetPropInfo(__typeinfo(_##EnumType),"X"))->PropType;\
PTypeData pTypeData = GetTypeData(pTypeInfo);\
 for(int i=pTypeData->MinValue;i<=pTypeData->MaxValue;i++)\
  { \
   Strings->Add(GetEnumName(pTypeInfo,i));\
  } \
}\
//---------------------------------------------------------------------------


Пример использования:

// описываем enum'ы
//---------------------------------------------------------------------------
typedef enum
 {
  One,
  Two,
  Three,
  Four

 } TSampleEnum;
//---------------------------------------------------------------------------
typedef enum
 {
  One2,
  Two2,
  Three2

 } TSampleEnum2;
//---------------------------------------------------------------------------
// Подставляем это добро препроцессору...
//---------------------------------------------------------------------------
IMPLEMENT_ENUM_INFO(TSampleEnum);
IMPLEMENT_ENUM_INFO(TSampleEnum2);
//---------------------------------------------------------------------------

// А теперь побалуемся...

void __fastcall TForm1::Button1Click(TObject *Sender)
{
EnumerateEnum(Memo1->Lines, One); // этот  в TMemo
EnumerateEnum(ListBox1->Items,One2); // а этот - в TListBox
}
//---------------------------------------------------------------------------


Как вы уже заметили, в EnumerateEnum вторым параметром надо передавать одно из значений нужного enum'а. Первый параметр — экземпляр класса TStrings.

З.Ы. Как всегда, приведенное решение — не истина в последней инстанции. Ждем предложений/альтернатив/пр.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.