Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este artigo descreve o processo de pintura do controle ActiveX e como você pode alterar o código de pintura para otimizar o processo. (Consulte Otimizando o desenho de controle para obter técnicas sobre como otimizar o desenho não fazendo com que os controles restaurem individualmente objetos GDI selecionados anteriormente. Depois que todos os controles tiverem sido desenhados, o contêiner poderá restaurar automaticamente os objetos originais.)
Importante
ActiveX é uma tecnologia herdada que não deve ser usada para novos desenvolvimentos. Para obter mais informações sobre tecnologias modernas que substituem o ActiveX, consulte Controles ActiveX.
Exemplos neste artigo são de um controle criado pelo Assistente de controle ActiveX MFC com configurações padrão. Para obter mais informações sobre como criar um aplicativo de controle esqueleto usando o Assistente de controle ActiveX MFC, consulte o artigo Assistente de controle ActiveX MFC.
São abordados os seguintes tópicos:
O processo de pintura de um controle ActiveX
Quando os controles ActiveX são inicialmente exibidos ou redesenhados, eles seguem um processo de pintura semelhante a outros aplicativos desenvolvidos usando MFC, com uma distinção importante: os controles ActiveX podem estar em um estado ativo ou inativo.
Um controlo ativo é representado em um container de controlo ActiveX por uma janela filha. Como outras janelas, ele é responsável por se pintar quando uma mensagem WM_PAINT é recebida. A classe base do controle, COleControl, manipula essa mensagem em sua OnPaint função. Esta implementação padrão chama a função OnDraw do seu controlo.
Um controle inativo é pintado de forma diferente. Quando o controle está inativo, sua janela é invisível ou inexistente, por isso não pode receber uma mensagem de pintura. Em vez disso, o contêiner de controle chama diretamente a função OnDraw do controlo. Isso difere do processo de pintura de um controle ativo, pois a OnPaint função de membro nunca é chamada.
Como discutido nos parágrafos anteriores, como um controle ActiveX é atualizado depende do estado do controle. No entanto, como a estrutura chama a OnDraw função de membro em ambos os casos, você adiciona a maioria do seu código de pintura nessa função de membro.
A OnDraw função de membro lida com a pintura de controle. Quando um controle está inativo, o contêiner de controle chama OnDraw, passando o contexto do dispositivo do contêiner de controle e as coordenadas da área retangular ocupada pelo controle.
O retângulo passado pelo framework para a função membro OnDraw contém a área ocupada pelo controlo. Se o controlo estiver ativo, o canto superior esquerdo é (0, 0) e o contexto do dispositivo passado é para a janela filha que contém o controlo. Se o controle estiver inativo, a coordenada superior esquerda não será necessariamente (0, 0) e o contexto do dispositivo passado será para o contêiner de controle que contém o controle.
Observação
É importante que as suas modificações em OnDraw não dependam de o ponto superior esquerdo do retângulo ser igual a (0, 0) e que desenhe apenas dentro do retângulo passado para OnDraw. Resultados inesperados podem ocorrer se você desenhar além da área do retângulo.
A implementação padrão fornecida pelo Assistente de controle ActiveX MFC 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 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 do dispositivo que é passado como o parâmetro pdc para a OnDraw função. Ocasionalmente, o contexto do dispositivo é fornecido pelo aplicativo contêiner e não será necessariamente inicializado para o estado padrão. Em particular, selecione explicitamente as canetas, pincéis, cores, fontes e outros recursos dos quais o código de desenho depende.
Otimizando seu código do Paint
Depois que o controlo conseguiu se pintar com sucesso, o próximo passo é otimizar a função OnDraw.
A implementação padrão da pintura de controle ActiveX pinta toda a área de controle. Isso é suficiente para controles simples, mas em muitos casos repintar o controle seria mais rápido se apenas a parte que precisava de atualização fosse repintada, em vez de todo o controle.
A OnDraw função fornece um método fácil de otimização passando rcInvalid, a área retangular do controle que precisa ser redesenhada. Use esta área, geralmente menor do que toda a área de controle, para acelerar o processo de pintura.
Pintando seu controle usando metarquivos
Na maioria das vezes, o parâmetro pdc para a função OnDraw aponta para um contexto de dispositivo de ecrã (DC). No entanto, ao imprimir imagens do controlo ou durante uma sessão de pré-visualização de impressão, o DC recebido para renderização é um tipo especial chamado "metafile DC". Ao contrário de um DC de tela, que lida imediatamente com solicitações enviadas a ele, um DC de metaarquivo armazena solicitações para serem reproduzidas posteriormente. Alguns aplicativos de contêiner também podem optar por renderizar a imagem de controle usando um controlador de domínio de metaarquivo quando no modo de design.
As solicitações de desenho de metarquivo podem ser feitas pelo contêiner através de duas funções de interface: IViewObject::Draw (esta função também pode ser chamada para desenho sem metaarquivo) e IDataObject::GetData. Quando um controlador de domínio de metaarquivo é passado como um dos parâmetros, a estrutura MFC faz uma chamada para COleControl::OnDrawMetafile. Como essa é uma função de membro virtual, substitua essa função na classe de controle para fazer qualquer processamento especial. O comportamento padrão chama COleControl::OnDraw.
Para garantir que o controle possa ser desenhado em contextos de dispositivo de tela e metarquivo, você deve usar apenas funções de membro que são suportadas em uma tela e um controlador de domínio de metaarquivo. Lembre-se de que o sistema de coordenadas pode não ser medido em pixels.
Como a implementação padrão de OnDrawMetafile chama a função OnDraw do controlo, use apenas funções que são adequadas tanto para um metarquivo quanto para um contexto de dispositivo de ecrã, a menos que substitua OnDrawMetafile. A seguinte lista apresenta o subconjunto de funções membro que podem ser usadas tanto num metaficheiro como num contexto de dispositivo de ecrã. Para obter mais informações sobre essas funções, consulte classe CDC na referência MFC.
| Arco | BibBlt | Acorde |
|---|---|---|
Ellipse |
Escape |
ExcludeClipRect |
ExtTextOut |
FloodFill |
IntersectClipRect |
LineTo |
MoveTo |
OffsetClipRgn |
OffsetViewportOrg |
OffsetWindowOrg |
PatBlt |
Pie |
Polygon |
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 das funções de CDC membro, existem várias outras funções que são compatíveis num DC de metaarquivo. Estes incluem CPalette::AnimatePalette, CFont::CreateFontIndirect, e três funções de membro de CBrush: CreateBrushIndirect, CreateDIBPatternBrush e CreatePatternBrush.
As 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 controlador de domínio de metarquivo não está realmente associado a um dispositivo, você não pode usar SetDIBits, GetDIBits e CreateDIBitmap com um controlador de domínio de metaarquivo. Você pode usar SetDIBitsToDevice e StretchDIBits com um controlador de domínio de metarquivo como destino. CreateCompatibleDC, CreateCompatibleBitmap e CreateDiscardableBitmap não são significativos com um contexto de dispositivo de metaarquivo.
Outro ponto a considerar ao usar um DC de metaarquivo é que o sistema de coordenadas pode não ser medido em pixels. Por esta razão, todo o seu código de desenho deve ser ajustado para caber no retângulo passado para OnDraw no parâmetro rcBounds . Isso evita a pintura acidental fora do controle porque rcBounds representa o tamanho da janela do controle.
Depois de implementar a renderização de metarquivo para o controle, use Test Container para testar o metaarquivo. Consulte Propriedades e eventos de teste com contêiner de teste para obter informações sobre como acessar o contêiner de teste.
Para testar o metarquivo do controle usando o contêiner de teste
No menu Editar do contêiner de teste, clique em Inserir novo controle.
Na caixa Inserir Novo Controle, selecione o controle e clique em OK.
O controle aparecerá no contêiner de teste.
No menu Controle , clique em Desenhar Metaarquivo.
Uma janela separada é exibida na qual o metarquivo é exibido. Você pode alterar o tamanho dessa janela para ver como o dimensionamento afeta o metarquivo do controle. Pode fechar esta janela a qualquer momento.