Я сделал это в классе "DomainEditor" для этого огромного приложения, которое я написал. Все таблицы моего типа (домена) в базе данных могут редактироваться администраторами программы, и, поскольку клиенты называют некоторые типы по именам, отличным от имен других, я создал диалог, который позволил вам их редактировать. Ну, я не хотел создавать редактор для 15+ типов доменов, поэтому я написал суперкласс, к которому я мог бы привести каждый класс, и используя указатели, я мог бы делать простые вызовы для каждой таблицы доменов. Каждый из них поддерживает одинаковые свойства, описание (имя), идентификатор, флаг неактивности и флаг обязательности. Итак, код начался с макроса для настройки моих вызовов:
#define DomainList(Class, Description, First, Next, Item, UpdateItem, DeleteItem, IsItemRequired, MaxLength) { \
CWFLHandler *handler = new CWFLHandler; \
handler->pWFL = new Class;\
handler->LoadFirstType = (LoadFirst)&Class::First;\
handler->LoadNextType = (LoadNext)&Class::Next;\
handler->LoadType = (Load)&Class::Item;\
handler->UpdateType = (Update)&Class::UpdateItem;\
handler->DeleteType = (Delete)&Class::DeleteItem;\
handler->IsRequiredType= (IsRequired)&Class::IsItemRequired; \
handler->MAX_LENGTH = MaxLength;\
PopulateListBox(m_Domain, Description, (long)handler); }\
Затем много обращений к макросу: (вот только один)
DomainList(CConfigWFL, "Application Parameter Types", LoadFirstParameterType, LoadNextParameterType, LoadParameterTypeByTypeId, UpdateParameterType, DeleteParameterType, IsParameterTypeRequired, LEN_APPL_PARAMETER_DESC);
Затем все запросы на редактирование данных были обычными, и мне не нужно было вообще дублировать код ...
Например, чтобы заполнить список выбранным элементом в DropDownList (заполняется макросом), код должен выглядеть следующим образом:
if((pWFLPtr->pWFL->*pWFLPtr->LoadFirstType)(true))
{
do
{
m_Grid.AddGridRow();
m_Grid.SetCheck(COLUMN_SYSTEM, (pWFLPtr->pWFL->*pWFLPtr->IsRequiredType)(pWFLPtr->pWFL->TypeId));
m_Grid.SetCheck(COLUMN_STATUS, pWFLPtr->pWFL->InactiveIndc == false);
m_Grid.AddTextToGrid(COLUMN_NAME, pWFLPtr->pWFL->TypeDesc);
m_Grid.AddTextToGrid(COLUMN_DEBUG, pWFLPtr->pWFL->TypeId);
m_Grid.AddTextToGrid(COLUMN_ID, pWFLPtr->pWFL->TypeId);
}
while((pWFLPtr->pWFL->*pWFLPtr->LoadNextType)());
Конечно, все это было сохранено в классе, который был частью диалога. И я просто создал новые экземпляры класса, сохранил их в элементе ItemData ListBox. Поэтому мне пришлось все это очистить, когда диалоговое окно закрылось ... Однако я оставил этот код вне этого сообщения.
Класс для хранения всего этого был определен как:
typedef bool (CMyWFL::*LoadFirst)(bool);
typedef bool (CMyWFL::*LoadNext)();
typedef bool (CMyWFL::*Load)(long);
typedef bool (CMyWFL::*Update)(long, const char*, bool);
typedef bool (CMyWFL::*Delete)(long);
typedef bool (CMyWFL::*IsRequired)(long);
class CWFLHandler {
public:
CWFLHandler() {};
~CWFLHandler() { if(pWFL) delete pWFL; }
CMyWFL *pWFL;
LoadFirst LoadFirstType;
LoadNext LoadNextType;
Load LoadType;
Update UpdateType;
Delete DeleteType;
IsRequired IsRequiredType;
int MAX_LENGTH;
};
CWFLHandler *pWFLPtr;
Благодаря всей этой работе было действительно приятно иметь возможность добавлять новые домены в приложение с очень небольшим трудом, чтобы добавить их в редактор доменов ... Возможно, был лучший способ, я не знаю. Но я пошел этим путем, и он работал ОЧЕНЬ хорошо для меня, и ИМХО, это было очень креативно ...:)