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