Aracılığıyla paylaş


Ç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 cosiç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

  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ı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

  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. bildirimini CalcPoints IPolyCtl PolyCtl.h'de sınıfının genel bölümüne CPolyCtl 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. İş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

  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ı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

  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

    ile ilgili ATL::CW2AEXhatalar 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 ) ); ile TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz );TRACE( "Source Text: %s\n", bstrSourceLineText );değiştirin.
    ile ilgili HMONITORhatalar 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
    
  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. 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

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

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

  3. Parametre Değeri kutusuna yazın5, 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 IViewObjectExImpltanı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

  1. çağrısı yöntemine FireViewChange ekleyerek PolyCtl.cpp güncelleştirin put_Sides . İş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 öğesine tıkladığınızda Invoke, denetimin hemen değiştiğini görmeniz gerekir.

Sonraki adımda bir olay ekleyeceğiz.

3 | . Adıma Geri Dön- 5. Adım

Ayrıca bkz.

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