Compartilhar via


Controles ActiveX na Internet

Os controles ActiveX são a versão atualizada da especificação de controle OLE.

Importante

O ActiveX é uma tecnologia herdada que não deve ser usada para novo desenvolvimento. Para obter mais informações, confira Controles ActiveX.

Os controles são uma arquitetura primária para desenvolver componentes de software programáveis que podem ser usados em diversos contêineres diferentes, incluindo navegadores da Web com reconhecimento de COM na Internet. Qualquer controle ActiveX pode ser um controle da Internet e pode adicionar sua funcionalidade a um documento ativo ou fazer parte de uma página da Web. Os controles em uma página da Web podem se comunicar entre si usando scripts.

Os controles ActiveX não estão limitados à Internet. Um controle ActiveX também pode ser usado em qualquer contêiner, desde que dê suporte às interfaces exigidas por esse contêiner.

Os controles ActiveX têm várias vantagens, incluindo:

  • Menos interfaces necessárias do que os controles OLE anteriores.

  • A capacidade de serem sem janelas e sempre ativos no local.

Para ser um controle ActiveX, um controle precisa:

  • Dar suporte à interface IUnknown.

  • Ser um objeto COM.

  • Exportar DLLRegisterServer e DLLUnRegisterServer.

  • Dar suporte a interfaces adicionais, conforme necessário para a funcionalidade.

Tornando seus controles existentes amigáveis para a Internet

A criação de um controle que funcionará bem em um ambiente da Internet requer consideração quanto às taxas de transmissão relativamente baixas na Internet. Você pode usar seus controles existentes, no entanto, há etapas que precisará seguir para reduzir o tamanho do código e fazer com que as propriedades do controle sejam baixadas de maneira assíncrona.

Para aprimorar o desempenho dos controles, siga estas dicas sobre eficiência:

  • Implemente as técnicas descritas no artigo Controles ActiveX: otimização.

  • Considere como um controle é instanciado.

  • Ser for assíncrono, não mantenha outros programas em espera.

  • Baixe os dados em blocos pequenos.

    Ao baixar grandes fluxos, como dados de vídeo ou bitmaps, acesse os dados de um controle de maneira assíncrona em cooperação com o contêiner. Recupere os dados de maneira incremental ou progressiva, trabalhando em cooperação com outros controles que também podem estar recuperando dados. O código também pode ser baixado de modo assíncrono.

  • Baixe o código e as propriedades em segundo plano.

  • Torne-se ativo na interface do usuário o mais rápido possível.

  • Considere como os dados persistentes são armazenados, tanto as propriedades quanto os BLOBs de dados grandes (como imagens bitmap ou dados de vídeo).

    Controles com quantidades significativas de dados persistentes, como bitmaps grandes ou arquivos AVI, exigem muita atenção ao método de download. Um documento ou página pode ficar visível assim que possível e permitir que o usuário interaja com a página enquanto os controles recuperam dados em segundo plano.

  • Escreva rotinas eficientes para manter o tamanho do código e o tempo de execução reduzidos.

    Controles de botão e rótulo pequenos, com apenas alguns bytes de dados persistentes, são adequados para uso no ambiente da Internet e funcionam bem dentro dos navegadores.

  • Considere que o progresso é comunicado ao contêiner.

    Notifique o contêiner do progresso no download assíncrono, incluindo quando o usuário pode começar a interagir com uma página e quando o download está concluído. O contêiner pode exibir o progresso (como a porcentagem de conclusão) para o usuário.

  • Considere como os controles são registrados no computador cliente.

Criando um controle ActiveX

Ao criar um controle usando o Assistente de Aplicativo, você pode optar por habilitar o suporte para monikers assíncronos, bem como outras otimizações. Para adicionar suporte para baixar propriedades de controle de maneira assíncrona, siga estas etapas:

