Поделиться через


Диапазоны

Привязки

Диапазон разделяется двумя привязками: начальной и конечной привязкой. Привязка существует в воображаемом слоте между двумя символами. Начальная привязка связана с текстом, который следует за привязкой, а концевая привязка — с текстом, предшествующим привязке. Начальные и конечные привязки могут находиться в одном расположении. В этом случае диапазон имеет нулевую длину.

Например, начните со следующего текста:

This is text.

Теперь примените диапазон к этому тексту с начальными и конечными привязками в позиции 0. Он визуально представлен следующим образом:

<anchor></anchor>This is text.

Привязки не занимают места в самом тексте. Это диапазон нулевой длины, и его текст пуст.

Теперь сместите концевую привязку на 3 позиции. Он визуально представлен следующим образом:

<anchor>Thi</anchor>s is text.

Начальная привязка располагается непосредственно перед символом в позиции 0, а концевая привязка — сразу после символа в позиции 3, так как концевая привязка перемещается в нужные 3 места. Теперь диапазон текста — "Thi".

Кроме того, начальную привязку нельзя сделать, чтобы следовать за конечной привязкой, а конечную привязку нельзя сделать перед начальной привязкой.

Привязка гравитации

Каждая привязка имеет значение силы тяжести , определяющее, как привязка реагирует на вставку текста в текстовый поток в позиции привязки. Когда вставка выполняется в позиции привязки, необходимо внести корректировку в положение привязки. Сила тяжести определяет, как выполняется корректировка положения привязки.

Пример:

It is <anchor></anchor>cold today.

Если слово "very" вставляется в позицию диапазона, начальную привязку можно разместить до или после вставленного слова:

It is <anchor>very </anchor>cold today.

-или-

It is very <anchor></anchor>cold today.

Гравитация привязки указывает, как привязка перемещается при вставке в ее положение. Сила тяжести может быть как назад , так и вперед.

Если привязка имеет обратную гравитацию, привязка перемещается назад относительно точки вставки при вставке, так что вставленный текст следует за привязкой:

It is <anchor>very </anchor>cold today.

Если привязка имеет силу вперед, привязка перемещается вперед (относительно точки вставки) при вставке, чтобы вставленный текст предшествовал привязке:

It is very <anchor></anchor>cold today.

Клоны и резервные копии

Существует два способа создания "копии" объекта диапазона. Первый — создать клон диапазона с помощью ITfRange::Clone. Второй — создать резервную копию диапазона с помощью ITfContext::CreateRangeBackup.

Клон — это копия диапазона, не включающая статические данные. Привязки диапазона копируются, но клон по-прежнему охватывает диапазон текста в контексте. Клон — это объект диапазона во всех отношениях. Это означает, что текст и свойства клонированного диапазона являются динамическими и будут изменяться при изменении текста и (или) свойств диапазона, охватываемого клоном.

Резервная копия хранит текст и свойства диапазона на момент создания резервной копии в виде статических данных. Резервная копия также клонирует исходный диапазон, чтобы можно было отслеживать изменения размера и положения исходного диапазона. Это означает, что текст и свойства для резервного копирования диапазона являются статическими и не изменяются при изменении текста и (или) свойств диапазона, охватываемого резервной копией.

Например, следующий диапазон (pRange) в контексте:

"This is some <pRange>text</pRange>."

Теперь создайте клон и резервную копию этого диапазона:

ITfRange *pClone;
ITfRangeBackup *pBackup;

pRange->Clone(&pClone);
pContext->CreateRangeBackup(ec, pRange, &pBackup);

Теперь объекты содержат следующее:

pRange  = "text"
pClone  = "text"
pBackup = "text"

Теперь измените текст pRange:

WCHAR wsz[] = L"other words";
pRange->SetText(ec, 0, wsz, lstrlenW(wsz));

Теперь объекты содержат следующее:

Context = "This is some other words."
pRange  = "other words"
pClone  = "other words"
pBackup = "text"

Установка текста привела к изменению текста в контексте. Это также привело к изменению конечной привязки pRange и pClone. PClone теперь содержит "другие слова", так как текст изменился в диапазоне, и эти изменения отслеживаются всеми диапазонами. При изменении текста, охватываемого как pRange, так и pClone, изменился и текст pClone.

Текст в pBackup не изменился по сравнению с исходным pRange, так как данные (текст и свойства) в резервной копии не связаны с контекстом и хранятся отдельно. Клон, содержащийся в резервной копии, фактически меняется, но данные являются статическими.

При восстановлении резервной копии ее можно применить к клону в резервной копии или к другому диапазону. Чтобы применить резервную копию к клону в резервной копии, передайте значение NULLв ITfRangeBackup::Restore , как показано в следующем примере кода:

pBackup->Restore(ec, NULL);

Теперь объекты содержат следующее:

Context = "This is some text."
pRange  = "text"
pClone  = "text"
pBackup = "text"

Чтобы восстановить резервную копию в другой диапазон, передайте указатель на объект диапазона при вызове ITfRangeBackup::Restore. Текст и свойства резервной копии будут применены к новому диапазону. Например, используя приведенный выше пример перед вызовом Restore , pRange будет изменен, чтобы продемонстрировать следующее:

LONG lShifted;
pRange->ShiftEnd(ec, -2, &lShifted, NULL);

Теперь объекты содержат следующее:

Context = "This is some other words."
pRange  = "other wor"
pClone  = "other words"
pBackup = "text"

Когда концевая привязка pRange была смещена влево в два места, концевая привязка pClone не изменилась.

Теперь восстановите резервную копию с помощью pRange в следующем примере кода:

pBackup->Restore(ec, pRange);

Теперь объекты содержат следующее:

Context = "This is some textds."
pRange  = "text"
pClone  = "textds"
pBackup = "text"

Текст, охватываемый pRange, был заменен на "text", часть текста, покрываемого pClone, изменилась, а pBackup изменится в соответствии с pRange.