W rysunku kod będzie używać funkcji grzechu i cos do obliczania punktów wielokąt, aby dodać obejmują math.h u góry PolyCtl.h:
# include lt;math.h >
# include "resource.h" / / główne symbole
Uwaga dopuszczenia tworzy tylkonbsp; Gdy ATL COM AppWizard generuje projektu domyślne, definiuje makro _ATL_MI&N_CRT. To makro jest zdefiniowany tak, aby nie doprowadzić C Run-Time Library w kodzie, jeśli nie będzie potrzebny. Formant wielokąt wymaga kod rozruchu C Run-Time Library zainicjować zmiennoprzecinkowych funkcji. W związku z tym należy usunąć makro _ATL_MIN_CRT , jeśli chcesz zbudować wersji. Aby usunąć makro, kliknij przycisk Ustawienia w menu Projekt . W Ustawienia dla: rozwijaną listę, wybierz Wielu konfiguracji. W Zaznacz projekt konfiguracji do modyfikowania pojawi się okno dialogowe kliknij przycisk pola wyboru dla wszystkich czterech wersje Release, a następnie kliknij przycisk OK. Na karcie C/C++ wybierz kategorię Ogólne , a następnie usunąć _ATL_MIN_CRT w polu edycji definicji preprocesora.
Po obliczane są punkty wielokąt, można przechowywać punktów dodając tablicą typu punkt do końca definicji klasy w PolyCtl.h:
OLE_COLOR m_clrFillColor;
krótkie m_nSides;
PUNKT m_arrPoint [100]
Teraz zmienić OnDraw funkcji w PolyCtl.h odpowiadać jeden poniżej. Uwaga usunięcie wywołań funkcji prostokąta i Begin DrawText. Również wyraźnie uzyskać i wybierz pióro czarnego i białego pędzla. Trzeba to zrobić, w przypadku, jeśli formant jest uruchomiony bez okien. Jeśli nie masz własne okno, nie można wprowadzać założenia dotyczące kontekstu urządzenia, że można będzie rysunek w.
Wypełniony OnDraw wygląda podobnie do następującej:
HRESULT CPolyCtl::OnDraw(ATL_DRAWINFOamp; di)
{
RECT & rc = *(RECT*)di.prcBounds;
HDC hdc = di.hdcDraw;
COLORREF colFore;
HBRUSH hOldBrush, hBrush;
HPEN hOldPen, hPen;
/ / Tłumaczyć m_colFore typu COLORREF
OleTranslateColor (m_clrFillColor, NULL & colFore);
/ / Tworzenie i wybierz kolory, aby narysować okrąg
hPen = (HPEN)GetStockObject(BLACK_PEN);
hOldPen = WybierzObiekt (HPEN) (hdc, hPen);
hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
hOldBrush = WybierzObiekt (HBRUSH) (hdc, hBrush);
Elipsa (hdc, rc.left, rc.top, rc.right, rc.bottom);
/ / Tworzenie i wybierz Pędzel, używany do wypełnienia wielokąta
hBrush = CreateSolidBrush(colFore);
WybierzObiekt (hdc, hBrush);
CalcPoints(rc);
Wielokąt (hdc & m_arrPoint [0], m_nSides);
/ / Zaznacz ponownie Stare pióro i Pędzel i Usuń pędzel stworzyliśmy
WybierzObiekt (hdc, hOldPen);
WybierzObiekt (hdc, hOldBrush);
DeleteObject(hBrush);
Zwraca wartość S_OK;
}
Teraz musisz dodać funkcję o nazwie CalcPoints , który będzie obliczyć współrzędne intersections.nbsp linii; Obliczenia te będą opierać się na zmiennej RECT, który jest przekazywany do funkcji. &Najpierw należy dodać definicję CalcPoints do sekcji publicznej dla klasy IPolyCtl w PolyCtl.h:
voidnbsp; CalcPoints (RECT stała & rc)
Publiczne sekcji klasy IPolyCtl powinno wyglądać tak jak to:
/ / IPolyCtl
publiczne:
STDMETHOD(get_Sides) (/ * [out, retval] * / krótki * newVal);
STDMETHOD(put_Sides) (/ * [w] * / krótki newVal);
voidnbsp; CalcPoints (RECT stała & rc)
Następnie dodaj wykonania CalcPoints funkcji na końcu pliku PolyCtl.cpp:
void CPolyCtl::CalcPoints (const RECTamp; rc)
{
stała podwójne pi = 3.14159265358979;
PKT ptCenter;
podwójne dblRadiusx = (rc.right - rc.left) / 2;
podwójne dblRadiusy = (rc.bottom - rc.top) / 2;
podwójne dblAngle = 3 * pi / 2; / / Start u góry
podwójne dblDiff = 2 * pi / m_nSides; / / Kąt każdej stronie sprawi, że
ptCenter.x = (rc.left + rc.right) / 2;
ptCenter.y = (rc.top + rc.bottom) / 2;
/ / Obliczyć punkty na każdej stronie
dla (int i = 0; i < m_nSides; i ++)
{
m_arrPoint, [i] .x = (długa) (dblRadiusx * cos(dblAngle) + ptCenter.x + 0,5);
.y m_arrPoint, [i] = (długa) (dblRadiusy * sin(dblAngle) + ptCenter.y + 0,5);
dblAngle += dblDiff;
}
}
Teraz, zainicjować m_clrFillColor . Wybierz green jako domyślny kolor i dodaj wiersz do CPolyCtl Konstruktor w PolyCtl.h:
m_clrFillColor = RGB (0, 0xFF, 0)
Jak to wygląda teraz konstruktora:
CPolyCtl()
{
m_nSides = 3;
m_clrFillColor = RGB (0, 0xFF, 0);
}
Teraz odbudować kontroli i spróbuj ponownie. Otwórz Kontener badania formantu ActiveX i wstawić formant. Powinien zostać wyświetlony zielony trójkąt w okręgu. Należy spróbować zmienić liczbę boków, wykonując poniższe kroki. Aby zmodyfikować właściwości na podwójnym interfejsem z w ramach Badania kontenera, należy użyć Metody Invoke:

