Unicode и буфер обмена

Обсуждение программ nnCron и nnCron LITE

OFF

Postby noob2k6 » Sat, 27 Jun 2009, 11:56

"Мигрени не будет, если отрубить голову" (с)
Извиняюсь за оффтопик :)

Сейчас попробовал применить наскоро переделанный пример из Справки к AutoHotKey: "WatchClipboard.ahk"
Code: Select all
#Persistent
return

OnClipboardChange:
;ToolTip Clipboard data type: %A_EventInfo%
ToolTip %clipboard%
Sleep 1000
ToolTip  ; Turn off the tip.
return

После этого сразу же перестал работать мой nnCron-скрипт - кстати, так и не заработал, пока я не догадался рестартовать nnCron. В общем, в топку AutoHotKey с его %clipboard%, лучше уж буду на вопросительные знаки изредка смотреть :D
noob2k6
 
Posts: 123
Joined: Thu, 01 Jun 2006, 06:30

OFF continued

Postby noob2k6 » Sun, 28 Jun 2009, 08:48

Пожалуй, я слишком резко - и совершенно несправедливо - отозвался об AutoHotkey. Неча на зеркало пенять, коли драйвер ruki.sys с кучей багов ;)

В общем, покопался в его Справке и нашел интересную функцию %ClipboardAll%, позволяющую, к примеру, скидывать "сырое" содержимое буфера обмена в какой-нибудь файл для вдумчивого изучения:
LogClipboardAll.ahk
Code: Select all
OnClipboardChange:
FileDelete C:\temp\Clipboard.clp
FileAppend, %ClipboardAll%, C:\temp\Clipboard.clp

Сегодня скачал сырцы AutoHotkey (на C++, в котором я разбираюсь еще хуже, чем в Форте), поищу там этот самый %ClipboardAll% :)
noob2k6
 
Posts: 123
Joined: Thu, 01 Jun 2006, 06:30

Re: Unicode и буфер обмена

Postby noob2k6 » Sun, 28 Jun 2009, 10:44

Предварительное решение своей проблемы всё же решил поискать в исходниках nnCron:
Code: Select all
<%
   WINAPI: GetClipboardData USER32.DLL
   WINAPI: OpenClipboard USER32.DLL
   WINAPI: CloseClipboard USER32.DLL

    1 CONSTANT CF_TEXT
   13 CONSTANT CF_UNICODETEXT

   CREATE CB-BUF-X 2048 ALLOT
   : CB-GET-X ( x -- addr u )
      ( x ) GetClipboardData
      ?DUP 0=
      IF
         CB-BUF-X 0
      ELSE
         ASCIIZ>
         2DUP TYPE CR \ 2debug
         2048 MIN >R
         CB-BUF-X R@ CMOVE
         CB-BUF-X R>
      THEN
   ;
   : CB-TEXT-X ( x -- addr u )
      0 OpenClipboard
      IF
         ( x ) CB-GET-X
         CloseClipboard DROP
      ELSE
         ( x ) DROP
         CB-BUF-X 0
      THEN
   ;
%>

К примеру, копирую прямо из браузера какую-нибудь фразу на русском, а затем набираю в консоли:
Code: Select all
CF_UNICODETEXT CB-TEXT-X S" C:\temp\unicode.clp" FWRITE

Текст в файл записывается, как и предполагалось, в кодировке Unicode, но почему-то не целиком, а только первое слово, а иногда даже только первый символ (то же самое дублируется в консоли).

Параллельно при помощи скрипта AutoHotkey со словом %ClipboardAll% скидываю "сырое" содержимое буфера обмена целиком в файл, при просмотре которого ничего странного не замечаю (текст в кодировке ANSI, со служебными символами до и после собственно текста).

Интересно, можно ли это как-то пофиксить проблему в nnCron-скрипте?
noob2k6
 
Posts: 123
Joined: Thu, 01 Jun 2006, 06:30

