Zmiana kodu rysującego (ATL — Samouczek, część 4)
Domyślnie kod rysunku kontrolki wyświetla kwadrat i tekst PolyCtl. W tym kroku zmienisz kod, aby wyświetlić coś bardziej interesującego. Są zaangażowane następujące zadania:
Modyfikowanie pliku nagłówka
Modyfikowanie
OnDraw
funkcjiDodawanie metody do obliczania punktów wielokątnych
Inicjowanie koloru wypełnienia
Modyfikowanie pliku nagłówka
Zacznij od dodania obsługi funkcji sin
matematycznych i cos
, które będą używane do obliczania punktów wielokątnych oraz przez utworzenie tablicy do przechowywania pozycji.
Aby zmodyfikować plik nagłówka
Dodaj linię
#include <math.h>
na górze pliku PolyCtl.h. Górna część pliku powinna wyglądać następująco:#include <math.h> #include "resource.h" // main symbols
Zaimplementuj interfejs,
IProvideClassInfo
aby udostępnić informacje o metodzie dla kontrolki, dodając następujący kod do pliku PolyCtl.h. W klasie zastąpCPolyCtl
wiersz:public CComControl<CPolyCtl>
with
public CComControl<CPolyCtl>, public IProvideClassInfo2Impl<&CLSID_PolyCtl, &DIID__IPolyCtlEvents, &LIBID_PolygonLib>
i w pliku
BEGIN_COM_MAP(CPolyCtl)
dodaj wiersze:COM_INTERFACE_ENTRY(IProvideClassInfo) COM_INTERFACE_ENTRY(IProvideClassInfo2)
Po obliczeniu punktów wielokątnych będą one przechowywane w tablicy typu
POINT
, więc dodaj tablicę po instrukcjishort m_nSides;
definicji w pliku PolyCtl.h:POINT m_arrPoint[100];
Modyfikowanie metody OnDraw
Teraz należy zmodyfikować metodę OnDraw
w pliku PolyCtl.h. Dodany kod tworzy nowy pióro i szczotkę, za pomocą którego można narysować wielokąt, a następnie wywołuje Ellipse
funkcje interfejsu API Win32 i Polygon
w celu wykonania rzeczywistego rysunku.
Aby zmodyfikować funkcję OnDraw
Zastąp istniejącą
OnDraw
metodę w pliku PolyCtl.h następującym kodem: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; }
Dodawanie metody do obliczania punktów wielokątnych
Dodaj metodę o nazwie CalcPoints
, która oblicza współrzędne punktów tworzących obwód wielokąta. Te obliczenia będą oparte na zmiennej RECT przekazywanej do funkcji.
Aby dodać metodę CalcPoints
Dodaj deklarację do
CalcPoints
publicznejIPolyCtl
sekcjiCPolyCtl
klasy w pliku PolyCtl.h:void CalcPoints(const RECT& rc);
Ostatnia część sekcji publicznej
CPolyCtl
klasy będzie wyglądać następująco:void FinalRelease() { } public: void CalcPoints(const RECT& rc);
Dodaj tę implementację
CalcPoints
funkcji na końcu 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; } }
Inicjowanie koloru wypełnienia
Zainicjuj m_clrFillColor
kolor domyślny.
Aby zainicjować kolor wypełnienia
Użyj koloru zielonego jako domyślnego, dodając ten wiersz do konstruktora
CPolyCtl
w pliku PolyCtl.h:m_clrFillColor = RGB(0, 0xFF, 0);
Konstruktor wygląda teraz następująco:
CPolyCtl()
{
m_nSides = 3;
m_clrFillColor = RGB(0, 0xFF, 0);
}
Kompilowanie i testowanie kontrolki
Ponownie skompiluj kontrolkę. Upewnij się, że plik PolyCtl.htm jest zamknięty, jeśli jest nadal otwarty, a następnie kliknij polecenie Kompiluj wielokąt w menu Kompilacja . Kontrolkę można wyświetlić ponownie na stronie PolyCtl.htm, ale tym razem użyj kontenera testów kontrolek ActiveX.
Aby użyć kontenera testów kontrolek ActiveX
Skompiluj i uruchom kontener testów kontrolek ActiveX. Przykład TSTCON: Kontener testów kontrolek ActiveX można znaleźć w witrynie GitHub.
Uwaga
W przypadku błędów dotyczących
ATL::CW2AEX
elementu w pliku Script.Cpp zastąp wierszTRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT );
ciągiemTRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz );
, i wierszemTRACE( "Source Text: %s\n", COLE2CT( bstrSourceLineText ) );
TRACE( "Source Text: %s\n", bstrSourceLineText );
.
W przypadku błędów obejmującychHMONITOR
plik otwórz plik StdAfx.h w projekcieTCProps
i zastąp:#ifndef WINVER #define WINVER 0x0400 #endif
with
#ifndef WINVER #define WINVER 0x0500 #define _WIN32_WINNT 0x0500 #endif
W kontenerze testowym w menu Edycja kliknij pozycję Wstaw nową kontrolkę.
Znajdź kontrolkę o nazwie
PolyCtl class
, a następnie kliknij przycisk OK. W okręgu zobaczysz zielony trójkąt.
Spróbuj zmienić liczbę stron, wykonując następną procedurę. Aby zmodyfikować właściwości w podwójnym interfejsie z poziomu kontenera testowego, użyj metod Invoke.
Aby zmodyfikować właściwość kontrolki z poziomu kontenera testów
W kontenerze testowym kliknij pozycję Wywołaj metody w menu Kontrolka.
Zostanie wyświetlone okno dialogowe Wywołaj metodę .
Wybierz właściwość PropPut właściwości Sides z listy rozwijanej Nazwa metody.
Wpisz
5
wartość parametru, kliknij pozycję Ustaw wartość, a następnie kliknij przycisk Wywołaj.
Należy pamiętać, że kontrolka nie zmienia się. Mimo że liczba stron została zmieniona wewnętrznie przez ustawienie zmiennej m_nSides
, nie spowodowało to przemalowania kontrolki. Jeśli przełączysz się do innej aplikacji, a następnie przełączysz się z powrotem do kontenera testowego, okaże się, że kontrolka została przemalowana i ma poprawną liczbę stron.
Aby rozwiązać ten problem, dodaj wywołanie funkcji FireViewChange
zdefiniowanej w IViewObjectExImpl
pliku po ustawieniu liczby stron. Jeśli kontrolka jest uruchomiona we własnym oknie, FireViewChange
wywoła metodę InvalidateRect
bezpośrednio. Jeśli kontrolka jest uruchomiona bez okna, InvalidateRect
metoda zostanie wywołana w interfejsie lokacji kontenera. Wymusza to kontrolę, aby przemalować się.
Aby dodać wywołanie funkcji FireViewChange
Zaktualizuj PolyCtl.cpp, dodając wywołanie metody
FireViewChange
doput_Sides
metody . Po zakończeniuput_Sides
metoda powinna wyglądać następująco: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")); } }
Po dodaniu FireViewChange
polecenia ponownie skompiluj kontrolkę i spróbuj ponownie w kontenerze testów kontrolek ActiveX. Tym razem, gdy zmienisz liczbę stron i klikniesz Invoke
przycisk , powinna zostać natychmiast wyświetlona zmiana kontrolki.
W następnym kroku dodasz zdarzenie.
Powrót do kroku 3 | do kroku 5
Zobacz też
Samouczek
Testowanie właściwości i zdarzeń za pomocą kontenera testu