Partilhar via


Fornecendo ativação sem interface de janela

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

Uma outra vantagem dos controles sem janela é que, ao contrário dos controles sem janela, os controles sem janela suportam pintura transparente e regiões de tela não retangulares. Um exemplo comum de um controle transparente é um controle de texto com um plano de fundo transparente. Os controles pintam o texto, mas não o plano de fundo, portanto, tudo o que está sob o texto é mostrado. Formulários mais recentes geralmente fazem uso de 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 escrito para suportar objetos sem janelas. Os controles sem janela são compatíveis com contêineres mais antigos. Em contêineres antigos que não foram gravados para suportar os controles sem janelas, os controles sem janelas criam uma janela quando estão ativos.

Como os controles sem janela 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 desta interface.) COleControl As funções de membro invocam esses serviços a partir do contêiner.

Para fazer com que seu controle use a ativação sem janela, 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 é 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 MFC.

Quando a ativação sem janela estiver habilitada, o contêiner delegará mensagens de entrada à interface do IOleInPlaceObjectWindowless controle. COleControlA implementação desta interface despacha as mensagens através do mapa de mensagens do seu 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 de membro que a use) sem primeiro verificar se seu valor não é NULL.

COleControl fornece funções de 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 controlos sem janelas, deve sempre utilizar as funções de membro COleControl em vez das funções de membro correspondentes CWnd ou das suas funções relacionadas da API Win32.

Você pode querer que um controle sem janela seja o destino de uma operação de arrastar e soltar OLE. Normalmente, isso exigiria que a janela do controle fosse registrada como um alvo de queda. Como o controle não tem janela própria, o contêiner usa sua própria janela como um alvo de queda. O controlo fornece uma implementação da interface IDropTarget à qual o contentor 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;
}

Ver também

Controles ActiveX MFC: Otimização