Para criar o projeto usando o Assistente de Controle ActiveX do MFC

  1. Clique em Novo no menu Arquivo.

  2. Selecione o Assistente de Controle ActiveX do MFC nos projetos do Visual Studio C++ e nomeie seu projeto.

  3. Na página Configurações de Controle, selecione Carrega propriedades de modo assíncrono. Selecionar essa opção configura a propriedade de estado pronto e o evento alterado de estado pronto para você.

    Também é possível selecionar outras otimizações, como a Ativação sem janelas, que é descrita em Controles ActiveX: otimização.

  4. Selecione Concluir para criar o projeto.

Para criar uma classe derivada de CDataPathProperty

  1. Crie uma classe derivada de CDataPathProperty.

  2. Em cada um dos arquivos de origem que incluem o arquivo de cabeçalho do controle, adicione o arquivo de cabeçalho para essa classe antes dele.

  3. Nessa classe, substitua OnDataAvailable. Essa função é chamada sempre que dados estão disponíveis para exibição. À medida que os dados ficam disponíveis, você pode lidar com eles da maneira que quiser, por exemplo, renderizando-os progressivamente.

    O trecho de código abaixo é um exemplo simples de como exibir dados progressivamente em um controle de edição. Observe o uso do sinalizador BSCF_FIRSTDATANOTIFICATION para limpar o controle de edição.

    void CMyDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
    {
       CListCtrl list_ctrl;
       CEdit *edit = list_ctrl.GetEditControl();
       if ((bscfFlag & BSCF_FIRSTDATANOTIFICATION) && edit->m_hWnd)
       {
          edit->SetSel(0, -1);
          edit->Clear();
       }
    
       if (dwSize > 0)
       {
          CString string;
          LPTSTR str = string.GetBuffer(dwSize);
          UINT nBytesRead = Read(str, dwSize);
          if (nBytesRead > 0)
          {
             string.ReleaseBuffer(nBytesRead);
             edit->SetSel(-1, -1);
             edit->ReplaceSel(string);
          }
       }
    }
    

    Observe que você precisa incluir AFXCMN.H para usar a classe CListCtrl.

  4. Quando o estado geral do controle for alterado (por exemplo, de carregando para inicializado ou interativo para o usuário), chame COleControl::InternalSetReadyState. Se o controle tiver apenas uma propriedade de caminho de dados, você poderá adicionar código em BSCF_LASTDATANOTIFICATION para notificar o contêiner de que o download está concluído. Por exemplo:

    if (bscfFlag & BSCF_LASTDATANOTIFICATION)
    {
       GetControl()->InternalSetReadyState(READYSTATE_COMPLETE);
    }
    
  5. Substitua OnProgress. Em OnProgress, você recebe um número mostrando o intervalo máximo e um número mostrando o quanto o download avançou até o momento. Você pode usar esses números para exibir o status, como a porcentagem de conclusão, para o usuário.

O próximo procedimento adiciona uma propriedade ao controle para usar a classe derivada.

Para adicionar uma propriedade

  1. No Modo de Exibição de Classe, clique com o botão direito do mouse na interface abaixo do nó da biblioteca e selecione Adicionar e Adicionar Propriedade. Isso iniciará o Assistente para Adicionar Propriedade.

  2. No Assistente para Adicionar Propriedade, selecione o botão de opção Definir/Obter Métodos, digite o Nome da Propriedade, por exemplo, EditControlText, e selecione BSTR como o Tipo de propriedade.

  3. Clique em Concluir.

  4. Declare uma variável de membro da classe derivada de CDataPathProperty para sua classe de controle ActiveX.

    CMyDataPathProperty EditControlText;
    
  5. Implemente os métodos Get/Set. Para Get, retorne a cadeia de caracteres. Para Set, carregue a propriedade e chame SetModifiedFlag.

    BSTR CMFCActiveXControlCtrl::GetEditControlText(void)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       CString strResult;
       strResult = EditControlText.GetPath();
       return strResult.AllocSysString();
    }
    
    void CMFCActiveXControlCtrl::SetEditControlText(LPCTSTR newVal)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       Load(newVal, EditControlText);
       SetModifiedFlag();
    }
    
  6. Em DoPropExchange, adicione a seguinte linha:

    PX_DataPath(pPX, _T("DataPath"), EditControlText);
    
  7. Substitua ResetData para notificar a propriedade para redefinir o respectivo controle adicionando esta linha:

    EditControlText.ResetData();
    

