그리기 코드 변경(ATL 자습서, 4부)
기본적으로 컨트롤의 그리기 코드는 정사각형 및 텍스트 PolyCtl을 표시합니다. 이 단계에서는 더 흥미로운 항목을 표시하도록 코드를 변경합니다. 관련된 작업은 다음과 같습니다.
헤더 파일 수정
OnDraw
함수 수정다각형 점을 계산하는 메서드 추가
채우기 색 초기화
헤더 파일 수정
먼저 수학 함수 sin
cos
에 대한 지원을 추가하고 다각형 점을 계산하고 위치를 저장할 배열을 만들어 계산합니다.
헤더 파일을 수정하려면
PolyCtl.h의 맨 위에 줄을
#include <math.h>
추가합니다. 파일의 맨 위는 다음과 같습니다.#include <math.h> #include "resource.h" // main symbols
IProvideClassInfo
PolyCtl.h에 다음 코드를 추가하여 컨트롤에 대한 메서드 정보를 제공하는 인터페이스를 구현합니다. 클래스에서CPolyCtl
줄 바꾸기:public CComControl<CPolyCtl>
다음과 같이 바꿉니다.
public CComControl<CPolyCtl>, public IProvideClassInfo2Impl<&CLSID_PolyCtl, &DIID__IPolyCtlEvents, &LIBID_PolygonLib>
에서
BEGIN_COM_MAP(CPolyCtl)
다음 줄을 추가합니다.COM_INTERFACE_ENTRY(IProvideClassInfo) COM_INTERFACE_ENTRY(IProvideClassInfo2)
다각형 점이 계산되면 형식
POINT
배열에 저장되므로 PolyCtl.h의 정의 문short m_nSides;
뒤 배열을 추가합니다.POINT m_arrPoint[100];
OnDraw 메서드 수정
이제 PolyCtl.h에서 메서드를 OnDraw
수정해야 합니다. 추가할 코드는 다각형을 그릴 새 펜과 브러시를 만든 다음 Win32 API 함수를 Polygon
호출 Ellipse
하여 실제 그리기를 수행합니다.
OnDraw 함수를 수정하려면
PolyCtl.h의 기존
OnDraw
메서드를 다음 코드로 바꿉다.HRESULT CPolyCtl::OnDraw(ATL_DRAWINFO& di) { RECT& rc = *(RECT*)di.prcBounds; HDC hdc = di.hdcDraw; COLORREF colFore; HBRUSH hOldBrush, hBrush; HPEN hOldPen, hPen; // Translate m_colFore into a COLORREF type OleTranslateColor(m_clrFillColor, NULL, &colFore); // Create and select the colors to draw the circle hPen = (HPEN)GetStockObject(BLACK_PEN); hOldPen = (HPEN)SelectObject(hdc, hPen); hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH); hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); // Create and select the brush that will be used to fill the polygon hBrush = CreateSolidBrush(colFore); SelectObject(hdc, hBrush); CalcPoints(rc); Polygon(hdc, &m_arrPoint[0], m_nSides); // Select back the old pen and brush and delete the brush we created SelectObject(hdc, hOldPen); SelectObject(hdc, hOldBrush); DeleteObject(hBrush); return S_OK; }
다각형 점을 계산하는 메서드 추가
다각형의 경계를 구성하는 점의 좌표를 계산하는 메서드를 CalcPoints
추가합니다. 이러한 계산은 함수에 전달되는 RECT 변수를 기반으로 합니다.
CalcPoints 메서드를 추가하려면
PolyCtl.h에서 클래스의
CPolyCtl
public 섹션에 선언CalcPoints
IPolyCtl
을 추가합니다.void CalcPoints(const RECT& rc);
클래스의 공개 섹션
CPolyCtl
의 마지막 부분은 다음과 같습니다.void FinalRelease() { } public: void CalcPoints(const RECT& rc);
이 함수 구현을
CalcPoints
PolyCtl.cpp 끝에 추가합니다.void CPolyCtl::CalcPoints(const RECT& rc) { const double pi = 3.14159265358979; POINT ptCenter; double dblRadiusx = (rc.right - rc.left) / 2; double dblRadiusy = (rc.bottom - rc.top) / 2; double dblAngle = 3 * pi / 2; // Start at the top double dblDiff = 2 * pi / m_nSides; // Angle each side will make ptCenter.x = (rc.left + rc.right) / 2; ptCenter.y = (rc.top + rc.bottom) / 2; // Calculate the points for each side for (int i = 0; i < m_nSides; i++) { m_arrPoint[i].x = (long)(dblRadiusx * cos(dblAngle) + ptCenter.x + 0.5); m_arrPoint[i].y = (long)(dblRadiusy * sin(dblAngle) + ptCenter.y + 0.5); dblAngle += dblDiff; } }
채우기 색 초기화
기본 색으로 초기화 m_clrFillColor
합니다.
채우기 색을 초기화하려면
PolyCtl.h의 생성자에 이 줄을
CPolyCtl
추가하여 녹색을 기본 색으로 사용합니다.m_clrFillColor = RGB(0, 0xFF, 0);
이제 생성자는 다음과 같이 표시됩니다.
CPolyCtl()
{
m_nSides = 3;
m_clrFillColor = RGB(0, 0xFF, 0);
}
컨트롤 빌드 및 테스트
컨트롤을 다시 빌드합니다. PolyCtl.htm 파일이 열려 있는 경우 닫혀 있는지 확인한 다음 빌드 메뉴에서 다각형 빌드를 클릭합니다. PolyCtl.htm 페이지에서 컨트롤을 다시 볼 수 있지만 이번에는 ActiveX 컨트롤 테스트 컨테이너를 사용합니다.
ActiveX 컨트롤 테스트 컨테이너를 사용하려면
ActiveX 컨트롤 테스트 컨테이너를 빌드하고 시작합니다. TSTCON 샘플: ActiveX 컨트롤 테스트 컨테이너는 GitHub에서 찾을 수 있습니다.
참고 항목
Script.Cpp에서 관련된
ATL::CW2AEX
오류의 경우 줄을TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT );
로 TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz );
바꾸고 줄 바꿈TRACE( "Source Text: %s\n", COLE2CT( bstrSourceLineText ) );
을 지정TRACE( "Source Text: %s\n", bstrSourceLineText );
합니다.
관련된HMONITOR
오류의 경우 프로젝트에서 StdAfx.h를 열고 다음을TCProps
바꿉다.#ifndef WINVER #define WINVER 0x0400 #endif
다음과 같이 바꿉니다.
#ifndef WINVER #define WINVER 0x0500 #define _WIN32_WINNT 0x0500 #endif
테스트 컨테이너의 편집 메뉴에서 새 컨트롤 삽입을 클릭합니다.
호출
PolyCtl class
될 컨트롤을 찾아 확인을 클릭합니다. 원 안에 녹색 삼각형이 표시됩니다.
다음 절차에 따라 측면 수를 변경해 봅니다. 테스트 컨테이너 내에서 이중 인터페이스의 속성을 수정하려면 Invoke 메서드를 사용합니다.
테스트 컨테이너 내에서 컨트롤의 속성을 수정하려면
테스트 컨테이너의 컨트롤 메뉴에서 메서드 호출을 클릭합니다.
메서드 호출 대화 상자가 표시됩니다.
메서드 이름 드롭다운 목록 상자에서 Sides 속성의 PropPut 버전을 선택합니다.
매개 변수 값 상자에 입력
5
하고 값 설정을 클릭한 다음 호출을 클릭합니다.
컨트롤은 변경되지 않습니다. 변수를 설정 m_nSides
하여 내부적으로 측면 수를 변경했지만 컨트롤이 다시 그려지지는 않았습니다. 다른 애플리케이션으로 전환한 다음 테스트 컨테이너로 다시 전환하면 컨트롤이 다시 그려지고 올바른 수의 측면이 있음을 확인할 수 있습니다.
이 문제를 해결하려면 측면 수를 설정한 후 정의된 함수에 IViewObjectExImpl
대한 호출 FireViewChange
을 추가합니다. 컨트롤이 자체 창 FireViewChange
에서 실행 중인 경우 메서드를 직접 호출합니다 InvalidateRect
. 컨트롤이 창 없이 InvalidateRect
실행되는 경우 컨테이너의 사이트 인터페이스에서 메서드가 호출됩니다. 이렇게 하면 컨트롤이 다시 그려집니다.
FireViewChange에 대한 호출을 추가하려면
메서드에 호출
FireViewChange
을 추가하여 PolyCtl.cpp 업데이트합니다put_Sides
. 완료되면 메서드는put_Sides
다음과 같이 표시됩니다.STDMETHODIMP CPolyCtl::put_Sides(short newVal) { if (2 < newVal && newVal < 101) { m_nSides = newVal; FireViewChange(); return S_OK; } else { return Error(_T("Shape must have between 3 and 100 sides")); } }
추가 FireViewChange
한 후 ActiveX 컨트롤 테스트 컨테이너에서 컨트롤을 다시 빌드하고 다시 시도합니다. 이번에는 측면 수를 변경하고 클릭하면 Invoke
컨트롤이 즉시 변경됩니다.
다음 단계에서는 이벤트를 추가합니다.