Należy zauważyć, że formant nie ulega zmianie. Co jest nie tak? Chociaż można zmienić liczbę boków wewnętrznie przez ustawienie m_nSides zmiennej, nie można spowodować kontroli do odświeżenia. Jeśli przełączysz się do innej aplikacji, a następnie przełącz się ponownie do Badania kontenera będą stwierdzą, że formant jest odowieżany i obecnie ma poprawną liczbę boków.
Aby rozwiązać ten problem, musisz dodać wywołanie funkcji FireViewChange , która jest zdefiniowana w IViewObjectExImpl, po ustawieniu liczbę boków. Jeśli formant jest uruchomiony w osobnym oknie, FireViewChange będzie bezpośrednio wywołać InvalidateRect interfejsu API. Jeśli formant jest uruchomiony bez okien, interfejsie witryny kontenera będzie można wywołać metody InvalidateRect . Wymusi to formant do odświeżenia sam.
Nowy put_Sides Metoda jest następująca:
STDMETHODIMP CPolyCtl::put_Sides(short newVal)
{
Jeżeli (newVal gt; 2 & & newVal < 101)
{
m_nSides = newVal;
FireViewChange();
Zwraca wartość S_OK;
}
Else
zwrócenie błędu (_T ("kształt musi być między 3 i 100"));
}
Po dodaniu FireViewChange, odbudowę i ponów kontroli. Tym razem, kiedy zmienić liczbę boków i kliknij Invoke, powinieneś zobaczyć formantu natychmiast zmienić.
Następnie należy dodać zdarzenie kontroli.
Wróć do kroku 3 |nbsp; Do kroku 5