Compartilhar via


Criando reconciliadores de maiúsculas e minúsculas

Um reconciliador de pasta fornece à Pasta os meios para reconciliar diferentes versões de um documento.

Sobre reconciliadores de maiúsculas e minúsculas

Um reconciliador de maiúsculas e minúsculas combina diferentes versões de entrada de um documento para produzir uma única versão de saída do documento. Talvez seja necessário criar um reconciliador de minúsculas para dar suporte ao seu tipo de documento. Essa visão geral descreve reconciliadores de pasta e explica como criá-los.

Os seguintes tópicos são abordados:

Reconciliação

Um documento é uma coleção de informações que podem ser copiadas e alteradas. Um documento terá versões diferentes se o conteúdo de pelo menos duas cópias do documento for diferente. A reconciliação produz uma única versão de um documento de duas ou mais versões iniciais. Normalmente, a versão reconciliada é uma combinação de informações das versões iniciais com as informações mais recentes ou úteis preservadas.

A reconciliação é iniciada pela Pasta quando determina que duas ou mais cópias do mesmo documento são diferentes. A pasta, que atua como iniciador nesse contexto, localiza e inicia o reconciliador de pasta associado ao tipo de documento fornecido. O reconciliador compara os documentos e determina quais partes dos documentos reter. Alguns reconciliadores podem exigir interação do usuário para concluir a reconciliação. Outras pessoas podem concluir a reconciliação sem interação do usuário. O reconciliador pode estar contido em um aplicativo ou ser uma extensão implementada como uma DLL.

Alguns reconciliadores de pasta podem criar resíduos. Um resíduo é um documento, geralmente com o mesmo tipo de arquivo que o documento inicial, que contém informações não salvas na versão mesclada. Normalmente, os resíduos são usados para dar aos autores uma maneira rápida de determinar quais informações de seu documento original não estão na versão final mesclada. Se um reconciliador der suporte a resíduos, ele criará um resíduo para cada uma das versões originais do documento. Os resíduos não são criados, a menos que o iniciador os solicite.

Alguns reconciliadores de maiúsculas e minúsculas funcionam com a Pasta para permitir que o usuário encerre a reconciliação. Esse é um recurso importante para um usuário que pode decidir que a reconciliação não deve continuar. Um reconciliador normalmente fornece um objeto de terminação quando a reconciliação requer interação do usuário e pode ser longa. Em alguns ambientes, um reconciliador pode permitir a reconciliação parcial, permitindo que um usuário suspenda temporariamente uma reconciliação e retome-a mais tarde. No entanto, a pasta não dá suporte à reconciliação parcial no momento.

Criando um reconciliador de maiúsculas e minúsculas

Você cria um reconciliador de pasta implementando as interfaces de reconciliação. No mínimo, um reconciliador implementa a interface IReconcilableObject e a interface IPersistStorage ou IPersistFile . Como iniciador, Briefcase determina quando a reconciliação é necessária e chama o método IReconcilableObject::Reconcile para iniciar a reconciliação.

Embora IReconcilableObject::Reconcile forneça um amplo conjunto de recursos de reconciliação, um reconciliador de maleta realiza apenas reconciliação mínima na maioria dos casos. Em particular, a Pasta não requer o reconciliador para dar suporte à geração de resíduos ou para dar suporte ao objeto de terminação. Além disso, o reconciliador realiza uma única reconciliação de cima para baixo e não deve retornar o valor REC_E_NOTCOMPLETE; ou seja, não deve tentar a reconciliação parcial.

A pasta fornece a interface IReconcileInitiator . O reconciliador de pasta pode usar o método IReconcileInitiator::SetAbortCallback para definir o objeto de terminação. A pasta não usa identificadores de versão e, portanto, não pode fornecer versões anteriores de um documento se um reconciliador os solicitar usando os métodos correspondentes em IReconcileInitiator.

A pasta passa para monikers de arquivo IReconcilableObject::Reconcile que representam as versões do documento a serem reconciliadas. O reconciliador de maiúsculas e minúsculas obtém acesso às versões usando o método IMoniker::BindToObject ou IMoniker::BindToStorage . Este último geralmente é mais rápido e é recomendado. O reconciliador deve liberar todos os objetos ou armazenamento aos quais ele se associa.

