Compartilhar via


Fornecendo ativação sem interface de janelas

O código de criação da janela (ou seja, tudo o que acontece quando você chama CreateWindow) é caro para ser executado. Um controle que mantém uma janela na tela precisa gerenciar mensagens para a janela. Portanto, os controles sem janela são mais rápidos do que os controles com janelas.

Uma vantagem adicional dos controles sem janelas é que, ao contrário dos controles com janelas, os controles sem janela dão suporte à pintura transparente e a regiões de tela não retangulares. Um exemplo comum de um controle transparente é um controle de texto com uma tela de fundo transparente. Os controles pintam o texto, mas não a tela de fundo, portanto, o que estiver sob o texto será exibido. Formulários mais recentes geralmente usam controles não retangulares, como setas e botões redondos.

Muitas vezes, um controle não precisa de uma janela própria e, em vez disso, pode usar os serviços de janela de seu contêiner, desde que o contêiner tenha sido gravado para dar suporte a objetos sem janelas. Os controles sem janela são retrocompatíveis com contêineres mais antigos. Em contêineres mais antigos que não foram projetados para suportar controles sem janela, os controles sem janela criam uma janela quando ativados.

Como os controles sem janelas não têm suas próprias janelas, o contêiner (que tem uma janela) é responsável por fornecer serviços que, de outra forma, teriam sido fornecidos pela própria janela do controle. Por exemplo, se o controle precisar consultar o foco do teclado, capturar o mouse ou obter um contexto de dispositivo, essas operações serão gerenciadas pelo contêiner. O contêiner roteia as mensagens de entrada do usuário enviadas para sua janela para o controle sem janela apropriado, usando a IOleInPlaceObjectWindowless interface. (Consulte o SDK do ActiveX para obter uma descrição dessa interface.) COleControl as funções membro invocam esses serviços do contêiner.

Para fazer com que seu controle use a ativação sem janelas, inclua o sinalizador windowlessActivate no conjunto de sinalizadores retornados por COleControl::GetControlFlags. Por exemplo:

DWORD CMyAxOptCtrl::GetControlFlags()
{
   DWORD dwFlags = COleControl::GetControlFlags();
// The control can activate without creating a window.
dwFlags |= windowlessActivate;
return dwFlags;
}

O código para incluir esse sinalizador será gerado automaticamente se você selecionar a opção de ativação sem janela na página Configurações de Controle do Assistente de Controle ActiveX do MFC.

Quando a ativação sem janela estiver habilitada, o contêiner delegará mensagens de entrada para a interface do IOleInPlaceObjectWindowless controle. COleControlA implementação dessa interface envia as mensagens por meio do mapa de mensagens do controle, depois de ajustar as coordenadas do mouse adequadamente. Você pode processar as mensagens como mensagens de janela comuns adicionando as entradas correspondentes ao mapa de mensagens. Em seus manipuladores para essas mensagens, evite usar a variável de membro m_hWnd (ou qualquer função membro que a use) sem primeiro verificar se seu valor não é NULL.

COleControl fornece funções membro que invocam a captura do mouse, o foco do teclado, a rolagem e outros serviços de janela do contêiner, conforme apropriado, incluindo:

Em controles sem janelas, você sempre deve usar as funções de membro COleControl em vez das funções de membro correspondentes CWnd ou suas funções de API Win32 relacionadas.

Talvez você queira que um controle sem janelas seja o destino de uma operação de arrastar e soltar OLE. Normalmente, isso exigiria que a janela do controle fosse registrada como um destino suspenso. Como o controle não possui janela própria, o contêiner utiliza sua própria janela como alvo de soltura. O controle fornece uma implementação da IDropTarget interface à qual o contêiner pode delegar chamadas no momento apropriado. Para expor essa interface ao contêiner, substitua COleControl::GetWindowlessDropTarget. Por exemplo:

IDropTarget* CMyAxOptCtrl::GetWindowlessDropTarget()
{
   m_DropTarget.m_xDropTarget.AddRef();
   return &m_DropTarget.m_xDropTarget;
}

Consulte também

Controles ActiveX do MFC: Otimização