2010-04-08 5 views
2

ATL을 사용하여 만든 사용자 지정 단추 컨트롤이 있습니다. 이 컨트롤은 일부 복합 컨트롤과 많은 대화 상자에서 사용됩니다. 방금 버튼 컨트롤에 몇 가지 새로운 속성을 추가 한 다음, 사용했던 모든 컨트롤과 대화 상자를 업데이트해야한다는 것을 알았습니다. 이것은 정말 가난한 상황이므로 더 나은 일을 할 수 있을지 궁금해했습니다.ATL 컨트롤의 지속성을 어떻게 증명할 것인가?

class ATL_NO_VTABLE CSMButton : 
    public CComObjectRootEx<CComSingleThreadModel>, 
    public CStockPropImpl<CSMButton, ISMButton>, 
    public IPersistStreamInitImpl<CSMButton>, 
    public IOleControlImpl<CSMButton>, 
    public IOleObjectImpl<CSMButton>, 
    public IOleInPlaceActiveObjectImpl<CSMButton>, 
    public IViewObjectExImpl<CSMButton>, 
    public IOleInPlaceObjectWindowlessImpl<CSMButton>, 
    public ISupportErrorInfo, 
    public IConnectionPointContainerImpl<CSMButton>, 
    public IConnectionPointImpl<CSMButton, &DIID__ISMButtonEvents>, 
    public CProxy_ISMButtonEvents<CSMButton>, 
    public IPersistStorageImpl<CSMButton>, 
    public ISpecifyPropertyPagesImpl<CSMButton>, 
    public IQuickActivateImpl<CSMButton>, 
#ifndef _WIN32_WCE 
    public IDataObjectImpl<CSMButton>, 
#endif 
    public IProvideClassInfo2Impl<&CLSID_SMButton, &__uuidof(_ISMButtonEvents), &LIBID_BaseControlsLib>, 
#ifdef _WIN32_WCE // IObjectSafety is required on Windows CE for the control to be loaded correctly 
    public IObjectSafetyImpl<CSMButton, INTERFACESAFE_FOR_UNTRUSTED_CALLER>, 
#endif 
    public CComCoClass<CSMButton, &CLSID_SMButton>, 
    public CComControl<CSMButton> 
{ 
... 
BEGIN_COM_MAP(CSMButton) 
    COM_INTERFACE_ENTRY(ISMButton) 
    COM_INTERFACE_ENTRY(IDispatch) 
    COM_INTERFACE_ENTRY(IViewObjectEx) 
    COM_INTERFACE_ENTRY(IViewObject2) 
    COM_INTERFACE_ENTRY(IViewObject) 
    COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless) 
    COM_INTERFACE_ENTRY(IOleInPlaceObject) 
    COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless) 
    COM_INTERFACE_ENTRY(IOleInPlaceActiveObject) 
    COM_INTERFACE_ENTRY(IOleControl) 
    COM_INTERFACE_ENTRY(IOleObject) 
    COM_INTERFACE_ENTRY(IPersistStreamInit) 
    COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit) 
    COM_INTERFACE_ENTRY(ISupportErrorInfo) 
    COM_INTERFACE_ENTRY(IConnectionPointContainer) 
    COM_INTERFACE_ENTRY(ISpecifyPropertyPages) 
    COM_INTERFACE_ENTRY(IQuickActivate) 
    COM_INTERFACE_ENTRY(IPersistStorage) 
#ifndef _WIN32_WCE 
    COM_INTERFACE_ENTRY(IDataObject) 
#endif 
    COM_INTERFACE_ENTRY(IProvideClassInfo) 
    COM_INTERFACE_ENTRY(IProvideClassInfo2) 
#ifdef _WIN32_WCE // IObjectSafety is required on Windows CE for the control to be loaded correctly 
    COM_INTERFACE_ENTRY_IID(IID_IObjectSafety, IObjectSafety) 
#endif 
END_COM_MAP() 

BEGIN_PROP_MAP(CSMButton) 
    PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4) 
    PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4) 
    PROP_ENTRY_TYPE("Caption", DISPID_CAPTION, CLSID_NULL, VT_BSTR) 
    PROP_ENTRY_TYPE("Colour", DISPID_COLOUR, CLSID_NULL, VT_COLOR) 
    PROP_ENTRY_TYPE("ButtonType", DISPID_BUTTONTYPE, CLSID_NULL, VT_I4) 
    PROP_ENTRY_TYPE("Toggle", DISPID_TOGGLE, CLSID_NULL, VT_BOOL) 
    PROP_ENTRY_TYPE("Down", DISPID_DOWN, CLSID_NULL, VT_BOOL) 
    // Example entries 
    // PROP_ENTRY_TYPE("Property Name", dispid, clsid, vtType) 
    // PROP_PAGE(CLSID_StockColorPage) 
END_PROP_MAP() 

두 VT_BOOLs 내가 추가 한 것입니다 : 여기

코드의 몇 가지 관련 비트입니다. 이를 수행하고 컨트롤을 작성한 후 런타임에 대화 상자를 표시 할 때 어설 션을 받았고 Visual Studio에서 대화 상자를 열면 경고가 표시되어 대화 상자를 다시 저장해야했습니다. 그러면 대화 상자가 런타임에 제대로 작동했습니다.

이 이유는 대화 상자가 자원의 이진 스트림으로 속성을 저장했으며 새로운 속성이 추가되면 더 이상 컨트롤을 완전히 초기화 할 수있는 충분한 데이터가 없다고 생각합니다. 이 경우에 원하는 동작은 설정되어있는 속성 값이며 나머지 속성은 기본값을 가져야합니다. 어떻게이 일을 성취 할 수 있습니까?

그리고 아니, 나는 간단한 일을 구현하기 위해 약간 ATL 지속성 클래스를 수정하는 데 사용

+0

생성자에서 속성의 기본값을 설정하기 만하면됩니다. –

+0

나는 그것을했지만 대화 상자 리소스에서 이진 데이터를로드하려고 할 때 런타임에 어설 션을 얻는다. 어설 션을 해결하려면 대화 상자 편집기로 가서 컨트롤을 다시 저장해야합니다. – markh44

답변

2

:-(.NET을 사용할 수 없습니다. 우리가있는 경우 이행 점검을 각 속성을 시작하기 전에, 스트림에서로드 할 때 이미 스트림의 끝 부분에 있습니다. 그리고 무제한 속성이 기본적으로 초기화 된 채로 있다고 가정하면 루프를 종료합니다.

거기에서 새 속성을 추가하고 이전 버전과의 호환성을 유지할 수 있습니다. 속성을 제거해야하는 경우, 지도에서 제거하지 말고 항목을 떠나야하지만 가짜 속성 설정자를 가리킬 수 있으므로 이전 버전의 컨트롤에서 저장 한 속성에 대한 지속성 값이있는 경우 오류가 발생하지 않고 폐기됩니다.

희망이 도움이됩니다.

+0

그것은 더 이상 중요하지 않습니다 (적어도 나에게!)하지만 당신의 대답은 그럴듯하게 들립니다. 다행히 그것은 다른 누군가를 도울 것입니다. – markh44

관련 문제