Quando o reconciliador de pasta usa IMoniker::BindToStorage, ele se associa ao armazenamento que é armazenamento simples (um fluxo) ou armazenamento estruturado definido por OLE. Se o reconciliador espera armazenamento simples, ele deve usar IMoniker::BindToStorage para solicitar a interface IStream . Se o reconciliador espera armazenamento estruturado, ele deve solicitar a interface IStorage . Em ambos os casos, ele deve solicitar acesso direto somente leitura (não transacionado) ao armazenamento; O acesso de leitura/gravação pode não estar disponível.

Um reconciliador de minúsculas mínimo normalmente examina diretamente o armazenamento das outras versões e lida com objetos inseridos de maneira muito primitiva, como mesclar duas versões do objeto, incluindo ambas as versões na versão de saída.

O iniciador localiza o reconciliador de pasta apropriado usando um subconjunto da lógica implementada pela função GetClassFile para determinar o tipo de um determinado arquivo e, em seguida, procura no registro a classe reconciliador associada ao tipo de arquivo fornecido. A pasta, como outros componentes do Shell, determina o tipo de um arquivo somente pela extensão de nome de arquivo. A extensão de um arquivo deve ter um tipo de arquivo registrado para a Pasta invocar um reconciliador para o arquivo. Você deve definir uma entrada do Registro do formulário a seguir ao instalar o reconciliador.

CLSID
   {the file CLSID}
      Roles
         Reconciler
            (Default) = {the reconciler-classid}

A classe deve ser de carregamento rápido, deve ser designada _MULTIPLEUSE e, a menos que os marshalers sejam fornecidos para a interface de reconciliação, deve ser um servidor em processo (contido em uma DLL) em vez de um servidor local (implementado em um arquivo .exe).

Interação do usuário na reconciliação

Um reconciliador de maiúsculas e minúsculas deve tentar realizar a reconciliação sem interação do usuário. Quanto mais automatizada a reconciliação, melhor será a percepção do usuário sobre o processo.

Em alguns casos, a intervenção do usuário pode ser valiosa. Por exemplo, um sistema de documentos pode exigir que um usuário revise as alterações antes de aceitar a versão mesclada de um documento ou pode exigir comentários do usuário explicando as alterações que foram feitas. Nesses casos, o iniciador, não o reconciliador de pasta, é responsável por consultar o usuário e executar as instruções do usuário.

Em outros casos, a intervenção do usuário pode ser necessária, por exemplo, quando duas versões foram editadas de maneiras incompatíveis. Nesses casos, o iniciador ou reconciliador de pasta deve consultar o usuário para obter instruções sobre como resolve o conflito. Em geral, nenhum iniciador pode confiar na conclusão de uma reconciliação sem esperar alguma interação do usuário. Reconciliadores, por outro lado, têm a opção de interagir com o usuário para resolve conflitos ou exigir que o iniciador faça isso.

Reconciliando objetos inseridos

Ao reconciliar um documento, o reconciliador de pasta em si pode se tornar um iniciador se descobrir um objeto inserido de um tipo que não pode reconciliar. Nesse caso, o reconciliador precisa reconciliar recursivamente cada um dos objetos inseridos e assumir todas as responsabilidades de um iniciador.

Para realizar a recursão, o reconciliador de maiúsculas e minúsculas carrega o objeto e as consultas para a interface apropriada. O manipulador do objeto deve dar suporte à interface . Se qualquer método da interface retornar o valor OLE_E_NOTRUNNING, o reconciliador deverá executar o objeto para executar a operação. Como o código para objetos inseridos nem sempre está disponível, um reconciliador deve fornecer uma solução para essa condição. Por exemplo, o reconciliador pode incluir versões antigas e novas do objeto inserido na versão reconciliada. O reconciliador não deve tentar reconciliar entre links.

