Çizim Kodunu değiştirme (ATL Eğitmeni, Bölüm 4)

Not

Etkin Şablon Kitaplığı (ATL) desteklenmeye devam eder. Ancak artık özellik eklemeyeceğiz veya belgeleri güncelleştirmeyeceğiz.

Varsayılan olarak, kontrolün çizim yöntemi 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 cosiçin destek ekleyerek çokgen noktaları hesaplayın ve konumları depolamak için bir dizi oluşturun.

Üst bilgi dosyasını düzenlemek için

  1. 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
    
  2. 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)
    
  3. Çokgen noktaları hesaplandıktan sonra, türünde POINTbir dizide depolanırlar, bu nedenle PolyCtl.h içindeki tanım deyiminden short m_nSides; sonra diziyi ekleyin:

    POINT m_arrPoint[100];
    

OnDraw Yöntemini Değiştirme

Şimdi PolyCtl.h dosyasındaki OnDraw yöntemini değiştirmeniz gerekir. Ekleyeceğiniz kod, çokgeninizi çizmek için yeni bir kalem ve fırça oluşturur ve gerçek çizimi gerçekleştirmek için Ellipse ve Polygon Win32 API işlevlerini çağırır.

OnDraw işlevini değiştirmek için

  1. 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ı CalcPointsbir yöntem ekleyin. Bu hesaplamalar işleve geçirilen RECT değişkenini temel alır.

CalcPoints yöntemini eklemek için

  1. CalcPoints bildirimini PolyCtl.h'deki CPolyCtl sınıfının genel bölümüne IPolyCtl 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);
    
  2. CalcPoints işlevinin bu uygulamasını PolyCtl.cpp dosyasının 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

  1. 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ı hala açıksa kapatıldığından emin olun, ardından Oluştur 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

  1. 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

    İle ilgili ATL::CW2AEX hataları Script.Cpp dosyasında TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT ); satırını TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz ); ile ve TRACE( "Source Text: %s\n", COLE2CT( bstrSourceLineText ) ); satırını TRACE( "Source Text: %s\n", bstrSourceLineText ); ile değiştirin.
    HMONITOR içeren hatalar için TCProps projesinde StdAfx.h dosyasını açın ve gereken kısmını değiştirin.

    #ifndef WINVER
    #define WINVER 0x0400
    #endif
    

    örneklerini şununla değiştirin:

    #ifndef WINVER
    #define WINVER 0x0500
    #define _WIN32_WINNT 0x0500
    #endif
    
  2. Test Kapsayıcısı'ndaki Düzenle menüsünde Yeni Denetim Ekle'ye tıklayın.

  3. adlı PolyCtl classdenetiminizi bulun ve Tamam'a tıklayın. Yeşil bir üçgeni dairenin içinde görürsünüz.

Sonraki prosedürü izleyerek kenar 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

  1. Test Kapsayıcısı'nda, Denetim menüsünden Yöntemleri Çağır'a tıklayın.

    Yordamı Çağır iletişim kutusu görüntülenir.

  2. Yöntem Adı açılır liste kutusunda, PropPut sürümünü Sides özelliği için seçin.

  3. 5 ifadesini Parametre Değeri kutusuna yazın, Değeri Ayarla ve ardından Çağır'a tıklayın.

Denetimin değişmediğini unutmayın. Değişkeni m_nSides olarak ayarlayarak kenar sayısını dahili olarak değiştirmenize rağmen, bu kontrolün 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, kenar sayısını ayarladıktan sonra IViewObjectExImpl içinde tanımlanan FireViewChange işlevine 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 site arabiriminde InvalidateRect yöntemi çağrılır. Bu, kontrolün kendisini yeniden boyamasını zorlar.

FireViewChange çağrısı eklemek için

  1. PolyCtl.cpp dosyasını, put_Sides yöntemine FireViewChange çağrısını ekleyerek güncelleyin. İşiniz bittiğinde put_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 FireViewChangesonra, ActiveX Denetim Testi Kapsayıcısı'nda denetimi yeniden derleyin ve yeniden deneyin. Bu kez kenar sayısını değiştirip Invoke öğesine tıkladığınızda, denetimin hemen değiştiğini görmeniz gerekir.

Sonraki adımda bir olay ekleyeceğiz.

3. Adıma Geri Dön | 5. Adıma Geç

Ayrıca bkz.

Eğitim
Test Kapsayıcısı ile Özellikleri ve Olayları Test Etme