컨트롤은 IUnknown이외의 인터페이스를 지원하지 않을 수 있으므로 컨테이너가 특정 인터페이스가 없는 경우 정상적으로 저하해야 합니다.
IUnknown뿐인 컨트롤의 유용성에 의문을 제기할 수 있습니다. 그러나 컨테이너가 개체를 컨트롤로 인식할 때 컨트롤이 컨테이너의 시각적 프로그래밍 환경(예: VB)에서 받는 이점을 고려합니다.
- 도구 상자에 개체에 대한 단추가 나타납니다.
- 도구 상자에서 폼으로 끌어 개체를 만들 수 있습니다.
- 시각적 프로그래밍 환경에서 인식되는 이름을 개체에 지정할 수 있습니다.
- 위의 동일한 이름(3)은 같은 형식(또는 다른 형식)의 컨트롤에 대한 다른 코드를 작성할 때 즉시 사용할 수 있습니다.
- 컨테이너는 해당 개체에서 사용할 수 있는 모든 이벤트에 대한 코드 진입점을 자동으로 제공할 수 있습니다.
- 컨테이너는 사용 가능한 모든 속성에 대한 자체 속성 검색 UI를 제공합니다.
개체가 컨트롤로 인식되지 않으면 이러한 매우 강력하고 유용한 통합 기능이 모두 손실될 수 있습니다. 예를 들어 Visual Basic 4.0에서는 컨트롤이 아닌 일부 임의 개체를 완전히 통합하기가 매우 어렵지만 속성과 이벤트가 여전히 있을 수 있습니다. Visual Basic 4의 컨트롤 개념은 매우 제한적이므로 개체는 위의 통합 기능을 얻지 못합니다. 제어의 단순한 수명으로 인해 어떤 자원의 존재가 결정되는 IUnknown이 있는 경우에도, 위에서 설명한 통합 기능을 확보할 수 있어야 합니다.
현재 도구에는 이점을 얻기 위해 많은 컨트롤 인터페이스 집합이 필요하므로 컨트롤은 일반적으로 오버 구현으로 이뤄지므로 실제로 필요한 것보다 많은 코드가 포함됩니다. 7K가 될 수 있는 컨트롤은 결국 25K가 될 수 있으며, 이는 인터넷과 같은 영역에서 큰 성능 문제입니다. 이로 인해 모든 인터페이스를 구현하는 복잡성 때문에 CDK와 같은 하나의 도구로만 컨트롤을 구현할 수 있다는 인식이 생겼으며, 이러한 컨트롤에 OC30.DLL 같은 큰 DLL이 필요한 경우 작업 집합이 증가합니다. 모든 인터페이스가 필요하지 않은 경우 많은 개발자가 직선 OLE 또는 다른 도구로 매우 작고 가벼운 컨트롤을 작성하여 각 컨트롤에 대한 오버헤드를 최소화할 수 있습니다.
이 부록은 CLSID 및 IUnknown 인터페이스를 사용하여 컨트롤을 모든 개체로 인식하는 이유입니다. IUnknown보다 아무것도 없는 경우에도 프로그래밍 환경이 있는 컨테이너는 적어도 기능 #3 및 ) 레지스트리 항목을 제공할 수 있어야 하며 # 1 및 #2를 얻습니다. 개체가 일부 이벤트 집합에 대해 IConnectionPointContainer(일반적으로 IProvideClassInfo)를 제공하는 경우 #5를 얻게 되며, 속성 및 메서드에 대한 IDispatch 지원하는 경우 컨테이너의 코드 통합이 향상됩니다.
간단히 말해, 개체는 위의 모든 시각적 기능을 얻기 위해 IDispatch 및 IConnectionPointContainer를 통해 노출되는 하나의 이벤트 집합을 구현할 수 있어야 합니다.
이 점을 염두에 두고 다음 표에서는 가능한 인터페이스가 없는 경우 컨테이너가 수행할 수 있는 작업을 설명합니다. 이러한 인터페이스만 나열되므로 컨테이너는 QueryInterface통해 직접 가져옵니다. IOleInPlaceActiveObject같은 다른 인터페이스는 다른 방법을 통해 가져옵니다.
인터페이스 | 인터페이스 부재의 의미 |
---|---|
IViewObject2 |
컨트롤에 자체 그리는 시각적 개체가 없으므로 제공할 명확한 범위가 없습니다. 런타임에서 컨테이너는 이 인터페이스가 없을 때 아무 것도 그리려고 시도하지 않습니다. 디자인 타임에 컨테이너는 적어도 이러한 컨트롤에 대한 이름으로 특정 종류의 기본 사각형을 그려야 하므로 시각적 프로그래밍 환경의 사용자가 개체를 선택하고 해당 속성, 메서드 및 존재하는 이벤트를 확인할 수 있습니다.
IViewObject2 없는 경우를 처리하는 것은 좋은 시각적 프로그래밍 지원에 매우 중요합니다. |
IOleObject |
컨트롤에는 사이트가 필요하지 않으며 포함된 개체 레이아웃 협상에도 참여하지 않습니다. 컨테이너가 이 인터페이스에서 기대할 수 있는 모든 정보(예: 제어 익스텐트)는 컨테이너 제공 기본값으로 채워져야 합니다. |
IOleInPlaceObject |
컨트롤이 제자리에서 활성화되지 않으므로 (예: 레이블), 이러한 방식으로 활성화를 시도하지 않습니다. 유일한 활성화는 속성 페이지일 수 있습니다. |
IOleControl |
컨트롤에는 니모닉이 없고 앰비언트 속성을 사용하지 않으며 컨테이너가 이벤트를 무시하는지 상관하지 않습니다. 이 인터페이스가 없는 경우 컨테이너는 해당 메서드를 호출하지 않습니다. |
IDataObject |
컨트롤은 속성 집합이나 캐시할 수 있는 시각적 렌더링을 제공하지 않으므로 컨테이너는 이 인터페이스(특히 CF_METAFILEPICT 지원)가 없을 때 일부 기본 프레젠테이션을 캐시하고 속성 집합 관련 기능을 사용하지 않도록 선택합니다. |
IDispatch |
컨트롤에 사용자 지정 속성이나 메서드가 없습니다. 이 경우 컨테이너는 컨트롤 속성을 표시할 필요가 없으며 컨테이너가 자체 확장된 컨트롤(메서드 및 속성을 지원할 수 있음)에 속하는 것으로 인식되지 않는 사용자 지정 메서드 호출을 허용하지 않아야 합니다. 확장된 컨트롤은 일반적으로 컨트롤에 대한 특정 IDispatch 호출을 위임하므로, 확장된 컨트롤은 컨트롤이 IDispatch을 가질 것이라고 기대하지 않아야 합니다. |
IConnectionPointContainer |
컨트롤에 이벤트가 없으므로 컨테이너는 처리에 대해 생각할 필요가 없습니다. |
IProvideClassInfo IProvideClassInfo2 |
컨트롤에 형식 정보 또는 이벤트가 없거나 컨테이너가 컨트롤의 레지스트리 항목을 통해 컨트롤의 형식 정보로 이동해야 합니다. 이 인터페이스의 존재는 최적화입니다. |
ISpecifyPropertyPages |
컨트롤에는 속성 페이지가 없으므로 컨테이너에 호출할 UI가 있는 경우 컨테이너는 해당 UI를 사용하지 않도록 설정해야 합니다. |
IPerPropertyBrowsing |
컨트롤에는 표시 이름 자체, 미리 정해진 문자열 및 값, 페이지 매핑에 대한 속성이 없습니다. 이 인터페이스는 컨테이너 사용자 인터페이스를 생성하는 데 거의 항상 사용되므로 이 인터페이스가 없으면 이러한 UI 요소가 비활성화됩니다. |
IPersist* |
컨트롤에 말할 영구 상태가 없으므로 컨테이너는 컨트롤 관련 데이터를 저장하는 것에 대해 걱정할 필요가 없습니다. 물론 컨테이너는 컨트롤에 대한 자체 정보를 자체 형식이나 문서에 저장하지만 컨트롤 자체는 해당 정보에 영향을 줄 필요가 없습니다. |
IOleCache IOleCache2 |
개체는 캐싱을 지원하지 않습니다. 컨테이너는 CreateDataCache사용하여 데이터 캐시 자체를 만들어서 캐싱을 계속 지원할 수 있습니다. |