O iniciador armazena as versões do documento que estão sendo mescladas. Em muitos casos, o iniciador tem acesso ao armazenamento de cada versão e salva o resultado da reconciliação usando armazenamento semelhante. Às vezes, no entanto, o iniciador pode ter um objeto na memória para o qual nenhuma versão persistente está disponível. Essa situação pode ocorrer quando um documento que contém objetos inseridos abertos deve ser reconciliado antes de ser salvo. Nesses casos, o iniciador salva o resultado da reconciliação na versão encontrada na memória.

O iniciador usa a interface IPersistStorage para associar (carregar) a versão mesclada. O iniciador usará o método IPersistStorage::Load se uma versão inicial já tiver sido criada e usar o método IPersistStorage::InitNew para a versão inicial. Quando a versão mesclada é carregada, o iniciador usa QueryInterface para recuperar o endereço da interface IReconcilableObject . Essa interface fornece ao iniciador acesso ao armazenamento dos resíduos existentes e fornece a ele uma maneira de criar armazenamento para quaisquer novos resíduos. Em seguida, o iniciador direciona a interface para realizar a reconciliação. O iniciador realmente consulta a interface IPersistFile antes de IPersistStorage. Se o reconciliador der suporte a IPersistFile, o iniciador manipulará o réplica por meio dos métodos IPersistFile em vez dos métodos IPersistStorage. Isso permite a reconciliação de arquivos que não são armazenados como documentos compostos.

Quando a reconciliação for concluída, o iniciador poderá salvar a versão mesclada usando a interface IPersistStorage ou IPersistFile . Durante a reconciliação, o reconciliador de maleta cria resíduos conforme necessário e grava seus bits persistentes no armazenamento. Se a versão mesclada for um fluxo, a interface IStorage passada para IPersistStorage::Load conterá um fluxo chamado "Contents" com seu estado de armazenamento definido como STATEBITS_FLAT. (Você pode definir os bits de estado usando o método IStorage::Stat .) Após a mesclagem, o iniciador salva a versão mesclada gravando os dados de maneira apropriada. Ele deve garantir que STATEBITS_FLAT seja definido conforme apropriado para o armazenamento.

Resíduos

O iniciador indica se deseja resíduos definindo o parâmetro pstgNewResidues como um endereço válido ao chamar o método IReconcilableObject::Reconcile . Se o reconciliador não der suporte à criação de resíduos, ele deverá retornar imediatamente o valor REC_E_NORESIDUES, a menos que o parâmetro dwFlags especifique o valor RECONCILEF_NORESIDUESOK .

O reconciliador de maleta retorna resíduos ao iniciador criando novos elementos de armazenamento e copiando-os para a matriz apontada por pstgNewResidues. Para resíduos de armazenamento estruturado, o reconciliador copia uma interface IStorage e, para resíduos de armazenamento simples, copia uma interface IStream ou IStorage com o sinalizador STATEBITS_FLAT definido. O reconciliador usa iStorage para criar o armazenamento necessário, usando IStorage::CreateStream para criar armazenamento simples para um resíduo que é um fluxo e IStorage::CreateStorage para criar armazenamento estruturado.

O iniciador prepara pstgNewResidues para que ele não contenha elementos na parte não atendida do namespace IStorage . O reconciliador de maleta coloca cada resíduo em um elemento cujo nome corresponde à ordem de sua versão inicial. Por exemplo, o primeiro resíduo está contido em "1", o segundo em "2" e assim por diante. Se o próprio objeto reconciliado produzir um resíduo, ele será encontrado no elemento chamado "0".

O reconciliador de pasta confirma cada um dos elementos recém-criados individualmente, garantindo que o iniciador tenha acesso às informações. No entanto, o reconciliador não confirma o próprio pstgNewResidues . O iniciador é responsável por confirmar isso ou de outra forma descartá-lo.

Referência do Reconciliador de Pasta

Esta seção contém informações sobre as interfaces de reconciliação. Ao tratar erros, um método pode retornar apenas os valores de erro definidos explicitamente como valores retornados possíveis. Além disso, o método deve definir todas as variáveis cujos endereços são passados como parâmetros para NULL antes de retornar do erro.

Interfaces e métodos de reconciliador de pasta