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
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
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
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);
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
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.
Em o contêiner de teste, no menu de Editar , clique em Novo controle de inserção.
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
Em o contêiner de teste, clique Chamar métodos no menu de Controle .
a caixa de diálogo de Método invoke é exibida.
Selecione a versão de PropPut da propriedade de Sides da lista suspensa de Nome do Método .
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