clp-ansi и clp-unicode :-)

Postby noob2k6 » Mon, 29 Jun 2009, 14:47

Методом проб и ошибок нашел кривое, неуниверсальное и, возможно, неэффективное, но вполне рабочее решение проблемы с неправильными кодировками текста в буфере обмена:
Code: Select all
<%
   WINAPI: GetClipboardData USER32.DLL
   WINAPI: OpenClipboard USER32.DLL
   WINAPI: CloseClipboard USER32.DLL

    1 CONSTANT CF_TEXT
   13 CONSTANT CF_UNICODETEXT

   CREATE CB-BUF-X 10240 ALLOT

   : UASCIIZ>plus { wa text-len -- wa u }
      wa  text-len 0=  IF UASCIIZ> ELSE text-len THEN
   ;

   : CB-GET-UNICODE { text-len -- addr u }
      CF_UNICODETEXT GetClipboardData ?DUP 0=
      IF  CB-BUF-X 0  ELSE
         text-len UASCIIZ>plus 2048 MIN >R
         CB-BUF-X R@ CMOVE
         CB-BUF-X R>
      THEN
   ;

   : clp-unicode { \ format-num text-len  -- wa u }
      0 OpenClipboard
      IF
         CF_TEXT 0 CB-GET-NUM  2 * TO text-len DROP
         CF_UNICODETEXT text-len CB-GET-NUM
         CloseClipboard DROP
      ELSE
         DROP
         S" "
      THEN
   ;         

   : clp-ansi ( -- a u )
      clp-unicode DUP 2 / -ROT UNICODE>S ROT NIP
   ;
%>

В общем, попробую пока использовать вместо стандартного слова CLIPBOARD самопальное clp-ansi (использовать непосредственно слово clp-unicode мне пока без надобности).
Насколько я понял, при конвертации из Unicode в ANSI не произойдет (частичной) потери информации, если в текстовом буфере обмена не встретятся символы, отсутствующие в наборе ANSI.
Возможно, кто-нибудь просмотрит код и выявит ошибки, которые там наверняка имеются ;)
noob2k6
 
Posts: 123
Joined: Thu, 01 Jun 2006, 06:30

Re: Unicode и буфер обмена

Postby dothen » Wed, 20 Apr 2016, 04:29

noob2k6 wrote:Текст в файл записывается, как и предполагалось, в кодировке Unicode, но почему-то не целиком, а только первое слово, а иногда даже только первый символ (то же самое дублируется в консоли).

В UTF-16 строка завершается двумя нулями, ASCIIZ> тут не годится.

Запись и чтение файлов работает.
Code: Select all
#( task-test-WRITE-READ-UNICODE-FILE
\ Кронтаб в кодировке UTF-8
NoActive
WINAPI: MessageBoxW user32.dll
Action:
  S" société προέλευση йцукен" \ строка UTF-8 (длина сразу в байтах, в конце один нулевой байт).
  S" d:\UTF_8.txt" FWRITE
  S" d:\UTF_8.txt" FILE UTF8>UNICODE
  DROP 0 SWAP DUP 0 MessageBoxW DROP

  S" SOCIÉTÉ ΠΡΟΈΛΕΥΣΗ ЙЦУКЕН" UTF8>UNICODE 2* \ строка UNICODE (длину строки указываем в байтах).
  S" d:\UNICODE.txt" FWRITE
  S" d:\UNICODE.txt" FILE
  DROP 0 SWAP DUP 0 MessageBoxW DROP

  S" d:\UTF_8.txt" FILE UTF8>UNICODE 2*
  S" d:\UNICODE.txt" FAPPEND
  S" d:\UNICODE.txt" FILE
  DROP 0 SWAP DUP 0 MessageBoxW DROP
)#
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Previous

Return to nnCron forum (Russian)

Who is online

Users browsing this forum: No registered users and 2 guests