Exibir cache
Um aplicativo de contêiner deve ser capaz de obter uma apresentação de um objeto com a finalidade de exibi-lo ou imprimi-lo para os usuários quando o documento está aberto, mas o aplicativo de servidor do objeto não está em execução ou não está instalado na máquina do usuário. Assumir, no entanto, que os servidores de todos os objetos que podem ser encontrados em um documento estão instalados na máquina de cada usuário e sempre podem ser executados sob demanda é irrealista. O manipulador de objetos padrão, que está disponível o tempo todo, resolve esse dilema armazenando em cache as apresentações de objetos no armazenamento do documento e manipulando essas apresentações em qualquer plataforma, independentemente da disponibilidade do servidor de objetos em qualquer instalação específica do contêiner.
Os contêineres podem manter apresentações de desenho para um ou mais dispositivos de destino específicos, além daquele necessário para manter o objeto na tela. Além disso, se você portar o objeto de uma plataforma para outra, o OLE converterá automaticamente os formatos de dados do objeto para aqueles suportados na nova plataforma. Por exemplo, se você mover um objeto do Windows para o Macintosh, OLE converterá suas apresentações de metarquivo para formatos PICT.
Para apresentar uma representação precisa de um objeto incorporado ao usuário, o aplicativo de contêiner do objeto inicia uma caixa de diálogo com o manipulador de objetos, solicitando dados e instruções de desenho. Para poder atender às solicitações do contêiner, o manipulador deve implementar as interfaces IDataObject, IViewObject2 e IOleCache.
IDataObject permite que um aplicativo de contêiner OLE obtenha dados e envie dados para seus objetos incorporados ou vinculados. Quando os dados são alterados em um objeto, essa interface fornece uma maneira para o objeto disponibilizar seus novos dados para seu contêiner e fornece ao contêiner uma maneira de atualizar os dados em sua cópia do objeto. (Para uma discussão sobre a transferência de dados em geral, consulte o Capítulo 4, Transferência de dados.)
A interface IViewObject2 é muito parecida com a interface IDataObject, exceto que ela pede a um objeto para se desenhar em um contexto de dispositivo, como uma tela, impressora ou metarquivo, em vez de mover ou copiar seus dados para a memória ou algum outro meio de transferência. O objetivo da interface é permitir que um contêiner OLE obtenha representações pictóricas alternativas de seus objetos incorporados, cujos dados ele já possui, evitando assim a sobrecarga de ter que transferir instâncias inteiramente novas dos mesmos objetos de dados simplesmente para obter novas instruções de desenho. Em vez disso, a interface IViewObject2permite que o contêiner peça a um objeto para fornecer uma representação pictórica de si mesmo desenhando em um contexto de dispositivo especificado pelo contêiner.
Ao chamar a interface IViewObject2 , um aplicativo de contêiner também pode especificar que o objeto se desenhe em um dispositivo de destino diferente daquele no qual ele realmente será renderizado. Isso permite que o contêiner, conforme necessário, gere renderizações diferentes de um único objeto. Por exemplo, o chamador pode pedir que o objeto se componha para uma impressora, mesmo que o desenho resultante seja renderizado na tela. O resultado, é claro, seria uma visualização de impressão do objeto.
A interface IViewObject2também fornece métodos que permitem que contêineres se registrem para notificações de alteração de exibição. Assim como acontece com dados e avisos OLE, uma conexão de aviso de exibição permite que um contêiner atualize suas renderizações de um objeto em sua própria conveniência, em vez de em resposta a uma chamada do objeto. Por exemplo, se uma nova versão do aplicativo de servidor de um objeto oferecesse exibições adicionais dos mesmos dados, o manipulador padrão do objeto chamaria a implementação de IAdviseSink::OnViewChange de cada contêiner para informá-los de que as novas apresentações estavam disponíveis. O contêiner recuperaria essas informações do coletor de avisos somente quando necessário.
Como os contextos de dispositivo do Windows têm significado apenas dentro de um único processo, você não pode passar ponteiros IViewObject2 através dos limites do processo. Como resultado, os servidores OLE locais e remotos não têm nenhuma necessidade de implementar a interface, o que não funcionaria corretamente, mesmo que funcionassem. Somente manipuladores de objetos e servidores em processo implementam a interface IViewObject2. OLE fornece uma implementação padrão, que você pode usar em seus próprios servidores OLE em processo e manipuladores de objeto simplesmente agregando o manipulador padrão OLE. Ou você pode escrever sua própria implementação de IViewObject2.
Um objeto implementa a interface IOleCache para permitir que o manipulador saiba quais recursos ele deve armazenar em cache. O manipulador de objetos também possui o cache e garante que ele seja mantido atualizado. À medida que o objeto incorporado entra no estado de execução, o manipulador configura conexões de consultoria apropriadas no objeto de servidor, com ele mesmo agindo como o coletor. As implementações de interface IDataObject e IViewObject2operam a partir de dados armazenados em cache no lado do cliente. A implementação do manipulador de IViewObject2é responsável por determinar quais formatos de dados armazenar em cache para atender às solicitações de desenho do cliente. A implementação do manipulador de IDataObject é responsável por obter dados em vários formatos, etc., entre a memória e a instância IStorage subjacente do objeto incorporado. Os manipuladores personalizados podem usar essas implementações agregando no manipulador padrão.
Observação
A interface IViewObject2 é uma extensão funcional simples de IViewObject e deve ser implementada em vez da última interface, que agora está obsoleta. Além de fornecer os métodos IViewObject, a interface IViewObject2 fornece um único membro adicional, GetExtent, que permite que um aplicativo contêiner obtenha o tamanho da apresentação de um objeto do cache sem primeiro precisar mover o objeto para o estado de execução com uma chamada para IOleObject::GetExtent.