Etapa 4: Modificando o código de desenho

Por padrão, o código de desenho do controle exibe um quadrado e o texto PolyCtl.Em esta etapa, você irá alterar o código para exibir algo interessante.As seguintes tarefas são involvidas:

  • Alterando o cabeçalho Arquivo

  • Alterando a função de OnDraw

  • Adicionando um método para calcular os pontos polygon

  • Inicializando a cor de preenchimento

Alterando o cabeçalho Arquivo

Início adicionando-se suporte para funções matemáticas sin e cos, que serão usados calculam os pontos de polígonos, e criar uma matriz para armazenar posições.

Para modificar o arquivo de cabeçalho

  1. Adicione a linha #include <math.h> à parte superior de PolyCtl.h.A parte superior do arquivo deve ser assim:

    #include <math.h>
    #include "resource.h"       // main symbols
    
  2. Uma vez que os pontos polygon são calculados, serão armazenados em uma matriz do tipo POINT, para adicionar a matriz após a definição de m_nSides em PolyCtl.h:

    POINT m_arrPoint[100];
    

Alterando o método de OnDraw

Agora você deve modificar o método de OnDraw em PolyCtl.h.O código que você adicionará cria uma nova caneta e pincel para desenhar com que seu polígonos, e então chama funções de Ellipse e de Polygon API do Win32 para executar desenho real.

Para alterar a função de OnDraw

  • Substitua o método existente de OnDraw em PolyCtl.h com o seguinte código:

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

Adicionando um método para calcular os pontos polygon

Adicione um método, CalcPointschamado, calculará que as coordenadas de pontos que compõem o perímetro polígono.Esses serão baseados em cálculos variável RECT que é passado para a função.

Para adicionar o método de CalcPoints

  1. Adicione a declaração de CalcPoints a seção pública de IPolyCtl da classe de CPolyCtl em PolyCtl.h:

    void CalcPoints(const RECT& rc);
    

    A última parte da seção da classe pública de CPolyCtl deve se parecer como este:

       void FinalRelease()
       {
       }
    public:
       STDMETHOD(get_Sides)(short* pVal);
       STDMETHOD(put_Sides)(short newVal);
       void CalcPoints(const RECT& rc);
    
  2. Adicionar essa implementação de função de CalcPoints ao final de 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;
       }
    }
    

Inicializando a cor de preenchimento

Inicializar m_clrFillColor com uma cor padrão.

Para inicializar a cor de preenchimento

  • Use o verde como a cor padrão adicionar essa linha para o construtor de CPolyCtl em PolyCtl.h:

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

O construtor agora tem a seguinte aparência:

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

Compilação e teste o controle

Crie o controle.Certifique-se de que o arquivo PolyCtl.htm é fechado ainda está aberto, e clique em Compile o polígonos no menu de Compilar .Você pode exibir o controle mais uma vez da página PolyCtl.htm, mas esse uso de tempo o contêiner de teste de controle ActiveX.

Para usar o recipiente de teste do controle ActiveX

  1. Criar e ligue o contêiner de teste de controle ActiveX.Para obter mais informações, consulte exemplo de TSTCON: Recipiente de teste do controle ActiveX.

  2. Em o contêiner de teste, no menu de Editar , clique em Novo controle de inserção.

  3. Localize o controle, que será chamado PolyCtl Class, e clique OK.Você verá um triângulo em um círculo verde.

Tente alterar o número de lados seguindo o procedimento a seguir.Para alterar as propriedades de uma interface dupla de dentro do contêiner de teste, use Invoke Methods.

Para alterar a propriedade de um controle dentro do contêiner de teste

  1. Em o contêiner de teste, clique Chamar métodos no menu de Controle .

    a caixa de diálogo de Método invoke é exibida.

  2. Selecione a versão de PropPut da propriedade de Sides da lista suspensa de Nome do Método .

  3. Digite 5 na caixa de Valor do Parâmetro , clique Definir valor, e clique Invoke.

Observe que o controle não muda.Embora você altera o número de lados internamente definir a variável de m_nSides , isso não fez com que o controle repintasse.Se você muda para outro aplicativo e alterne de volta para o contêiner de teste, você verá que o controle repintou e tem o número correto de lados.

Para corrigir esse problema, adicione uma chamada para a função de FireViewChange , definida em IViewObjectExImpl, após você definir o número de lados.Se o controle está sendo executado em sua própria janela, FireViewChange chamar o método de InvalidateRect diretamente.Se o controle é executado sem janelas, o método será chamado de InvalidateRect a interface do site do recipiente.Isso força o controle para repintar-se.

Para adicionar uma chamada para FireViewChange

  • Atualizar PolyCtl.cpp adicionando a chamada a FireViewChange para o método de put_Sides .Quando você terminar, o método de put_Sides deve ser assim:

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

Após adicionar FireViewChange, a recompilação e tentar novamente o controle no recipiente de teste de controle ActiveX.De esta vez quando você altera o número de lados e clique Invoke, você deve ver a alteração do controle imediatamente.

Em o próximo passo, você adicionará um evento.

De volta para a etapa 3 | a etapa 5

Consulte também

Tarefas

Testando propriedades e eventos com o contêiner de teste

Referência

Tutorial de ATL