Çizim Kodunu değiştirme (ATL Eğitmeni, Bölüm 4)
Varsayılan olarak, denetimin çizim kodu bir kare ve PolyCtl metnini görüntüler. Bu adımda, daha ilginç bir şey görüntülemek için kodu değiştireceksiniz. Aşağıdaki görevler söz konusu olur:
Üst Bilgi Dosyasını Değiştirme
İşlevi
OnDraw
DeğiştirmeÇokGen Noktalarını Hesaplamak için Yöntem Ekleme
Dolgu Rengini Başlatma
Üst Bilgi Dosyasını Değiştirme
İlk olarak, kullanılacak matematik işlevleri sin
ve cos
için destek ekleyerek çokgen noktaları hesaplayın ve konumları depolamak için bir dizi oluşturun.
Üst bilgi dosyasını değiştirmek için
PolyCtl.h dosyasının en üstüne çizgi
#include <math.h>
ekleyin. Dosyanın üst kısmı şu şekilde görünmelidir:#include <math.h> #include "resource.h" // main symbols
IProvideClassInfo
PolyCtl.h'ye aşağıdaki kodu ekleyerek denetim için yöntem bilgileri sağlamak üzere arabirimini uygulayın.CPolyCtl
sınıfında satırı değiştirin:public CComControl<CPolyCtl>
örneklerini şununla değiştirin:
public CComControl<CPolyCtl>, public IProvideClassInfo2Impl<&CLSID_PolyCtl, &DIID__IPolyCtlEvents, &LIBID_PolygonLib>
ve içine
BEGIN_COM_MAP(CPolyCtl)
satırları ekleyin:COM_INTERFACE_ENTRY(IProvideClassInfo) COM_INTERFACE_ENTRY(IProvideClassInfo2)
Çokgen noktaları hesaplandıktan sonra, türünde
POINT
bir dizide depolanırlar, bu nedenle PolyCtl.h içindeki tanım deyimindenshort m_nSides;
sonra diziyi ekleyin:POINT m_arrPoint[100];
OnDraw Yöntemini Değiştirme
Şimdi PolyCtl.h dosyasında yöntemini değiştirmeniz OnDraw
gerekir. Ekleyeceğiniz kod, çokgeninizi çizmek için yeni bir kalem ve fırça oluşturur ve sonra gerçek çizimi gerçekleştirmek için ve Polygon
Win32 API işlevlerini çağırırEllipse
.
OnDraw işlevini değiştirmek için
PolyCtl.h dosyasındaki mevcut
OnDraw
yöntemi aşağıdaki kodla değiştirin: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; }
ÇokGen Noktalarını Hesaplamak için Yöntem Ekleme
Çokgenin çevresini oluşturan noktaların koordinatlarını hesaplayacak adlı CalcPoints
bir yöntem ekleyin. Bu hesaplamalar işleve geçirilen RECT değişkenini temel alır.
CalcPoints yöntemini eklemek için
bildirimini
CalcPoints
IPolyCtl
PolyCtl.h'de sınıfının genel bölümüneCPolyCtl
ekleyin:void CalcPoints(const RECT& rc);
Sınıfın genel bölümünün son bölümü
CPolyCtl
şöyle görünür:void FinalRelease() { } public: void CalcPoints(const RECT& rc);
İşlevin
CalcPoints
bu uygulamasını PolyCtl.cpp sonuna ekleyin: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; } }
Dolgu Rengini Başlatma
Varsayılan bir renkle başlatın m_clrFillColor
.
Dolgu rengini başlatmak için
PolyCtl.h içindeki oluşturucuya
CPolyCtl
bu çizgiyi ekleyerek varsayılan renk olarak yeşil kullanın:m_clrFillColor = RGB(0, 0xFF, 0);
Oluşturucu şimdi şöyle görünür:
CPolyCtl()
{
m_nSides = 3;
m_clrFillColor = RGB(0, 0xFF, 0);
}
Denetimi Oluşturma ve Test Etme
Denetimi yeniden oluşturun. PolyCtl.htm dosyasının hala açıksa kapalı olduğundan emin olun ve ardından Derleme menüsünde ÇokGen Oluştur'a tıklayın. denetimi PolyCtl.htm sayfasından bir kez daha görüntüleyebilirsiniz, ancak bu kez ActiveX Denetim Testi Kapsayıcısını kullanın.
ActiveX Denetim Testi Kapsayıcısını kullanmak için
ActiveX Denetim Testi Kapsayıcısını derleyin ve başlatın. TSTCON Örneği: ActiveX Denetim Testi Kapsayıcısı GitHub'da bulunabilir.
Not
ile ilgili
ATL::CW2AEX
hatalar için Script.Cpp dosyasında satırını ve satırınıTRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT );
TRACE( "Source Text: %s\n", COLE2CT( bstrSourceLineText ) );
ileTRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz );
TRACE( "Source Text: %s\n", bstrSourceLineText );
değiştirin.
ile ilgiliHMONITOR
hatalar için projede StdAfx.h dosyasınıTCProps
açın ve şunu değiştirin:#ifndef WINVER #define WINVER 0x0400 #endif
örneklerini şununla değiştirin:
#ifndef WINVER #define WINVER 0x0500 #define _WIN32_WINNT 0x0500 #endif
Test Kapsayıcısı'ndaki Düzenle menüsünde Yeni Denetim Ekle'ye tıklayın.
adlı
PolyCtl class
denetiminizi bulun ve Tamam'a tıklayın. Daire içinde yeşil bir üçgen görürsünüz.
Sonraki yordamı izleyerek taraf sayısını değiştirmeyi deneyin. Test Kapsayıcısı'nın içinden bir çift arabirimdeki özellikleri değiştirmek için Invoke Yöntemleri'ni kullanın.
Test Kapsayıcısı'nın içinden bir denetimin özelliğini değiştirmek için
Test Kapsayıcısı'nda, Denetim menüsünden Yöntemleri Çağır'a tıklayın.
Çağırma Yöntemi iletişim kutusu görüntülenir.
Yöntem Adı açılan liste kutusunda Sides özelliğinin PropPut sürümünü seçin.
Parametre Değeri kutusuna yazın
5
, Değer Ayarla'ya ve ardından Çağır'a tıklayın.
Denetimin değişmediğini unutmayın. Değişkeni ayarlayarak m_nSides
kenar sayısını dahili olarak değiştirseniz de, bu denetimin yeniden boyanmasına neden olmadı. Başka bir uygulamaya geçip Test Kapsayıcısı'na geri dönerseniz denetimin yeniden boyandığını ve doğru sayıda kenar olduğunu göreceksiniz.
Bu sorunu düzeltmek için FireViewChange
, kenar sayısını ayarladıktan sonra işlevine içinde IViewObjectExImpl
tanımlanan bir çağrı ekleyin. Denetim kendi penceresinde çalışıyorsa, FireViewChange
yöntemini doğrudan çağırır InvalidateRect
. Denetim penceresiz çalışıyorsa, kapsayıcının InvalidateRect
site arabiriminde yöntemi çağrılır. Bu, denetimi kendini yeniden boyamaya zorlar.
FireViewChange çağrısı eklemek için
çağrısı yöntemine
FireViewChange
ekleyerek PolyCtl.cpp güncelleştirinput_Sides
. İşiniz bittiğindeput_Sides
yöntemi şu şekilde görünmelidir: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")); } }
ekledikten FireViewChange
sonra, ActiveX Denetim Testi Kapsayıcısı'nda denetimi yeniden derleyin ve yeniden deneyin. Bu kez kenar sayısını değiştirip öğesine tıkladığınızda Invoke
, denetimin hemen değiştiğini görmeniz gerekir.
Sonraki adımda bir olay ekleyeceğiz.
Ayrıca bkz.
Öğretici
Test Kapsayıcısı ile Özellikleri ve Olayları Test Etme