Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo descreve o processo de subclasse de um controle comum do Windows para criar um controle ActiveX. A subclasse de um controle existente do Windows é uma maneira rápida de desenvolver um controle ActiveX. O novo controle terá as habilidades do controle do Windows subclasse, como pintar e responder a cliques do mouse. O botão de exemplo de controles ActiveX do MFC é um exemplo de subclasse de um controle do Windows.
Importante
O ActiveX é uma tecnologia herdada que não deve ser usada para o novo desenvolvimento. Para obter mais informações sobre tecnologias modernas que substituem o ActiveX, consulte Controles ActiveX.
Para subclasse de um controle do Windows, conclua as seguintes tarefas:
Substituir as funções de membro IsSubclassedControl e PreCreateWindow do COleControl
Manipular mensagens de controle ActiveX (OCM) refletidas no controle
Observação
Grande parte desse trabalho é feito para você pelo Assistente de Controle ActiveX se você selecionar o controle a ser subclasse usando a lista suspensa Selecionar Classe de Janela Pai na página Configurações de Controle .
Substituindo IsSubclassedControl e PreCreateWindow
Para substituir PreCreateWindow e IsSubclassedControladicionar as seguintes linhas de código à protected seção da declaração da classe de controle:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();
No arquivo de implementação de controle (. CPP), adicione as seguintes linhas de código para implementar as duas funções substituídas:
// CMyAxSubCtrl::PreCreateWindow - Modify parameters for CreateWindowEx
BOOL CMyAxSubCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
cs.lpszClass = _T("BUTTON");
return COleControl::PreCreateWindow(cs);
}
// CMyAxSubCtrl::IsSubclassedControl - This is a subclassed control
BOOL CMyAxSubCtrl::IsSubclassedControl()
{
return TRUE;
}
Observe que, neste exemplo, o controle de botão do Windows é especificado em PreCreateWindow. No entanto, qualquer controle padrão do Windows pode ser subclasse. Para obter mais informações sobre controles padrão do Windows, consulte Controles.
Ao subclasse de um controle do Windows, convém especificar um estilo de janela específico (WS_) ou sinalizadores de estilo de janela estendido (WS_EX_) a serem usados na criação da janela do controle. Você pode definir valores para esses parâmetros na PreCreateWindow função membro modificando os cs.style campos e a cs.dwExStyle estrutura. As modificações nesses campos devem ser feitas usando uma operação OR , para preservar os sinalizadores padrão definidos por classe COleControl. Por exemplo, se o controle estiver subclasse o controle BUTTON e você quiser que o controle apareça como uma caixa de seleção, insira a seguinte linha de código na implementação de , antes da CSampleCtrl::PreCreateWindowinstrução de retorno:
cs.style |= BS_CHECKBOX;
Essa operação adiciona o sinalizador de estilo BS_CHECKBOX, deixando o sinalizador de estilo padrão (WS_CHILD) da classe COleControl intacto.
Modificando a função de membro OnDraw
Se você quiser que o controle subclasse mantenha a mesma aparência do controle do Windows correspondente, a OnDraw função membro do controle deverá conter apenas uma chamada para a DoSuperclassPaint função membro, como no exemplo a seguir:
void CMyAxSubCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
if (!pdc)
return;
DoSuperclassPaint(pdc, rcBounds);
}
A DoSuperclassPaint função membro, implementada por COleControl, usa o procedimento de janela do controle do Windows para desenhar o controle no contexto do dispositivo especificado, dentro do retângulo delimitador. Isso torna o controle visível mesmo quando ele não está ativo.
Observação
A DoSuperclassPaint função membro funcionará somente com os tipos de controle que permitem que um contexto de dispositivo seja passado como o wParam de uma mensagem de WM_PAINT. Isso inclui alguns dos controles padrão do Windows, como SCROLLBAR e BUTTON, e todos os controles comuns. Para controles que não dão suporte a esse comportamento, você precisará fornecer seu próprio código para exibir corretamente um controle inativo.
Manipulando mensagens de janela refletidas
Os controles do Windows normalmente enviam determinadas mensagens de janela para a janela pai. Algumas dessas mensagens, como WM_COMMAND, fornecem notificação de uma ação pelo usuário. Outros, como WM_CTLCOLOR, são usados para obter informações da janela pai. Um controle ActiveX geralmente se comunica com a janela pai por outros meios. As notificações são comunicadas disparando eventos (enviando notificações de evento) e informações sobre o contêiner de controle são obtidas acessando as propriedades ambientes do contêiner. Como essas técnicas de comunicação existem, os contêineres de controle ActiveX não devem processar nenhuma mensagem de janela enviada pelo controle.
Para impedir que o contêiner receba as mensagens de janela enviadas por um controle do Windows subclasse, COleControl cria uma janela extra para servir como pai do controle. Essa janela extra, chamada de "refletor", é criada apenas para um controle ActiveX que subclasse um controle do Windows e tem o mesmo tamanho e posição que a janela de controle. A janela do refletor intercepta determinadas mensagens de janela e as envia de volta ao controle. O controle, em seu procedimento de janela, pode processar essas mensagens refletidas executando ações apropriadas para um controle ActiveX (por exemplo, disparar um evento). Consulte IDs de Mensagem da Janela Refletida para obter uma lista de mensagens interceptadas do Windows e suas mensagens refletidas correspondentes.
Um contêiner de controle ActiveX pode ser projetado para executar a reflexão de mensagem em si, eliminando a necessidade de COleControl criar a janela do refletor e reduzindo a sobrecarga de tempo de execução para um controle do Windows subclasse.
COleControl detecta se o contêiner dá suporte a essa funcionalidade verificando se há uma propriedade ambiente MessageReflect com um valor VERDADEIRO.
Para lidar com uma mensagem de janela refletida, adicione uma entrada ao mapa de mensagens de controle e implemente uma função de manipulador. Como as mensagens refletidas não fazem parte do conjunto padrão de mensagens definidas pelo Windows, o Modo de Exibição de Classe não dá suporte à adição desses manipuladores de mensagens. No entanto, não é difícil adicionar um manipulador manualmente.
Para adicionar um manipulador de mensagens a uma mensagem de janela refletida manualmente, faça o seguinte:
Na classe de controle. Arquivo H, declarar uma função de manipulador. A função deve ter um tipo de retorno de LRESULT e dois parâmetros, com os tipos WPARAM e LPARAM, respectivamente. Por exemplo:
class CMyAxSubCtrl : public COleControl {protected: LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam); };Na classe de controle. Arquivo CPP, adicione uma entrada ON_MESSAGE ao mapa de mensagens. Os parâmetros dessa entrada devem ser o identificador de mensagem e o nome da função de manipulador. Por exemplo:
BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl) ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand) END_MESSAGE_MAP()Também no . Arquivo CPP, implemente a
OnOcmCommandfunção membro para processar a mensagem refletida. Os parâmetros wParam e lParam são os mesmos da mensagem de janela original.
Para obter um exemplo de como as mensagens refletidas são processadas, consulte o botão de exemplo de controles ActiveX do MFC. Ele demonstra um OnOcmCommand manipulador que detecta o código de notificação BN_CLICKED e responde disparando (enviando) um Click evento.