단락 : 이벤트 및/또는 위젯에 대해 "정적으로"선언 된 ID가 중형 및 대형 프로젝트간에 충돌하지 않는지 확인하는 방법은 무엇입니까? WxWidget ID 문제
... 그리고 긴 : wxWidgets에있는 ID를 다루는한 가지 방법은 위젯의 소스 파일에서 컴파일 단위, 즉 당 열거에 의해를 선언하는 것입니다. 그러나 ID가 WxWidgets의 이벤트 처리에 사용될 때는 전역 적으로 고유해야합니다. 일부는 전 세계적으로 고유 할 필요는 없지만 모든 것이 안전하다면 런타임에 잠재적 인 가능성이 있습니다. "충돌"은 경고를 유발하지 않습니다. 이벤트는 단순히 다른 위젯에 의해 처리됩니다. 불행히도, 나는이 문제를 두 번이나 보았습니다. (상속 된 코드베이스) - 뭔가를 놓치지 않는 한 추적하기가 어렵고 짜증납니다. 어쨌든, 이것을 한 번에 정렬하고 싶습니다. :-)
나는 WxWidgets도 동적 바인딩을 지원하며, 우리는 이것을 일부 장소에서 사용합니다. 그러나 모든 "정적으로"선언 된 ID에 대한 코드를 변경하는 것은 너무 많은 노력입니다. 따라서 본질적으로 wxID_HIGHEST에서 열거 된 열거 형 (겉으로보기에) 임의의 오프셋이있는 많은 개별 소스 파일 (> 60)이 있습니다. 오프셋이 임의적이라고 생각합니다. 위의 ID 충돌 문제에 대한 단일 사례를 수정하기 위해 추가 된 것 같습니다. 어쨌든 모든 열거 형을 하나의 파일/열거 형에 넣는 것은 믿을 수 없을 정도로 긴 목록이므로 약간 추한 것 같습니다.
여기 제가 생각해 봤습니다. 하나의 열거 형을 사용하여 하나의 헤더 파일에 여러 위젯의 MIN/MAX-ID를 유지 관리하고 주어진 ID 열거 형을 시작하고 끝내는 두 개의 매크로를 제공합니다. END-macro는 선언 된 MAX-ID가 초과되지 않았는지 확인해야합니다. 그게 합리적이라고 생각하니? ID 충돌 문제를 해결하는 일반적인 방법은 무엇입니까?
내 솔루션은 다음과 같습니다. 동적 바인딩을위한 ID를 처리하는 함수를 추가 할 계획입니다. WxWindows는 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;
감사합니다. 비록 합리적으로 빠르고 우아한 방식으로 (상속받은) 난장판을 해결할 필요가 있긴하지만 내가 다루고있다. 하나의 최상위 창 아래에 모든 것이 "살아"있으므로 전 세계적으로 고유 한 ID가 더 안전합니다. IMHO. 이 모든 것들이 함께 어울리는 방식은 다소 차선책이며, 부분적으로 아프고, 잘 성장하지 못하고, 잘 유지되지 않습니다. 지금은 적절한 정리 및 재구성을 할 시간이 없습니다. ID-To-Bind()는 간단합니다. ID가 OnCommandEvent() 또는 유사한 메소드의 전환 명령문에서 사용되거나 컨트롤을 찾는 데 사용되거나, (?) 무엇인가 빠졌습니까? –
하나의 메소드에서 여러 컨트롤의 이벤트를 처리해야하는 경우'wxEvent :: GetEventObject() '를 사용하여 이벤트를 구분할 수 있습니다. 이것은 기본적으로 (반드시 고유 한) 제어 포인터를 ID로 재사용합니다. –
ID를 사용하지 않고 메뉴 항목에 바인딩하는 방법을 찾을 때이 답변을 발견했습니다 (나는 싫어합니다). 가장 논리적 인 해결책은 (1) 'wxCommantEvent' 객체에서 이벤트 핸들러 내의 메뉴 항목에 대한 포인터를 얻거나 (2)'wxMenuItem'에 직접 바인드 할 수있는 것입니다. 적어도 왜 wxWidgets 3.1에서는 가능하지 않은지 궁금합니다. 아니면 내가 틀렸어? –