Decidindo entre derivar de CDataPathProperty ou CCachedDataPathProperty

O exemplo anterior descreve as etapas para derivar a propriedade do controle de CDataPathProperty. Essa é uma boa opção quando você está baixando dados em tempo real que mudam com frequência e você não precisa manter todos os dados, apenas o valor atual. Um exemplo é um controle de ações.

Você também pode derivar de CCachedDataPathProperty. Nesse caso, os dados baixados são armazenados em cache em um arquivo de memória. Essa é uma boa opção quando você precisa manter todos os dados baixados, por exemplo, um controle que renderiza progressivamente um bitmap. Nesse caso, a classe tem uma variável de membro contendo seus dados:

CMemFile m_Cache;

Na classe do controle ActiveX, você pode usar esse arquivo mapeado da memória em OnDraw para exibir os dados. Na classe derivada de CCachedDataPathProperty do controle ActiveX, substitua a função membro OnDataAvailable e invalide o controle depois de chamar a implementação da classe base.

void CMyCachedDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
{
   CCachedDataPathProperty::OnDataAvailable(dwSize, bscfFlag);
   GetControl()->InvalidateControl();
}

Baixando dados de maneira assíncrona usando controles ActiveX

O download de dados em uma rede deve ser feito de maneira assíncrona. A vantagem de fazer isso é que, se uma grande quantidade de dados for transferida ou se a conexão estiver lenta, o processo de download não bloqueará outros processos no cliente.

Monikers assíncronos fornecem uma maneira de baixar dados de maneira assíncrona em uma rede. Uma operação de leitura em um moniker assíncrono retorna imediatamente, mesmo que a operação não tenha sido concluída.

Por exemplo, se apenas 10 bytes estiverem disponíveis e a leitura for chamada de maneira assíncrona em um arquivo de 1K, a leitura não será bloqueada, mas retornará com os 10 bytes disponíveis no momento.

Você implementa monikers assíncronos usando a classe CAsyncMonikerFile. No entanto, os controles ActiveX podem usar a classe CDataPathProperty, que é derivada de CAsyncMonikerFile, para ajudar a implementar propriedades de controle assíncronas.

Exibindo um controle em uma página da Web

Aqui, temos um exemplo de marca de objeto e atributos para inserir um controle em uma página da Web.

<OBJECT
  CLASSID="clsid:FC25B780-75BE-11CF-8B01-444553540000"
  CODEBASE="/ie/download/activex/iechart.ocx"
  ID=chart1
  WIDTH=400
  HEIGHT=200
  ALIGN=center
  HSPACE=0
  VSPACE=0>
  <PARAM NAME="BackColor" value="#ffffff"/>
  <PARAM NAME="ForeColor" value="#0000ff"/>
  <PARAM NAME="url" VALUE="/ie/controls/chart/mychart.txt"/>
</OBJECT>

Atualizando um controle OLE existente para usar novos recursos de controle ActiveX

Se o controle OLE foi criado com uma versão do Visual C++ anterior à 4.2, há etapas que você pode seguir para aprimorar seu desempenho e sua funcionalidade. Para ver uma discussão detalhada sobre essas alterações, consulte Controles ActiveX: otimização.

Se você estiver adicionando suporte de propriedade assíncrona a um controle existente, precisará adicionar a propriedade de estado pronto e o evento ReadyStateChange por conta própria. No construtor do controle, adicione:

m_lReadyState = READYSTATE_LOADING;

Você atualizará o estado pronto à medida que o código for baixado chamando COleControl::InternalSetReadyState. Um lugar onde você pode chamar InternalSetReadyState é da substituição OnProgress da classe derivada de CDataPathProperty.

Confira também

Tarefas de programação da Internet no MFC
Noções básicas de programação da Internet no MFC