O código de desenho que você usará funções sin e cos para calcular os pontos de polígono, para adicionar incluir matemática na parte superior de PolyCtl. H:
# include lt;math.h >
# include "Resource. h" / / principais símbolos
&Nota para a imprensa constrói apenasnbsp; Quando o AppWizard de COM ATL gera o projeto padrão, ele define a macro ATL_MIN_CRT. Essa macro é definida para que você não trazer a biblioteca C Run-Time para seu código se você não precisa dele. O controle de polígono precisa o código de arranque de biblioteca C Run-Time para inicializar as funções de ponto flutuante. Portanto, você precisará remover a macro ATL_MIN_CRT se você quiser construir uma versão de lançamento. Para remover a macro, clique em configurações no menu Project . Na configurações para: soltar-para baixo lista, escolher Várias configurações. Na Selecionar configurações de projeto alterar caixa de diálogo que aparece, clique as caixas de seleção para todas as quatro versões de lançamento e, em seguida, clique em OK. No separador de C/C++ , escolha a categoria Geral e, em seguida, remover ATL_MIN_CRT da caixa de editar as definições de pré-processador.
Uma vez que são calculados os pontos do polígono, você armazena os pontos, adicionando uma matriz do tipo POINT para o fim da definição da classe in PolyCtl. H:
OLE_COLOR m_clrFillColor;
m_nSides curto;
PONTO de m_arrPoint [100]
Agora altere o OnDraw função em PolyCtl. H para corresponder a essa abaixo. Observe que você remova as chamadas para as funções retângulo e DrawText. Você também explicitamente obter e selecione um pincel em branco e caneta preta. Você precisa fazer isso caso seu controle está sendo executado sem janelas. Se você não tiver sua própria janela, você não pode fazer suposições sobre o contexto de dispositivo que você vai desenhando.
O concluído OnDraw parece com isso:
HRESULT CPolyCtl::OnDraw(ATL_DRAWINFOamp; di)
{
RECT & rc = *(RECT*)di.prcBounds;
HDC hdc = di.hdcDraw;
COLORREF colFore;
HBRUSH hOldBrush, hBrush;
HPEN hOldPen, hPen;
/ / Translate m_colFore em um tipo COLORREF
OleTranslateColor (m_clrFillColor, NULL, & colFore);
/ / Criar e selecione cores para desenhar o círculo
hPen = (HPEN)GetStockObject(BLACK_PEN);
hOldPen = (HPEN) SelectObject (hdc, hPen);
hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
hOldBrush = (HBRUSH) SelectObject (hdc, hBrush);
Elipse (hdc, rc.left, rc.top, rc.right, rc.bottom);
/ / Criar e selecione o pincel que será usado para preencher o polígono
hBrush = CreateSolidBrush(colFore);
SelectObject (hdc, hBrush);
CalcPoints(rc);
Polígono (hdc, & m_arrPoint [0], m_nSides);
/ / Selecionar volta a antiga caneta e pincel e excluir o brush que criamos
SelectObject (hdc, hOldPen);
SelectObject (hdc, hOldBrush);
DeleteObject(hBrush);
retornar S_OK;
}
Você agora precisará adicio&nar uma função, chamada CalcPoints , que irá calcular as coordenadas da linha intersections.nbsp; Esses cálculos se baseará na variável RECT que é passado para a função. Primeiro você deve adicionar a definição de CalcPoints a seção pública da classe IPolyCtl em PolyCtl. H:
voidnbsp; CalcPoints (const RECT & rc)
A seção pública da classe IPolyCtl deve agora olhar como este:
/ / IPolyCtl
público:
STDMETHOD(get_Sides) (/ * [out, retval] * / curto * newVal);
STDMETHOD(put_Sides) (/ * [no] * / curta-newVal);
voidnbsp; CalcPoints (const RECT & rc)
Em seguida, adicionar the implementação of a CalcPoints função para o final do arquivo PolyCtl. cpp:
void CPolyCtl::CalcPoints (const RECTamp; rc)
{
const double pi = 3,14159265358979;
PONTO de ptCenter;
Double dblRadiusx = (rc.right - rc.left) / 2;
Double dblRadiusy = (rc.bottom - rc.top) / 2;
Double dblAngle = 3 * pi / 2; / / Iniciar na parte superior
Double dblDiff = 2 * pi / m_nSides; / / Ângulo de cada lado vai fazer
ptCenter.x = (rc.left + rc.right) / 2;
ptCenter.y = (rc.top + rc.bottom) / 2;
/ / Calcular os pontos para cada lado
para (int i = 0; i < m_nSides; i + +)
{
m_arrPoint [i]. x = (long) (dblRadiusx * cos(dblAngle) + ptCenter.x + 0.5);
.y m_arrPoint [i] = (long) (dblRadiusy * sin(dblAngle) + ptCenter.y + 0.5);
dblAngle + = dblDiff;
}
}
Agora, inicializar m_clrFillColor . Escolha verde como a cor padrão e adicionar esta linha para o CPolyCtl Construtor em PolyCtl. H:
m_clrFillColor = RGB (0, 0xFF, 0)
O Construtor agora esta aparência:
CPolyCtl()
{
m_nSides = 3;
m_clrFillColor = RGB (0, 0xFF, 0);
}
Agora reconstruir o controle e tente novamente. Abra o Controlarar ActiveX teste recipiente e inserir o controle. Você deve ver um triângulo verde dentro de um círculo. Tente alterar o número de lados, seguindo as etapas abaixo. Para modificar as propriedades de uma interface dupla do dentro o Contêiner de teste, use Invocação métodos:

Observe que o controle não muda. Qual é o problema? Embora você mudou o número de lados internamente, definindo o m_nSides variável, você não causa o controle para redesenhar. Se você alterna para outro aplicativo e, em seguida, alterna de volta para o Contêiner de teste , você vai descobrir que o Controlarar é redesenhado e agora tem o número correto de lados.
Para corrigir esse problema, você precisará adicionar uma chamada para a função FireViewChange , que é definida em IViewObjectExImpl, depois de definir o número de lados. Se o Controlarar está sendo executado em sua própria janela, FireViewChange irá chamar o InvalidateRect API diretamente. Se o Controlarar está sendo executado sem janelas, o método InvalidateRect será chamado no site interface Contêiner. Isso força o Controlarar para redesenhar propriamente dito.
O novo put_Sides método é o seguinte:
STDMETHODIMP CPolyCtl::put_Sides(short newVal)
{
se (newVal gt; 2 & & newVal < 101)
{
m_nSides = newVal;
FireViewChange();
retornar S_OK;
}
outra pessoa
retornam o erro ( t ("forma deve ter entre 3 e 100"));
}
Depois de adicionar FireViewChange, reconstruir e tente novamente o controle. Desta vez quando você alterar o número de lados e clique em Invoke, você deverá ver o controle alterar imediatamente.
Avançar, você irá adicionar um evento para o controle.
Voltar à etapa 3 |nbsp; A etapa 5