<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; АНК: корректная передача русского текста через буфер обмена]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=1073</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=1073&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «АНК: корректная передача русского текста через буфер обмена».]]></description>
		<lastBuildDate>Sun, 26 Jun 2016 14:41:55 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: АНК: корректная передача русского текста через буфер обмена]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=105571#p105571</link>
			<description><![CDATA[<p>Варианты вышеописанных функций для современных версий AutoHotkey. На юникодных версиях ClipPutText помещает текст в буфер обмена в формате CF_UNICODETEXT, а на ANSI-версии в формате CF_TEXT, т.е. так же, как действует команда Clipboard. Примеры вызова:<br /></p><div class="codebox"><pre><code>
ClipPutText(Text, [LocaleID])     ; альтернатива команде Clipboard = %Text%
Text := ClipGetText([CodePage])   ; альтернатива команде Text = %Clipboard%

; Если параметр LocaleID не указан, он считается равным 0x419 (Ru-Ru).
; Если не задан параметр CodePage, он считается равным 1251 (русская ANSI-кодировка).
</code></pre></div><p>Сами функции:<br /></p><div class="codebox"><pre><code>
ClipPutText(Text, uLocale = 0x419)
{
    static CF_LOCALE := 16, GMEM_MOVEABLE := 2
    TextLen := StrLen(Text)
    If (A_IsUnicode) {
        cbTextBuf := TextLen * 2 + 2
        uFormat := 13   ; CF_UNICODETEXT
    }
    Else {
        cbTextBuf := TextLen + 1
        uFormat := 1    ; CF_TEXT
    }
    hText := DllCall(&quot;GlobalAlloc&quot;, &quot;uint&quot;, GMEM_MOVEABLE, &quot;ptr&quot;, cbTextBuf, &quot;ptr&quot;)
    hLocale := DllCall(&quot;GlobalAlloc&quot;, &quot;uint&quot;, GMEM_MOVEABLE, &quot;ptr&quot;, 4, &quot;ptr&quot;)
    If (!hText || !hLocale) {
        ErrorMsg := &quot;Ошибка выделения памяти.&quot;
        Goto, Error
    }
    pText := DllCall(&quot;GlobalLock&quot;,  &quot;ptr&quot;, hText, &quot;ptr&quot;)
    pLocale := DllCall(&quot;GlobalLock&quot;, &quot;ptr&quot;, hLocale, &quot;ptr&quot;)
    StrPut(Text, pText), NumPut(uLocale, pLocale + 0, 0, &quot;uint&quot;)
    DllCall(&quot;GlobalUnlock&quot;, &quot;ptr&quot;, hText), DllCall(&quot;GlobalUnlock&quot;, &quot;ptr&quot;, hLocale)
    Opened := DllCall(&quot;OpenClipboard&quot;, &quot;ptr&quot;, 0)
    If (!Opened) {
        ErrorMsg := &quot;Не удалось открыть буфер обмена.&quot;
        Goto, Error
    }
    If !DllCall(&quot;EmptyClipboard&quot;) {
        ErrorMsg := &quot;Не удалось очистить буфер обмена.&quot;
        Goto, Error
    }
    If (!DllCall(&quot;SetClipboardData&quot;, &quot;uint&quot;, uFormat, &quot;ptr&quot;, hText, &quot;ptr&quot;)
    || !DllCall(&quot;SetClipboardData&quot;, &quot;uint&quot;, CF_LOCALE, &quot;ptr&quot;, hLocale, &quot;ptr&quot;)) {
        ErrorMsg := &quot;Ошибка при записи в буфер обмена.&quot;
        Goto, Error 
    }
    DllCall(&quot;CloseClipboard&quot;)
    Return True
Error:
    If Opened
        DllCall(&quot;CloseClipboard&quot;)
    If hText
        DllCall(&quot;GlobalFree&quot;, &quot;ptr&quot;, hText)
    If hLocale
        DllCall(&quot;GlobalFree&quot;, &quot;ptr&quot;, hLocale)
    MsgBox,, %A_ThisFunc%, %ErrorMsg%
    Return False
}

ClipGetText(uCodePage = 1251)
{
    static CF_TEXT := 1, CF_UNICODETEXT := 13
    uFormat := 0
    If !DllCall(&quot;OpenClipboard&quot;, &quot;ptr&quot;, 0) {
        MsgBox,, %A_ThisFunc%, Не удалось открыть буфер обмена.
        Return False
    }
    Loop
    {
        uFormat := DllCall(&quot;EnumClipboardFormats&quot;, &quot;uint&quot;, uFormat)
        If (uFormat = 0 || uFormat = CF_UNICODETEXT || uFormat = CF_TEXT)
            Break
    }
    If (uFormat = 0) {
        DllCall(&quot;CloseClipboard&quot;)
        MsgBox,, %A_ThisFunc%, Нет текста в буфере обмена.
        Return False
    }
    hText := DllCall(&quot;GetClipboardData&quot;, &quot;uint&quot;, uFormat, &quot;ptr&quot;)
    pText := DllCall(&quot;GlobalLock&quot;, &quot;ptr&quot;, hText, &quot;ptr&quot;)
    If (A_IsUnicode) {
        If (uFormat = CF_UNICODETEXT)
            Text := StrGet(pText)
        Else {
            cbText := DllCall(&quot;lstrlenA&quot;, &quot;ptr&quot;, pText) + 1
            cchText := DllCall(&quot;MultiByteToWideChar&quot;, &quot;uint&quot;, uCodePage, &quot;int&quot;, 0
                        , &quot;ptr&quot;, pText, &quot;uint&quot;, cbText, &quot;ptr&quot;, 0, &quot;uint&quot;, 0)
            VarSetCapacity(Text, cchText * 2)
            DllCall(&quot;MultiByteToWideChar&quot;, &quot;uint&quot;, uCodePage, &quot;int&quot;, 0
                        , &quot;ptr&quot;, pText, &quot;uint&quot;, cbText, &quot;ptr&quot;, &amp;Text, &quot;uint&quot;, cchText)
            VarSetCapacity(Text, -1)
        }
    }
    Else {
        If (uFormat = CF_TEXT)
            Text := StrGet(pText)
        Else {
            cchText := DllCall(&quot;lstrlenW&quot;, &quot;ptr&quot;, pText) + 1
            cbText := DllCall(&quot;WideCharToMultiByte&quot;, &quot;uint&quot;, uCodePage, &quot;int&quot;, 0
                        , &quot;ptr&quot;, pText, &quot;uint&quot;, cchText, &quot;ptr&quot;, 0, &quot;uint&quot;, 0, &quot;ptr&quot;, 0, &quot;ptr&quot;, 0)
            VarSetCapacity(Text, cbText)
            DllCall(&quot;WideCharToMultiByte&quot;, &quot;uint&quot;, uCodePage, &quot;int&quot;, 0
                        , &quot;ptr&quot;, pText, &quot;uint&quot;, cchText, &quot;ptr&quot;, &amp;Text, &quot;uint&quot;, cbText, &quot;ptr&quot;, 0, &quot;ptr&quot;, 0)
            VarSetCapacity(Text, -1)
        }
    }
    DllCall(&quot;GlobalUnlock&quot;, &quot;ptr&quot;, hText)
    DllCall(&quot;CloseClipboard&quot;)
    Return Text
}
</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Sun, 26 Jun 2016 14:41:55 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=105571#p105571</guid>
		</item>
		<item>
			<title><![CDATA[Re: АНК: корректная передача русского текста через буфер обмена]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=29300#p29300</link>
			<description><![CDATA[<p>Поправил вызовы функций из msvcrt.dll, обозначив их <a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%88%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0">соглашение вызова</a> (cdecl). Работало и без этого, поскольку AutoHotkey всё равно сам восстанавливает стек после вызова DLL-функции. Но всё-таки в ErrorLevel он сигнализировал о замеченном непорядке.</p><p>Также добавил в ClipGetText, в блок после If(Format=0), закрытие буфера обмена — DllCall(&quot;CloseClipboard&quot;). Отсутствие этого приводило к сбою — например, при последующей попытке записи в буфер через команду вроде такой:<br /></p><div class="codebox"><pre><code>Clipboard := &quot;Hello&quot;</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Fri, 16 Oct 2009 07:12:00 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=29300#p29300</guid>
		</item>
		<item>
			<title><![CDATA[Re: АНК: корректная передача русского текста через буфер обмена]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=8516#p8516</link>
			<description><![CDATA[<p>Присмотримся ко второму фигуранту в деле - переменной ClipboardAll.</p><p>Эта переменная предназначена для сохранения всего содержимого буфера обмена в переменную или файл, а впоследствии, при необходимости, восстановления этого содержимого в буфере. Таким образом можно временно использовать буфер для чего-то другого, а потом вернуть к прежнему состоянию.</p><p>Вот простой код сохранения и восстановления:<br /></p><div class="codebox"><pre><code>F11::
  Clip:=ClipboardAll ; Читаем всё в переменную.
  Clipboard:=Clip    ; Пишем всё обратно в буфер.
Return</code></pre></div><p>По идее он не должен повлечь за собой никаких сюрпризов - что было, то и стало. Проведём эксперимент. Открываю в Avant Browser страничку с русским текстом, хотя бы эту самую. Переключаю окно на английский, копирую строчку в буфер обмена. Вставляю в Блокноте:<br /></p><div class="quotebox"><blockquote><p>Встроенная переменная Clipboard - удобная вещь</p></blockquote></div><p>Вставилось нормально, несмотря на англоязычную локаль, поскольку CF_UNICODETEXT, находящийся в буфере, помещён туда самим Avant Browser&#039;ом и закодирован им корректно по таблице 1251. Перекодировка от системы не требуется.</p><p>Теперь запускаю скрипт, нажимаю F11, снова вставляю в Блокноте:<br /></p><div class="quotebox"><blockquote><p>Âñòðîåííàÿ ïåðåìåííàÿ Clipboard - óäîáíàÿ âåùü</p></blockquote></div><p>Что за чертовщина? В буфере явно уже не то, что было, хотя, казалось бы, должно быть всё то же.</p><p>Копируем заново и смотрим в буфер обмена. К сожалению, программа InsideClipboard в данном случае не годится, т.к. не показывает форматы в том порядке, как они лежат в буфере, а сортирует их по алфавиту, размеру и т.п. Я использовал самописную функцию. Вот что видим:<br /></p><div class="quotebox"><blockquote><p>DataObject<br />CF_TEXT<br />CF_UNICODETEXT<br />HTML Format<br />Rich Text Format<br />Ole Private Data<br />CF_LOCALE<br />CF_OEMTEXT</p></blockquote></div><p>Нажимаем F11 и повторяем просмотр:<br /></p><div class="quotebox"><blockquote><p>DataObject<br />CF_TEXT<br />HTML Format<br />Rich Text Format<br />Ole Private Data<br />CF_LOCALE<br />CF_OEMTEXT<br />CF_UNICODETEXT</p></blockquote></div><p>Ну вот, CF_UNICODETEXT уехал почему-то в самый низ, что бы это значило? Я не встречал пока прямых заявлений на этот счёт, но из своих экспериментов сделал вывод, что текстовые форматы, перечисляемые до CF_LOCALE, помещены в буфер обмена приложением, а те, что после, доступны как результат перекодировки системой. Таким образом, CF_UNICODETEXT, закодированный Avant Browser&#039;ом, из буфера исчез и теперь, если будет затребован текст в Юникоде, произойдёт перекодировка с неверной кодовой страницей, в соответствии с локалью.</p><p>Дальнейшие опыты показали, что если поместить форматы в другом порядке, чтобы сначала шёл CF_UNICODETEXT, а потом CF_TEXT, то отброшен будет CF_TEXT. Таким образом, AutoHotkey сохраняет в ClipboardAll только самый первый из найденных в буфере обмена форматов простого текста (CF_TEXT, CF_UNICODETEXT, CF_OEMTEXT), а остальные игнорирует. Так что, строго говоря, ClipboardAll - не совсем All. Возможно, это сделано для экономии объёма памяти под переменную и места под файл.</p><p>Не в целях саморекламы, но справедливости ради замечу, что ClipGetText() от этого не пострадает, т.к. также работает только с первым найденным форматом, а он-то всегда сохраняется как был изначально.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Thu, 31 Jan 2008 07:28:31 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=8516#p8516</guid>
		</item>
		<item>
			<title><![CDATA[Re: АНК: корректная передача русского текста через буфер обмена]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=8249#p8249</link>
			<description><![CDATA[<p>Подправил ClipPutText, чтобы при невозможности открыть буфер память освобождалась. Пока ещё никогда с таким случаем не сталкивался, но мало ли. Получается утечка памяти. В случае успеха, освобождение памяти после записи в буфер обмена не нужно, т.к. она поступает в ведение операционной системы, которая дальше сама о ней позаботится.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Thu, 24 Jan 2008 05:07:40 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=8249#p8249</guid>
		</item>
		<item>
			<title><![CDATA[АНК: корректная передача русского текста через буфер обмена]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=8215#p8215</link>
			<description><![CDATA[<p><em><span style="color: green">Примечание: варианты описанных здесь функций для современных версий AutoHotkey см. в</span> <a href="http://forum.script-coding.com/viewtopic.php?pid=105571#p105571">посте №5</a>. <span style="color: green">В первом посте вариант для AutoHotkey Basic.</span></em></p><p>Встроенная переменная Clipboard - удобная вещь, сильно упрощающая работу с буфером обмена, но если объектом является русский текст, иногда в результате получаем нечто странное. Слово <strong>привет</strong> превращается либо в <strong>ïðèâåò</strong>, либо в <strong>??????</strong>.</p><p>Чтобы понять, что тут происходит, - немного теории. В буфере обмена могут одновременно находиться разные данные в разных форматах. Скопируем текст в буфер обмена и заглянем туда с помощью, например, программы <a href="http://www.nirsoft.net/utils/inside_clipboard.html">InsideClipboard</a> (спасибо <strong>alexii</strong> за ссылку). Получим список наподобие этого:<br /></p><div class="quotebox"><blockquote><p>CF_TEXT<br />CF_LOCALE<br />CF_OEMTEXT<br />CF_UNICODETEXT</p></blockquote></div><p>Строки 1, 3 и 4 соответствуют скопированному нами тексту в трёх разных форматах, CF_LOCALE - это число, обозначающее локаль ввода, т.е., проще говоря, язык текста. В обычной ситуации двух языков Ru/En это число будет либо 0x409 (En), либо 0x419 (Ru). Текст в буфер обмена помещает не операционная система, а приложение. При этом оно может указать и локаль, если же оно этого не сделает, она будет соответствовать языку окна, из которого взят текст.</p><p>Если уж быть совсем точным, локаль ввода - это атрибут не окна, а потока (thread), создавшего окно. Процесс приложения в памяти может состоять из одного или нескольких потоков, каждый поток может создать одно или несколько окон. В последнем случае, переключая язык в одном окне потока, переключим его одновременно и для всех других окон этого потока. (Тут имеются в виду не потоки в терминологии скриптов AutoHotkey, конечно.)</p><p>Приложение может поместить текст в буфер обмена в любом формате или сразу в нескольких (AutoHotkey использует CF_TEXT). Другое приложение, куда мы вставляем текст, также может запросить текст из буфера в любом формате. А если такого формата там нет? К примеру, мы скопировали в буфер текст в формате CF_TEXT, что в русской системе соответствует 8-битной кодировке Windows-1251, а приложение, куда нужно вставить, требует текст в Юникоде? В этом случае операционная система осуществляет перекодирование в CF_UNICODETEXT.</p><p>И вот здесь решающее значение имеет CF_LOCALE, т.к. именно ею определяется, какая кодовая страница будет использована при перекодировке: русская 1251 или западно-европейская 1252, соответствующая локали 0x409. В последнем случае вместо <strong>привет</strong> получим <strong>ïðèâåò</strong>.</p><p>Вышеприведённый список форматов текста пусть никого не введёт в заблуждение, это список <em><strong>доступных</strong></em> форматов, а не тех, что реально лежат в буфере. Реально часто лежит один, остальные доступны как результат перекодировки и фактически там появятся только после неё. Так что такая конвертация форматов по запросу - обычное явление.</p><p>Рассмотрим обратную ситуацию: текст помещается в буфер обмена в CF_UNICODETEXT (так делает, например, Блокнот), а запрашивается как CF_TEXT (так делает AutoHotkey). Если CF_LOCALE имеет значение 0x409 (окно Блокнота было на английском), для перекодирования используется таблица 1252. Кодам из русского диапазона Юникода там поставлен в соответствие символ <strong>?</strong>. Соответственно вместо <strong>привет</strong> получается <strong>??????</strong>.</p><p>Итак,&nbsp; корень зла в обоих случаях - западная локаль ввода у потока, помещающего текст в буфер обмена, что вызывает использование не той кодовой страницы при необходимости перекодирования текста.</p><p>От этого гораздо реже должны страдать те, у кого в системе язык ввода по умолчанию русский. Тут любой поток при запуске имеет русскую локаль, разве что язык будет намеренно переключен. Но сомневаюсь, что разного рода скриптеры и кодеры поголовно относятся к этой категории. По крайней мере для себя я нашёл русский язык по умолчанию неудобным. В результате любой скрипт AutoHotkey у меня запускается с локалью 0x409, и если я там делаю что-то вроде:<br /></p><div class="codebox"><pre><code>Clipboard=Привет, как дела?</code></pre></div><p>то результат вставки этой строки из буфера в какое-нибудь окно непредсказуем, всё зависит от того, какой формат предпочитает приложение, создавшее это окно.</p><p>Для решения проблем с неверной кодовой страницей существует способ правки реестра, который, например, предлагает и <strong>Androgen</strong> в своём фундаментальном и основополагающем исследовании <a href="http://www.script-coding.com/AutoHotkey/AhkRussian_3b.html">AutoHotkey и русский язык – дружба навеки</a>. Суть его в том, чтобы параметр 1252 указывал на файл c_1251.nls. Способ действенный, но есть и неудобства. В случае запуска скрипта на другой машине, где реестр не правлен, проблема может вылезти опять. А вы у себя уже успели от неё отвыкнуть и забыли учесть этот момент. Кроме того, страница 1252 иногда бывает полезной - например, для восстановления текста, неправильно перекодированного самим приложением и уже в таком виде помещённого им в буфер обмена. Такое иногда бывает при копировании из PDF.</p><p>Короче говоря, тем, кто предпочитает реестр не трогать, могу предложить следующие две функции:<br /></p><div class="codebox"><pre><code>ClipPutText(Text, [LocaleID])   ; альтернатива команде Clipboard=%Text%
Text:=ClipGetText([CodePage])   ; альтернатива команде Text=%Clipboard%

; Если параметр LocaleID не указан, он считается равным 0x419.
; Если не задан параметр CodePage, он считается равным 1251.</code></pre></div><p>ClipPutText помещает в буфер обмена текст в виде CF_TEXT, а также информацию о локали - по умолчанию 0x419. Теперь возможный перевод в Юникод ничем русским буквам не грозит.<br />ClipGetText просматривает форматы буфера обмена в поисках CF_TEXT или CF_UNICODETEXT и использует тот из них, который встретится первым, исходя из идеи, что первый формат помещён в буфер самим приложением, тогда как второй уже может быть результатом неправильной перекодировки. Если раньше всего найден CF_UNICODETEXT, он конвертируется в CF_TEXT с использованием указанной кодовой таблицы, по умолчанию 1251, таким образом локаль игнорируется.</p><div class="codebox"><pre><code>ClipPutText(Text, LocaleID=0x419)
{
  CF_TEXT:=1, CF_LOCALE:=16, GMEM_MOVEABLE:=2
  TextLen   :=StrLen(Text)
  HmemText  :=DllCall(&quot;GlobalAlloc&quot;, &quot;UInt&quot;, GMEM_MOVEABLE, &quot;UInt&quot;, TextLen+1)  ; Запрос перемещаемой
  HmemLocale:=DllCall(&quot;GlobalAlloc&quot;, &quot;UInt&quot;, GMEM_MOVEABLE, &quot;UInt&quot;, 4)  ; памяти, возвращаются хэндлы.
  If(!HmemText || !HmemLocale)
    Return
  PtrText   :=DllCall(&quot;GlobalLock&quot;,  &quot;UInt&quot;, HmemText)   ; Фиксация памяти, хэндлы конвертируются
  PtrLocale :=DllCall(&quot;GlobalLock&quot;,  &quot;UInt&quot;, HmemLocale) ; в указатели (адреса).
  DllCall(&quot;msvcrt\memcpy&quot;, &quot;UInt&quot;, PtrText, &quot;Str&quot;, Text, &quot;UInt&quot;, TextLen+1, &quot;Cdecl&quot;) ; Копирование текста.
  NumPut(LocaleID, PtrLocale+0)                   ; Запись идентификатора локали.
  DllCall(&quot;GlobalUnlock&quot;,     &quot;UInt&quot;, HmemText)   ; Расфиксация памяти.
  DllCall(&quot;GlobalUnlock&quot;,     &quot;UInt&quot;, HmemLocale)
  If not DllCall(&quot;OpenClipboard&quot;, &quot;UInt&quot;, 0)      ; Открытие буфера обмена.
  {
    DllCall(&quot;GlobalFree&quot;, &quot;UInt&quot;, HmemText)    ; Освобождение памяти,
    DllCall(&quot;GlobalFree&quot;, &quot;UInt&quot;, HmemLocale)  ; если открыть не удалось.
    Return
  }
  DllCall(&quot;EmptyClipboard&quot;)                     ; Очистка.
  DllCall(&quot;SetClipboardData&quot;, &quot;UInt&quot;, CF_TEXT,   &quot;UInt&quot;, HmemText)   ; Помещение данных.
  DllCall(&quot;SetClipboardData&quot;, &quot;UInt&quot;, CF_LOCALE, &quot;UInt&quot;, HmemLocale)
  DllCall(&quot;CloseClipboard&quot;)     ; Закрытие.
}


ClipGetText(CodePage=1251)
{
  CF_TEXT:=1, CF_UNICODETEXT:=13, Format:=0
  If not DllCall(&quot;OpenClipboard&quot;, &quot;UInt&quot;, 0)                 ; Открытие буфера обмена.
    Return
  Loop
  {
    Format:=DllCall(&quot;EnumClipboardFormats&quot;, &quot;UInt&quot;, Format)  ; Перебор форматов.
    If(Format=0 || Format=CF_TEXT || Format=CF_UNICODETEXT)
      Break
  }
  If(Format=0) {      ; Текста не найдено.
    DllCall(&quot;CloseClipboard&quot;)
    Return
  }
  If(Format=CF_TEXT)
  {
    HmemText:=DllCall(&quot;GetClipboardData&quot;, &quot;UInt&quot;, CF_TEXT)  ; Получение хэндла данных.
    PtrText :=DllCall(&quot;GlobalLock&quot;,       &quot;UInt&quot;, HmemText) ; Конвертация хэндла в указатель.
    TextLen :=DllCall(&quot;msvcrt\strlen&quot;,    &quot;UInt&quot;, PtrText, &quot;Cdecl&quot;)  ; Измерение длины найденного текста.
    VarSetCapacity(Text, TextLen+1)  ; Переменная под этот текст.
    DllCall(&quot;msvcrt\memcpy&quot;, &quot;Str&quot;, Text, &quot;UInt&quot;, PtrText, &quot;UInt&quot;, TextLen+1, &quot;Cdecl&quot;) ; Текст в переменную.
    DllCall(&quot;GlobalUnlock&quot;, &quot;UInt&quot;, HmemText)  ; Расфиксация памяти.
  }
  Else If(Format=CF_UNICODETEXT)
  {
    HmemTextW:=DllCall(&quot;GetClipboardData&quot;, &quot;UInt&quot;, CF_UNICODETEXT)
    PtrTextW :=DllCall(&quot;GlobalLock&quot;,       &quot;UInt&quot;, HmemTextW)
    TextLen  :=DllCall(&quot;msvcrt\wcslen&quot;,    &quot;UInt&quot;, PtrTextW, &quot;Cdecl&quot;)
    VarSetCapacity(Text, TextLen+1)
    DllCall(&quot;WideCharToMultiByte&quot;, &quot;UInt&quot;, CodePage, &quot;UInt&quot;, 0, &quot;UInt&quot;, PtrTextW 
                                 , &quot;Int&quot;, TextLen+1, &quot;Str&quot;, Text, &quot;Int&quot;, TextLen+1
                                 , &quot;UInt&quot;, 0, &quot;Int&quot;, 0)  ; Конвертация из Unicode в ANSI.
    DllCall(&quot;GlobalUnlock&quot;, &quot;UInt&quot;, HmemTextW)
  }
  DllCall(&quot;CloseClipboard&quot;)  ; Закрытие.
  Return Text
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Wed, 23 Jan 2008 09:29:31 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=8215#p8215</guid>
		</item>
	</channel>
</rss>
