다음을 통해 공유


MFC ActiveX 컨트롤: Windows 컨트롤 서브클래싱

이 문서에서는 ActiveX 컨트롤을 만들기 위해 일반적인 Windows 컨트롤을 서브클래싱하는 프로세스를 설명합니다. 기존 Windows 컨트롤을 서브클래싱하면 ActiveX 컨트롤을 빠르게 개발할 수 있습니다. 새 컨트롤에는 그리기 및 마우스 클릭 응답과 같은 서브클래싱된 Windows 컨트롤의 기능이 있습니다. MFC ActiveX 컨트롤 샘플 BUTTON 은 Windows 컨트롤을 서브클래싱하는 예제입니다.

Important

ActiveX는 새로운 개발에 사용하지 않아야 하는 레거시 기술입니다. ActiveX를 대체하는 최신 기술에 관한 자세한 내용은 ActiveX 컨트롤을 참조하세요.

Windows 컨트롤을 서브클래스하려면 다음 작업을 완료합니다.

IsSubclassedControl 및 PreCreateWindow 재정의

재정 PreCreateWindow 의하려면 IsSubclassedControl컨트롤 클래스 선언의 섹션에 protected 다음 코드 줄을 추가합니다.

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();

컨트롤 구현 파일(. CPP) 다음 코드 줄을 추가하여 재정의된 두 함수를 구현합니다.

// CMyAxSubCtrl::PreCreateWindow - Modify parameters for CreateWindowEx

BOOL CMyAxSubCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
   cs.lpszClass = _T("BUTTON");
   return COleControl::PreCreateWindow(cs);
}

// CMyAxSubCtrl::IsSubclassedControl - This is a subclassed control

BOOL CMyAxSubCtrl::IsSubclassedControl()
{
   return TRUE;
}

이 예제에서는 Windows 단추 컨트롤이 에 지정되어 있습니다 PreCreateWindow. 그러나 모든 표준 Windows 컨트롤은 서브클래스될 수 있습니다. 표준 Windows 컨트롤에 대한 자세한 내용은 컨트롤을 참조 하세요.

Windows 컨트롤을 서브클래싱할 때 컨트롤의 창을 만드는 데 사용할 특정 창 스타일(WS_) 또는 확장 창 스타일(WS_EX_) 플래그를 지정할 수 있습니다. 멤버 함수에서 PreCreateWindow 구조체 필드와 cs.dwExStyle 구조체 필드를 수정하여 이러한 매개 변수에 cs.style 대한 값을 설정할 수 있습니다. 클래스COleControl에 의해 설정된 기본 플래그를 유지하려면 OR 연산을 사용하여 이러한 필드를 수정해야 합니다. 예를 들어 컨트롤이 BUTTON 컨트롤을 서브클래싱하고 컨트롤이 검사 상자로 표시되도록 하려면 return 문 앞에 다음 코드 줄을 구현CSampleCtrl::PreCreateWindow에 삽입합니다.

cs.style |= BS_CHECKBOX;

이 작업은 클래스의 기본 스타일 플래그(WS_CHILD)를 그대로 유지하면서 BS_CHECKBOX 스타일 플래그를 COleControl 추가합니다.

OnDraw 멤버 함수 수정

서브클래스된 컨트롤이 해당 Windows 컨트롤 OnDraw 과 동일한 모양을 유지하도록 하려면 다음 예제와 같이 컨트롤의 멤버 함수에 대한 호출 DoSuperclassPaint 만 포함해야 합니다.

void CMyAxSubCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   if (!pdc)
      return;

   DoSuperclassPaint(pdc, rcBounds);
}

구현된 COleControl멤버 함수는 DoSuperclassPaint Windows 컨트롤의 창 프로시저를 사용하여 지정된 디바이스 컨텍스트의 경계 사각형 내에서 컨트롤을 그립니다. 이렇게 하면 활성화되지 않은 경우에도 컨트롤이 표시됩니다.

참고 항목

멤버 함수는 DoSuperclassPaint 디바이스 컨텍스트를 WM_PAINT 메시지의 wParam으로 전달할 수 있도록 하는 컨트롤 형식에서만 작동합니다. 여기에는 SCROLLBAR 및 BUTTON과 같은 일부 표준 Windows 컨트롤과 모든 공통 컨트롤이 포함됩니다. 이 동작을 지원하지 않는 컨트롤의 경우 비활성 컨트롤을 제대로 표시하려면 사용자 고유의 코드를 제공해야 합니다.

