Intervalos
Um intervalo é delimitado por duas âncoras, uma âncora inicial e uma âncora final. Existe uma âncora em um slot imaginário entre dois caracteres. A âncora inicial está relacionada ao texto que segue a âncora e a âncora final está relacionada ao texto que precede a âncora. As âncoras inicial e final podem existir no mesmo local. Nesse caso, o intervalo tem comprimento zero.
Por exemplo, comece com o seguinte texto:
This is text.
Agora, aplique um intervalo a esse texto com as âncoras inicial e final na posição 0. Ele é representado visualmente como:
<anchor></anchor>This is text.
As âncoras não ocuparão espaço dentro do próprio texto. Esse é um intervalo de comprimento zero e seu texto está vazio.
Agora, mude a âncora final +3 posições. Ele é representado visualmente como:
<anchor>Thi</anchor>s is text.
A âncora inicial é posicionada pouco antes do caractere na posição 0 e a âncora final é posicionada logo após o caractere na posição 3 porque a âncora final foi movida para os 3 lugares à direita. O intervalo de texto agora é "Thi".
Além disso, a âncora inicial não pode ser feita para seguir a âncora final e a âncora final não pode ser feita para preceder a âncora inicial.
Cada âncora tem uma configuração de gravidade que determina como a âncora responde quando o texto é inserido no fluxo de texto na posição da âncora. Quando uma inserção é feita na posição de uma âncora, um ajuste deve ser feito na posição da âncora. A gravidade determina como esse ajuste de posição de âncora é feito.
Por exemplo:
It is <anchor></anchor>cold today.
Se a palavra "very" for inserida na posição do intervalo, a âncora inicial poderá ser posicionada antes ou depois da palavra inserida:
It is <anchor>very </anchor>cold today.
- Ou -
It is very <anchor></anchor>cold today.
A gravidade da âncora especifica como a âncora é reposicionada quando uma inserção é feita em sua posição. A gravidade pode ser para trás ou para frente.
Se a âncora tiver gravidade para trás, a âncora se moverá para trás, em relação ao ponto de inserção, na inserção para que o texto inserido siga a âncora:
It is <anchor>very </anchor>cold today.
Se a âncora tiver gravidade de avanço, a âncora avançará (em relação ao ponto de inserção) na inserção para que o texto inserido preceda a âncora:
It is very <anchor></anchor>cold today.
Há duas maneiras de fazer uma "cópia" de um objeto de intervalo. A primeira é fazer um clone do intervalo usando ITfRange::Clone. A segunda é fazer um backup do intervalo usando ITfContext::CreateRangeBackup.
Um clone é uma cópia de um intervalo que não inclui dados estáticos. As âncoras do intervalo são copiadas, mas o clone ainda abrange um intervalo de texto dentro do contexto. Um clone é um objeto de intervalo em todos os aspectos. Isso significa que o texto e as propriedades de um intervalo clonado são dinâmicos e serão alterados se o texto e/ou as propriedades do intervalo coberto pelo clone forem alterados.
Um backup armazena o texto e as propriedades de um intervalo no momento em que o backup é feito como dados estáticos. Um backup também clona o intervalo original para que as alterações no tamanho e na posição do intervalo original possam ser rastreadas. Isso significa que o texto e as propriedades de um intervalo de backup são estáticos e não são alterados se o texto e/ou as propriedades do intervalo coberto pelo backup forem alterados.
Por exemplo, o seguinte intervalo (pRange) dentro do contexto:
"This is some <pRange>text</pRange>."
Agora, faça um clone e um backup desse intervalo:
ITfRange *pClone;
ITfRangeBackup *pBackup;
pRange->Clone(&pClone);
pContext->CreateRangeBackup(ec, pRange, &pBackup);
Agora, os objetos contêm o seguinte:
pRange = "text"
pClone = "text"
pBackup = "text"
Agora, altere o texto de pRange:
WCHAR wsz[] = L"other words";
pRange->SetText(ec, 0, wsz, lstrlenW(wsz));
Agora, os objetos contêm o seguinte:
Context = "This is some other words."
pRange = "other words"
pClone = "other words"
pBackup = "text"
A configuração do texto fez com que o texto dentro do contexto mudasse. Também fez com que a âncora final de pRange e pClone fosse alterada. O pClone agora contém "outras palavras" porque o texto foi alterado dentro do intervalo e essas alterações são controladas por todos os intervalos. Quando o texto coberto por pRange e pClone foi alterado, o texto de pClone também foi alterado.
O texto em pBackup não foi alterado do pRange original porque os dados (texto e propriedades) no backup não estão relacionados ao contexto e são armazenados separadamente. O clone contido no backup realmente é alterado, mas os dados são estáticos.
Ao restaurar um backup, o backup pode ser aplicado ao clone dentro do backup ou a um intervalo totalmente diferente. Para aplicar o backup ao clone dentro do backup, passe NULL para ITfRangeBackup::Restore , conforme mostrado no exemplo de código a seguir:
pBackup->Restore(ec, NULL);
Agora, os objetos contêm o seguinte:
Context = "This is some text."
pRange = "text"
pClone = "text"
pBackup = "text"
Para restaurar o backup para um intervalo diferente, passe um ponteiro para o objeto range ao chamar ITfRangeBackup::Restore. O texto e as propriedades de backup serão aplicados ao novo intervalo. Por exemplo, usando o exemplo acima antes da chamada de Restauração , o pRange será modificado para demonstrar isso:
LONG lShifted;
pRange->ShiftEnd(ec, -2, &lShifted, NULL);
Agora, os objetos contêm o seguinte:
Context = "This is some other words."
pRange = "other wor"
pClone = "other words"
pBackup = "text"
Quando a âncora final do pRange foi deslocada para os dois lugares à esquerda, a âncora final do pClone não foi alterada.
Agora, restaure o backup usando pRange com o seguinte exemplo de código:
pBackup->Restore(ec, pRange);
Agora, os objetos contêm o seguinte:
Context = "This is some textds."
pRange = "text"
pClone = "textds"
pBackup = "text"
O texto coberto por pRange foi substituído por "text", uma parte do texto coberto por pClone foi alterada e as alterações de pBackup para corresponder ao pRange.