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 지속성 클래스를 수정하는 데 사용
생성자에서 속성의 기본값을 설정하기 만하면됩니다. –
나는 그것을했지만 대화 상자 리소스에서 이진 데이터를로드하려고 할 때 런타임에 어설 션을 얻는다. 어설 션을 해결하려면 대화 상자 편집기로 가서 컨트롤을 다시 저장해야합니다. – markh44