반사된 창 메시지 처리

Windows 컨트롤은 일반적으로 부모 창에 특정 창 메시지를 보냅니다. 이러한 메시지 중 일부(예: WM_COMMAND)는 사용자의 작업 알림을 제공합니다. WM_CTLCOLOR 같은 다른 항목은 부모 창에서 정보를 가져오는 데 사용됩니다. ActiveX 컨트롤은 일반적으로 다른 수단으로 부모 창과 통신합니다. 알림은 이벤트 발생(이벤트 알림 보내기)을 통해 전달되며, 컨트롤 컨테이너에 대한 정보는 컨테이너의 앰비언트 속성에 액세스하여 가져옵니다. 이러한 통신 기술이 존재하기 때문에 ActiveX 컨트롤 컨테이너는 컨트롤에서 보낸 창 메시지를 처리하지 않을 것으로 예상됩니다.

컨테이너가 서브클래싱된 Windows 컨트롤에서 보낸 창 메시지를 받지 못하도록 하려면 컨트롤 COleControl 의 부모 역할을 할 추가 창을 만듭니다. "리플렉터"라고 하는 이 추가 창은 Windows 컨트롤을 서브클래싱하고 컨트롤 창과 크기 및 위치가 같은 ActiveX 컨트롤에 대해서만 만들어집니다. 리플렉터 창은 특정 창 메시지를 가로채 컨트롤로 다시 보냅니다. 그런 다음 컨트롤은 창 프로시저에서 ActiveX 컨트롤에 적합한 작업(예: 이벤트 발생)을 수행하여 이러한 반영된 메시지를 처리할 수 있습니다. 가로채는 창 메시지 목록과 해당 반영된 메시지 목록은 Reflected Window 메시지 ID를 참조하세요.

ActiveX 컨트롤 컨테이너는 메시지 리플렉션 자체를 수행하도록 설계되어 리플렉터 창을 만들 필요가 COleControl 없으며 서브클래싱된 Windows 컨트롤의 런타임 오버헤드를 줄일 수 있습니다. COleControl는 값이 TRUE인 MessageReflect 앰비언트 속성에 대해 검사 컨테이너에서 이 기능을 지원하는지 여부를 검색합니다.

반사된 창 메시지를 처리하려면 컨트롤 메시지 맵에 항목을 추가하고 처리기 함수를 구현합니다. 반영된 메시지는 Windows에서 정의한 표준 메시지 집합의 일부가 아니므로 클래스 뷰는 이러한 메시지 처리기 추가를 지원하지 않습니다. 그러나 처리기를 수동으로 추가하는 것은 어렵지 않습니다.

반영된 창 메시지에 대한 메시지 처리기를 추가하려면 다음을 수동으로 수행합니다.

  • 컨트롤 클래스에서 . H 파일, 처리기 함수를 선언합니다. 함수에는 각각 WPARAM 및 LPARAM 형식이 있는 LRESULT의 반환 형식두 개의 매개 변수가 있어야 합니다. 예시:

    class CMyAxSubCtrl : public COleControl
    {
    
    protected:
       LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam);
    };
    
  • 컨트롤 클래스에서 . CPP 파일, 메시지 맵에 ON_MESSAGE 항목을 추가합니다. 이 항목의 매개 변수는 메시지 식별자 및 처리기 함수의 이름이어야 합니다. 예시:

    BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl)
       ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand)
    END_MESSAGE_MAP()
    
  • 또한 . CPP 파일, 반영된 메시지를 처리하는 멤버 함수를 구현 OnOcmCommand 합니다. wParamlParam 매개 변수는 원래 창 메시지의 매개 변수와 동일합니다.

반영된 메시지를 처리하는 방법에 대한 예제는 MFC ActiveX 컨트롤 샘플 BUTTON을 참조하세요. BN_CLICKED 알림 코드를 검색하고 이벤트를 발생(전송)Click하여 응답하는 처리기를 보여 OnOcmCommand 줍니다.

참고 항목

MFC ActiveX 컨트롤