简而言之:如何确保“静态”声明的事件和/或小部件的 ID 在大中型项目中不会发生冲突?
......还有很长的:
在 WxWidgets 中处理 ID 的一种方法是通过每个编译单元的枚举来声明它们,即在小部件的源文件中。但是,当 ID 用于 WxWidgets 的事件处理时,它们应该或必须是全局唯一的。有些不需要是全局唯一的,但我认为如果它们都是唯一的,它会更安全,否则可能会出现运行时 - “冲突”,不会触发任何警告 - 事件只是由另一个小部件处理。不幸的是,我多次遇到这个问题(继承的代码库)——它们很难追踪而且很烦人,除非我遗漏了一些东西。无论如何,我想一劳永逸地解决这个问题:-)
我知道,WxWidgets 也支持动态绑定,我们/我在某些地方使用它。但是,更改所有“静态”声明的 ID 的代码将是一个很大的工作量。所以基本上我拥有的是许多单独的源文件(> 60),其中有从 wxID_HIGHEST 开始的枚举,带有一些(看似)任意偏移量。我确实认为偏移量是任意的,可能是为了解决上述 ID 冲突问题的单个情况而添加的。无论如何,将所有枚举放入单个文件/枚举似乎有点难看,因为这将是一个非常长的列表。
所以这就是我一直在想的:我使用单个枚举在单个头文件中维护不同小部件的 MIN/MAX-ID,并提供两个宏来开始和结束给定的 ID 枚举。END 宏还应检查声明的 MAX-ID 是否未超过。这听起来合理吗?解决 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;