Controles de ActiveX MFC: Pintura de um controle ActiveX
Este artigo descreve o processo de pintura de controle de ActiveX e como você pode alterar o código de pintura para otimizar o processo.(Consulte Otimizando controle desenho de técnicas sobre como otimizar o desenho por não ter controles individualmente restaurar objetos GDI selecionados anteriormente.Após todos os controles foram desenhados, o contêiner pode automaticamente restaurar os objetos originais.)
Os exemplos neste artigo são de um controle criado pelo Assistente de controle de ActiveX do MFC com configurações padrão.Para obter mais informações sobre a criação de um aplicativo de esqueleto de controle usando o Assistente de controle de ActiveX do MFC, consulte o artigo Assistente de controle MFC ActiveX.
Os seguintes tópicos são abordados:
O processo geral para pintura um controle e o código criado pelo Assistente de controle de ActiveX para oferecer suporte a pintura
Como otimizar o processo de pintura
Como pintar seu controle usando metarquivos
O processo de pintura de um controle ActiveX
Quando ActiveX controles são exibidos inicialmente ou são redesenhados, eles seguem um processo de pintura semelhante a outros aplicativos desenvolvidos usando o MFC, com uma distinção importante: controles de ActiveX podem ser um ativo ou um estado inativo.
Um controle ativo é representado em um contêiner de controle de ActiveX por uma janela filho.Como outras janelas, é responsável pela pintura próprio quando um WM_PAINT mensagem é recebida.Classe de base do controle, COleControl, trata esta mensagem no seu OnPaint função.Esta implementação padrão chama o OnDraw função do seu controle.
Um controle inativo é pintado de forma diferente.Quando o controle está inativo, sua janela é invisível ou inexistente, portanto, ele não pode receber uma mensagem de pintura.Em vez disso, o contêiner de controle diretamente chama o OnDraw função do controle.Isso difere do processo de pintura de um controle ativo em que o OnPaint nunca é chamada de função de membro.
Conforme discutido nos parágrafos anteriores, como um controle ActiveX é atualizado depende do estado do controle.No entanto, como o framework chama o OnDraw função de membro em ambos os casos, você adicionar a maior parte do seu código de pintura esta função de membro.
O OnDraw função de membro trata pintura de controle.Quando um controle está inativo, o contêiner de controle chama OnDraw, passando o contexto de dispositivo do contêiner de controle e as coordenadas da área retangular ocupada pelo controle.
O retângulo passado pela estrutura para o OnDraw função de membro contém a área ocupada pelo controle.Se o controle estiver ativo, o canto superior esquerdo é (0, 0) e o contexto para dispositivo passado para a janela filho que contém o controle.Se o controle está inativo, a coordenada superior esquerdo não é necessariamente (0, 0) e o contexto para dispositivo passado para o contêiner de controle que contém o controle.
Observação |
---|
É importante que as modificações OnDraw não dependem do ponto esquerdo superior do retângulo sendo igual a (0, 0) e desenhar somente dentro do retângulo passado para OnDraw.Podem ocorrer resultados inesperados se você desenhar além área do retângulo. |
A implementação padrão fornecida pelo Assistente de controle de MFC ActiveX no arquivo de implementação de controle (.CPP), mostrado abaixo, pinta o retângulo com um pincel branco e preenche a elipse com a cor de plano de fundo atual.
void CMyAxUICtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
if (!pdc)
return;
// TODO: Replace the following code with your own drawing code.
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->Ellipse(rcBounds);
}
Observação |
---|
Ao pintar um controle, você não deve fazer suposições sobre o estado do contexto de dispositivo é passado como o pdc parâmetro para o OnDraw função.Ocasionalmente, o contexto de dispositivo fornecido pelo aplicativo de contêiner e necessariamente não será possível inicializar o estado padrão.Em particular, explicitamente selecione as canetas, pincéis, cores, fontes e outros recursos que seu código desenho depende. |
Otimizar o código de pintura
Após o controle com êxito é pintura propriamente dito, a próxima etapa é otimizar o OnDraw função.
A implementação padrão do controle ActiveX pintura pinta a área inteira do controle.Isso é suficiente para controles simples, mas em muitos casos redesenho o controle seria mais rápido se apenas a parte que precisava atualizar foi redesenhada, em vez de todo o controle.
O OnDraw função fornece um método fácil de otimização, passando rcInvalid, a área retangular do controle precisa redesenho.Use esta área, geralmente menor que a área inteira do controle, para acelerar o processo de pintura.
Pintura seu controle usando metarquivos
Na maioria dos casos o pdc parâmetro para o OnDraw função aponta para um contexto de dispositivo de tela (DC).No entanto, ao imprimir imagens do controle ou durante uma sessão de visualização de impressão, o DC recebido para processamento é um tipo especial chamado um "metarquivo DC".Ao contrário de uma tela DC, imediatamente trata solicitações enviadas a ele, um metarquivo do controlador de domínio armazena as solicitações para ser reproduzido em um momento posterior.Alguns aplicativos recipientes também podem optar por processar a imagem do controle usando um metarquivo do controlador de domínio no modo de design.
Metarquivo desenho solicitações pode ser feito pelo recipiente através de duas funções de interface: IViewObject::Draw (essa função também pode ser chamada de não-metarquivo desenho) e IDataObject:: GetData.Quando um metarquivo DC é passado como um dos parâmetros, o framework MFC faz uma chamada para COleControl::OnDrawMetafile.Como esta é uma função de membro virtual, substitua essa função na classe do controle para fazer qualquer processamento especial.Chamadas de comportamento padrão COleControl::OnDraw.
Para certificar-se de que o controle pode ser desenhado na tela e Metarquivo contextos de dispositivo, você deve usar apenas as funções de membro que são suportadas em uma tela e um metarquivo DC.Lembre-se de que o sistema de coordenadas não pode ser medido em pixels.
Porque a implementação padrão de OnDrawMetafile chama o controle OnDraw função, use apenas as funções de membro que são adequadas para um metarquivo e um contexto de dispositivo de tela, a menos que você substituir OnDrawMetafile.A seguir lista o subconjunto de CDC funções de membro podem ser usadas em um metarquivo e um contexto de dispositivo de tela.Para obter mais informações sobre essas funções, consulte a classe CDC na Referência MFC.
Arco |
BibBlt |
Corda |
---|---|---|
Elipse |
Escape |
ExcludeClipRect |
ExtTextOut |
FloodFill |
IntersectClipRect |
LineTo |
MoveTo |
OffsetClipRgn |
OffsetViewportOrg |
OffsetWindowOrg |
PatBlt |
Pie |
Polígono |
Polyline |
PolyPolygon |
RealizePalette |
RestoreDC |
RoundRect |
SaveDC |
ScaleViewportExt |
ScaleWindowExt |
SelectClipRgn |
SelectObject |
SelectPalette |
SetBkColor |
SetBkMode |
SetMapMode |
SetMapperFlags |
SetPixel |
SetPolyFillMode |
SetROP2 |
SetStretchBltMode |
SetTextColor |
SetTextJustification |
SetViewportExt |
SetViewportOrg |
SetWindowExt |
SetWindowORg |
StretchBlt |
TextOut |
|
Além dos CDC funções de membro, há várias outras funções que são compatíveis em um metarquivo DC.Esses incluem CPalette::AnimatePalette, CFont::CreateFontIndirecte três funções de membro de CBrush: CreateBrushIndirect, CreateDIBPatternBrush, e CreatePatternBrush.
Funções que não são registradas em um metarquivo são: DrawFocusRect, DrawIcon, DrawText, ExcludeUpdateRgn, FillRect, FrameRect, GrayString, InvertRect, ScrollDC, e TabbedTextOut.Como um metarquivo do controlador de domínio não é realmente associado com um dispositivo, você não pode usar SetDIBits, GetDIBits e CreateDIBitmap com um metarquivo do controlador de domínio.Você pode usar SetDIBitsToDevice e StretchDIBits com um metarquivo do controlador de domínio como o destino.CreateCompatibleDC, CreateCompatibleBitmap, e CreateDiscardableBitmap não são significativos com um metarquivo do controlador de domínio.
Outro ponto a considerar ao usar um metarquivo DC é o sistema de coordenadas não pode ser medido em pixels.Por esse motivo, todo o seu código desenho deve ser ajustado para caber no retângulo passado para OnDraw na rcBounds parâmetro.Isso impede que pintura acidental fora do controle porque rcBounds representa o tamanho da janela do controle.
Após implementar o processamento de metarquivo para o controle, use o contêiner de teste para testar o metarquivo.Consulte testes de propriedades e eventos com o contêiner de teste do para obter informações sobre como acessar o contêiner de teste.
Para testar o metarquivo do controle usando o contêiner de teste
O contêiner de teste Editar menu, clique em Inserir novo controle.
No Inserir novo controle caixa, selecione o controle e clique em OK.
O controle será exibida no contêiner de teste.
Sobre o controle menu, clique em Desenhar metarquivo.
Será exibida uma janela separada na qual o metarquivo é exibido.Você pode alterar o tamanho da janela para ver como a escala afeta metarquivo do controle.Você pode fechar esta janela a qualquer momento.