Sdílet prostřednictvím


Změna kódu kreslení (ATL – tutoriál, část 4)

Ve výchozím nastavení zobrazuje kód výkresu ovládacího prvku čtverec a text PolyCtl. V tomto kroku změníte kód tak, aby zobrazoval něco zajímavějšího. Patří sem následující úlohy:

  • Úprava hlavičkového souboru

  • Úprava OnDraw funkce

  • Přidání metody pro výpočet mnohoúhelníku

  • Inicializace barvy výplně

Úprava hlavičkového souboru

Začněte přidáním podpory matematických funkcí sin , coskteré se použijí k výpočtu mnohoúhelníku, a vytvořením pole pro ukládání pozic.

Úprava souboru záhlaví

  1. Přidejte čáru #include <math.h> na začátek PolyCtl.h. Horní část souboru by měla vypadat takto:

    #include <math.h>
    #include "resource.h"       // main symbols
    
  2. IProvideClassInfo Implementujte rozhraní pro poskytnutí informací o metodě pro ovládací prvek přidáním následujícího kódu do PolyCtl.h. CPolyCtl Ve třídě nahraďte řádek:

    public CComControl<CPolyCtl>
    

    with

    public CComControl<CPolyCtl>,
    public IProvideClassInfo2Impl<&CLSID_PolyCtl, &DIID__IPolyCtlEvents, &LIBID_PolygonLib>
    

    a do BEGIN_COM_MAP(CPolyCtl), přidejte řádky:

    COM_INTERFACE_ENTRY(IProvideClassInfo)
    COM_INTERFACE_ENTRY(IProvideClassInfo2)
    
  3. Po výpočtu mnohoúhelníku budou uloženy v poli typu POINT, takže přidejte pole za příkaz short m_nSides; definice v PolyCtl.h:

    POINT m_arrPoint[100];
    

Úprava onDraw – metoda

Nyní byste měli upravit metodu OnDraw v PolyCtl.h. Kód, který přidáte, vytvoří nové pero a štětec, se kterým chcete nakreslit mnohoúhelník, a potom zavolá Ellipse funkce rozhraní API Win32 Polygon k provedení skutečného výkresu.

Úprava funkce OnDraw

  1. Nahraďte existující OnDraw metodu v PolyCtl.h následujícím kódem:

    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;
    }
    

Přidání metody pro výpočet mnohoúhelníku

Přidejte metodu nazvanou CalcPoints, která vypočítá souřadnice bodů, které tvoří obvod mnohoúhelníku. Tyto výpočty budou založeny na proměnné RECT, která je předána do funkce.

Přidání metody CalcPoints

  1. Přidejte deklaraci CalcPoints do IPolyCtl veřejné části CPolyCtl třídy v PolyCtl.h:

    void CalcPoints(const RECT& rc);
    

    Poslední část veřejné části CPolyCtl třídy bude vypadat takto:

       void FinalRelease()
       {
       }
    public:
       void CalcPoints(const RECT& rc);
    
  2. Přidejte tuto implementaci CalcPoints funkce na konec 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;
       }
    }
    

Inicializace barvy výplně

Inicializace m_clrFillColor s výchozí barvou

Inicializace barvy výplně

  1. Použijte zelenou jako výchozí barvu přidáním této čáry do konstruktoru CPolyCtl v PolyCtl.h:

    m_clrFillColor = RGB(0, 0xFF, 0);
    

Konstruktor teď vypadá takto:

CPolyCtl()
{
   m_nSides = 3;
   m_clrFillColor = RGB(0, 0xFF, 0);
}

Sestavení a testování ovládacího prvku

Znovu sestavte ovládací prvek. Ujistěte se, že je soubor PolyCtl.htm zavřený, pokud je stále otevřený, a potom klepněte na tlačítko Sestavit mnohoúhelník v nabídce Sestavení . Ovládací prvek můžete znovu zobrazit na stránce PolyCtl.htm, ale tentokrát použijte kontejner testů ovládacích prvků ActiveX.

Použití testovacího kontejneru ovládacích prvků ActiveX

  1. Sestavte a spusťte testovací kontejner ovládacího prvku ActiveX. Ukázka TSTCON: Testovací kontejner ovládacích prvků ActiveX najdete na GitHubu.

    Poznámka:

    V případě chyb zahrnujících ATL::CW2AEXskript.Cpp nahraďte řádek TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT ); řádkem TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz );a řádkem TRACE( "Source Text: %s\n", bstrSourceLineText );TRACE( "Source Text: %s\n", COLE2CT( bstrSourceLineText ) ); .
    V případě chyb souvisejících s HMONITORotevřením souboru StdAfx.h v TCProps projektu a nahrazením:

    #ifndef WINVER
    #define WINVER 0x0400
    #endif
    

    with

    #ifndef WINVER
    #define WINVER 0x0500
    #define _WIN32_WINNT 0x0500
    #endif
    
  2. V testovacím kontejneru v nabídce Upravit klepněte na příkaz Vložit nový ovládací prvek.

  3. Vyhledejte ovládací prvek, který bude volána PolyCtl class, a klepněte na tlačítko OK. V kruhu uvidíte zelený trojúhelník.

Zkuste změnit počet stran pomocí dalšího postupu. Chcete-li upravit vlastnosti v duálním rozhraní z testovacího kontejneru, použijte metody Invoke.

Úprava vlastnosti ovládacího prvku z testovacího kontejneru

  1. V testovacím kontejneru klepněte na tlačítko Vyvolat metody v nabídce Ovládací prvek .

    Zobrazí se dialogové okno Vyvolat metodu .

  2. V rozevíracím seznamu Název metody vyberte verzi PropPut vlastnosti Sides.

  3. Zadejte 5 do pole Hodnota parametru, klepněte na tlačítko Nastavit hodnotu a klepněte na tlačítko Vyvolat.

Všimněte si, že ovládací prvek se nezmění. I když jste počet stran interně změnili nastavením m_nSides proměnné, nezpůsobil to ovládací prvek překreslit. Pokud přepnete do jiné aplikace a pak přepnete zpět do testovacího kontejneru, zjistíte, že se ovládací prvek překresloval a má správný počet stran.

Chcete-li tento problém vyřešit, přidejte volání FireViewChange funkce definované v IViewObjectExImpl, po nastavení počtu stran. Pokud ovládací prvek běží ve vlastním okně, FireViewChange zavolá metodu InvalidateRect přímo. Pokud ovládací prvek běží bez oken, InvalidateRect metoda bude volána v rozhraní lokality kontejneru. To vynutí kontrolu, aby se znovu nakreslila.

Přidání volání do FireViewChange

  1. Aktualizujte PolyCtl.cpp přidáním volání metody FireViewChange put_Sides . Po dokončení put_Sides by metoda měla vypadat takto:

    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 přidání FireViewChangeznovu sestavte a zkuste ovládací prvek znovu v kontejneru testů ovládacích prvků ActiveX. Tentokrát, když změníte počet stran a kliknete , Invokeměli byste vidět změnu ovládacího prvku okamžitě.

V dalším kroku přidáte událost.

Zpět na krok 3 | : Krok 5

Viz také

Kurz
Testování vlastností a událostí pomocí testovacího kontejneru