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 para subclassificar um controle comum do Windows para criar um controle ActiveX. Subclassificar um controle existente do Windows é uma maneira rápida de desenvolver um controle ActiveX. O novo controle terá as habilidades do controle subclassificado do Windows, como pintar e responder a cliques do mouse. O exemplo de controles ActiveX MFC BUTTON é um exemplo de subclassificação de um controle do Windows.
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.
Para subclassificar um controle do Windows, conclua as seguintes tarefas:
Sobreponha as funções de membro IsSubclassedControl e PreCreateWindow do COleControl
Manipular quaisquer mensagens de controle ActiveX (OCM) refletidas para o controle
Observação
Grande parte desse trabalho é feito para você pelo Assistente de Controle ActiveX se você selecionar o controle a ser subclassificado usando a lista suspensa Selecionar Classe de Janela Pai na página Configurações de Controle .
Substituindo IsSubclassedControl e PreCreateWindow
Para substituir PreCreateWindow e IsSubclassedControl, adicione as seguintes linhas de código à protected seção da declaração de classe de controle:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();
No ficheiro de execução do controlo (. 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 subclassificado. Para obter mais informações sobre controles padrão do Windows, consulte Controles.
Ao subclassificar um controle do Windows, convém especificar determinados sinalizadores de estilo de janela (WS_) ou estilo de janela estendida (WS_EX_) a serem usados na criação da janela do controle. Você pode definir valores para esses parâmetros na PreCreateWindow função de 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 controlo estiver a sobrescrever o controlo BUTTON e quiser que o controlo apareça como uma caixa de seleção, insira a seguinte linha de código na implementação de CSampleCtrl::PreCreateWindow, antes da instrução return:
cs.style |= BS_CHECKBOX;
Esta operação adiciona o sinalizador de estilo BS_CHECKBOX, deixando intacto o sinalizador de estilo padrão (WS_CHILD) da classe COleControl .
Modificando a função de membro do OnDraw
Se você quiser que seu controle subclassificado mantenha a mesma aparência que o controle do Windows correspondente, a OnDraw função de membro para o controle deve conter apenas uma chamada para a DoSuperclassPaint função de membro, como no exemplo a seguir:
void CMyAxSubCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
if (!pdc)
return;
DoSuperclassPaint(pdc, rcBounds);
}
A função de membro DoSuperclassPaint, implementada por COleControl, utiliza o procedimento de janela do controlo do Windows para desenhar o controlo 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 de membro funcionará apenas com os tipos de controle que permitem que um contexto de dispositivo seja passado como o wParam de uma mensagem 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 suportam esse comportamento, você terá que 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 por parte do usuário. Outros, como WM_CTLCOLOR, são usados para obter informações da janela principal. Um controle ActiveX geralmente se comunica com a janela pai por outros meios. As notificações são comunicadas por eventos de disparo (envio de notificações de eventos), e as informações sobre o contêiner de controle são obtidas acessando as propriedades ambientais do contêiner. Como essas técnicas de comunicação existem, não se espera que os contêineres de controle ActiveX processem mensagens de janela enviadas pelo controle.
Para impedir que o contêiner receba as mensagens de janela enviadas por um controle do Windows subclassificado, 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 refletora interceta determinadas mensagens e as envia de volta ao controlo. 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 de janela refletida para ver uma lista de mensagens intercetadas do Windows e suas mensagens refletidas correspondentes.
Um contentor de controlo ActiveX pode ser concebido para realizar a reflexão da mensagem por si mesmo, eliminando a necessidade de COleControl criar a janela refletora e reduzindo a sobrecarga no tempo de execução para um controlo do Windows subclassificado.
COleControldeteta se o contêiner oferece suporte a esse recurso verificando se há uma propriedade de ambiente MessageReflect com um valor TRUE.
Para manipular uma mensagem de janela refletida, adicione uma entrada ao mapa de mensagem de controle e implemente uma função de manipulador. Como as mensagens refletidas não fazem parte do conjunto padrão de mensagens definido pelo Windows, o Modo de Exibição de Classe não oferece suporte à adição desses manipuladores de mensagens. No entanto, não é difícil adicionar um manipulador manualmente.
Para adicionar um manipulador de mensagens para uma mensagem de janela refletida manualmente, faça o seguinte:
Na classe de controlo . H, declare 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 controlo .CPP, adicione uma entrada ON_MESSAGE no mapa de mensagens. Os parâmetros desta entrada devem ser o identificador da mensagem e o nome da função do manipulador. Por exemplo:
BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl) ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand) END_MESSAGE_MAP()Também no . CPP, implemente a
OnOcmCommandfunção de membro para processar a mensagem refletida. Os parâmetros wParam e lParam são os mesmos da mensagem da janela original.
Para obter um exemplo de como as mensagens refletidas são processadas, consulte o exemplo de controles ActiveX do MFC BUTTON. Ele demonstra um OnOcmCommand manipulador que deteta o código de notificação BN_CLICKED e responde disparando (enviando) um Click evento.