Краткое: как убедиться, что «статически» объявленные идентификаторы для событий и/или виджетов не сталкиваются с проектом среднего и большего размера?Проблема с идентификатором WxWidget
... и долго:
Один из способов борьбы с идентификаторами в WxWidgets это объявить их с помощью перечислений на компиляции-единицы, т.е. в исходном файле-виджета. Однако, когда идентификаторы используются в обработке событий WxWidgets, они должны быть или должны быть глобально уникальными. Некоторым не обязательно быть глобально уникальными, но я думаю, что это безопаснее, если все они есть, иначе есть потенциал для выполнения - «столкновения», которые не вызывают никакого предупреждения - событие просто обрабатывается другим виджетами. К сожалению, я наткнулся на эту проблему пару раз (унаследованная база кода) - их трудно отследить и, скорее, раздражать, если я чего-то не упускаю. Во всяком случае, я хочу разобраться, раз и навсегда :-)
Я знаю, что WxWidgets также поддерживает динамическое связывание, и мы/я используем его в некоторых местах. Однако изменение кода для всех «статически» объявленных идентификаторов было бы слишком большим усилием. По сути, у меня много разных исходных файлов (> 60), где есть перечисления, начинающиеся со значения wxID_HIGHEST с некоторым (по-видимому) произвольным смещением. Я думаю, что смещение произвольное, вероятно, было добавлено, чтобы исправить отдельные случаи вышеуказанной проблемы с ID-столкновением. В любом случае, перечисление всех перечислений в один файл/перечисление кажется немного уродливым, потому что это будет невероятно длинный список.
Итак, вот что я думал: я поддерживаю MIN/MAX-ID для разных виджетов в одном заголовочном файле, используя единую перечисление, и предоставляю два макроса, которые BEGIN и END определяют идентификатор ID. END-макрос должен также проверить, что объявленный MAX-ID не будет превышен. Это звучит разумно? Каковы распространенные способы решения проблемы ID-столкновения?
Мое предназначение решения выглядит примерно так. Я планирую добавить функцию, которая имеет дело с идентификаторами для динамической привязки. Я знаю, что WxWidgets предоставляет связанную функциональность с подсчетом ID-ссылок, однако я думал, что пока я нахожусь ... Он предназначен как можно более независимый от платформы.
#include <wx/defs.h>
#define NUM_OF_DYNAMIC_AUTO_IDS 500
namespace WxWidgetIdHelper {
enum WxWidgetIDsEnum {
MIN_DYNAMIC_AUTO_ID = wxID_HIGHEST + 1,
MAX_DYNAMIC_AUTO_ID = MIN_DYNAMIC_AUTO_ID + NUM_OF_DYNAMIC_AUTO_IDS,
STATIC_ID_OFFSET = MAX_DYNAMIC_AUTO_ID + 1,
Widget1_MIN_ID = STATIC_ID_OFFSET + 1,
Widget1_MAX_ID = Widget1_MIN_ID + 20,
Widget2_MIN_ID = Widget1_MAX_ID + 1,
Widget2_MAX_ID = Widget2_MIN_ID + 20,
...
};
template<bool> struct MaxIdCheck;
template<> struct MaxIdCheck<false> {};
}
#define BEGIN_WXWIDGET_ID_ENUM(CLASSNAME) \
enum CLASSNAME##_##WXWIDGET_IDs { \
CLASSNAME##_##MIN_ID = WxWidgetIdHelper##::##CLASSNAME##_##MIN_ID,
#define END_WXWIDGET_ID_ENUM(CLASSNAME) CLASSNAME##_##MAX_ID }; \
WxWidgetIdHelper::MaxIdCheck< \
(CLASSNAME##_##MAX_ID>WxWidgetIdHelper::CLASSNAME##_##MAX_ID) > \
INCREASE##_##CLASSNAME##_##MAX_ID_in_WxWidgetIdHelper_h;
Большое спасибо. Хотя мне нужен разумно быстрый и элегантный способ решения (унаследованного) беспорядка, с которым я имею дело. Все «живет» под одним верхним уровнем окна, таким образом, глобально уникальные идентификаторы будут более безопасными, ИМХО. То, как все это висит вместе, является своего рода не оптимальным, частично непродуманным, плохо «выращенным», не особенно ухоженным - у меня нет времени прямо сейчас для правильной очистки и повторного факторинга. IDs-To-Bind() прост: не так много, если идентификаторы используются в операторах switch в OnCommandEvent() или аналогичных методах, а также для поиска элементов управления или мне что-то не хватает (?). –
Если вам нужно обрабатывать события из нескольких элементов управления в одном методе, вы можете использовать 'wxEvent :: GetEventObject()', чтобы различать их. Это в основном повторяет (обязательно уникальный) указатель управления как идентификатор. –
Я нашел этот ответ, когда искал способ привязки к элементам меню без использования идентификаторов (мне тоже не нравятся). Наиболее логичным решением для меня было бы: (1) получить указатель на элемент меню внутри обработчика события из объекта 'wxCommantEvent' или (2) привязать непосредственно к' wxMenuItem'. И мне интересно, почему не представляется возможным, по крайней мере, не в wxWidgets 3.1. Или я ошибаюсь? –