一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

在AHK腳本中使用Send發(fā)送中文

 jinnixue 2009-11-09

最簡單的方法其實是先把要發(fā)送的內容先保存到剪貼板中去,然后在要發(fā)送的時候“粘貼”一下(Send一個 Ctrl+V)即可。不過這樣做有一些缺點:
1、由于使用了剪貼板,用戶在 Send 的過程中將不能正常使用 Ctrl+C 和 Ctrl+V 等剪貼板相關的功能;
2、有可能會在還沒執(zhí)行完“粘貼”操作之前剪貼板的內容就被修改了,結果發(fā)送了別的內容。


當然還有別的方法,先引用一下下面的內容:

我們通過鍵盤只能夠輸入鍵盤上有的字符,其實,按住 ALT 鍵,然后在數(shù)字鍵盤上按表示要輸入字符的十進制代碼值的鍵,等完成輸入后,釋放 ALT 鍵還可以輸入鍵盤上沒有的字符呢。

如 果鍵入的第一個數(shù)字是“0”,該值將被識別為當前輸入?yún)^(qū)域設置中的代碼點或字符值。例如,在當前的輸入?yún)^(qū)域設置為“英語(美國)”時(代碼頁 1252:Windows Latin-1),按住 ALT 鍵,然后在數(shù)字鍵盤上鍵入“0163”將產生英鎊符號 £ (U+00A3)。在當前輸入?yún)^(qū)域是 "Russia" (代碼頁 1251:Windows Cyrillic),相同的鍵順序會產生西里爾大寫字母 JE (U+0408)。

而如果鍵入的第一位數(shù)是“1”到“9”的任意數(shù),該值將被識別為系統(tǒng) OEM 代碼頁中的代碼點。根據(jù)在“控制面板”的“區(qū)域選項”中所指定的 Windows 系統(tǒng)區(qū)域設置,結果各有不同。例如,如果您的系統(tǒng)區(qū)域設置是“英語(美國)”,代碼頁為 437(MS-DOS 拉丁美洲),那么只要按住 ALT 鍵,然后在數(shù)字鍵盤上鍵入“163”,就可以輸入 ú(U+00FA, 帶重音符號的小寫拉丁字母 U)。如果系統(tǒng)區(qū)域設置是“希臘語”(OEM 代碼頁 737 MS-DOS 希臘),相同序列將產生希臘語小寫字母 MU (U+03BC)。

新建一個文本文件,輸入“中文”這兩個字并保存,然后用UltraEdit等十六進制編輯器打開并用十六進制視圖顯示,可看到如下內容:

00000000h: D6 D0 CE C4                                     ; 中文

可知中文這兩個字的十六進制分別是 0xD6D0、0xCEC4(即十進制的54992、52932),那么如果要輸入“中”字,則只要按住Alt鍵,逐個輸入其十進制數(shù)字54992即可。
這樣,要實現(xiàn)自己的 Send 函數(shù)就簡單了:

AHK腳本:
; GBK是GB2312的擴展,是向下兼容的,因此GB2312中的漢字的編碼與GBK中
; 漢字的相同。另外,GBK中還包含繁體字的編碼,GBK中每個漢字仍然包含兩
; 個字節(jié),第一個字節(jié)的范圍是0x81-0xFE(即129-254),第二個字節(jié)的范圍
; 是0x40-0xFE(即64-254)。GBK中有碼位23940個,包含漢字21003個。

#NoEnv
SetKeyDelay
,
20                 
; 如因速度過快導致發(fā)送不正常請嘗試修改此行的延遲數(shù)值
SendMode InputThenPlay      
; 如因速度過快導致發(fā)送不正常請則注釋此行或改為其它模式
SetWorkingDir %A_ScriptDir%

string1 :=
"簡體中文字符發(fā)送測試"
string2 :=
"繁體中文字符發(fā)送測試"

F10
::
    Loop,
100
    {
        SendString( "Sending #" . A_Index . " " . string1
)
        Send, {Enter}
    }
Return

SendString( string
)
{
    Len := StrLen(string)  
; 得到字符串的長度,注意一個中文字符的長度是2,即占2個字節(jié)
    Keys := ""                  
; 將要發(fā)送的字符序列
    Index := 1                  
; 用于循環(huán)
    
Loop
    {
        IsUnicodeChar :=
false
        Code2 := 0                                             
; 字符2的ASCII碼
        Code1 := Asc( SubStr(string, Index, 1) )    
; 得到第一個字符的ASCII值
        if(Code1 >= 129 && Code1 <= 254 && Index < Len)   
; 判斷是否中文字符的第一個字符
        {
            Code2 := Asc( SubStr(string, Index+1, 1) )            
; 得到第二個字符的ASCII值
            if(Code2 >= 64 && Code2 <= 254)        
; 若條件成立則說明是中文字符
            {
                IsUnicodeChar :=
true
                Code1 <<= 8                                  
; 第一個字符應放到高8位上
                Code1 += Code2                              
; 第二個字符放在低8位上
            }
            ++Index
        }
        if( IsUnicodeChar
)
            Keys .= "{ASC " . Code1 .
"}"
       
else
        {
            Keys .= "{ASC 0" . Code1 . "}"                
; 如果非中文字符,則需要前綴一個0
            if( Code2 > 0
)
                Keys .= "{ASC 0" . Code2 .
"}"
        }
        ++Index
        if(Index > Len
)
            
Break
    }
    Send % Keys
}

SendByClipboard( string, BackupClipBoard = false
)
{
    if(BackupClipBoard
)
        ClipSaved :=
ClipboardAll
    ClipBoard := string
    Send ^v
    if(BackupClipBoard
)
    {
        Clipboard := ClipSaved
        ClipSaved
=
    }
}

///////////////////////////////////////////////////////////////////////////////

AU3腳本(3.2.4.0 之后的版本)
由于AutoIt自從版本3.2.4.0+開始已不再提供ANSI版本,因此再寫個能在新版用的

測試版本:v3.3.0.0
在編寫的過程中,一開始是打算使用 StringToBinary/Binary/DllStructSetData 來生成一個Ansi字符串方便處理的,但因為AutoIt存在將字符串截斷的問題(這個問題也算是歷史悠久了),因此不得不使用API來進行轉換。
有意思的是,在AutoIt的更新日志里面卻說這個問題已經解決了face


Fixed #92: DllStruct data truncated with char[]/wchar[].

最后還是要抱怨一下默認情況下AutoIt的 Send 函數(shù)速度實在是太慢了,好在AutoHotkey的速度很理想,盡管Send這種功能我本來也很少用 :)

HotKeySet("{F10}", "SendTest")

While
1
    Sleep(100)
WEnd

Func
SendTest()
    Local $string = "A中文字符串A"
    $begin = TimerInit()

    For $i = 1 To 10
        _Send( $string )
        Send("{Enter}")
    Next
    $dif = TimerDiff($begin)
    MsgBox(0,"Time passed", $dif)
EndFunc

; 函數(shù): _Send
; 用途:發(fā)送字符串
; 參數(shù):$string,待轉換的字符串,既可以是字符串字面值常量也可以是一個指向包含
;                Unicode 字符數(shù)組的 DllStruct 元素的指針
;       $bSendKeys,是否發(fā)送字符串,為 false 時只返回待發(fā)送的 Keys(請參考返回
;                值的說明) 而不發(fā)送字符串
; 返回值:使用 Send 函數(shù)時傳遞給它的第一個參數(shù)(Keys),形如 {Asc nn1}{Asc nn2}
Func _Send( Const $string, $bSendKeys = true )
    Local $szKeys = ""                           ; 待發(fā)送的按鍵序列
    Local $nLen = StringLen($string)             ; 字符串的長度
    ; 字符串的 Unicode 編碼數(shù)組
    Local $UnicodeStringASCIIArray = StringToASCIIArray( $string )
    ; 因須將 $string 轉換為多字節(jié)版本,下面計算足夠用以保存轉換成后數(shù)據(jù)的空間大小    
    Local $nAnsiBufferSize = ($nLen+1) * 2               
    ; 用以保存轉換后的結果
    Local $pAnsiStringStruct = DllStructCreate("ubyte[" & $nAnsiBufferSize & "]")
    ; 將 $string 轉換為多字節(jié)版本
    Local $nBytesWritten = WideCharToMultiByte( $string, DllStructGetPtr($pAnsiStringStruct) )
    If $nBytesWritten <= 0 Then
        $pAnsiStringStruct = 0
        Return SetError(@error, 0, "")
    EndIf


    Local $AnsiIndex = 1  ; Ansi 字符串元素的索引
    Local $value          ; 要傳給 Send 函數(shù)的數(shù)值,用以構成 {Asc $value}
    For $i = 0 To $nLen-1
        $value = DllStructGetData($pAnsiStringStruct, 1, $AnsiIndex)
        If $UnicodeStringASCIIArray[$i] > 255 Then  ; 大于255的字符說明是Unicode字符
            $AnsiIndex += 1
            $value = $value * 256 + DllStructGetData($pAnsiStringStruct, 1, $AnsiIndex)
        ElseIf $value > 0 Then
            $value = "0" & $value
        EndIf
        $szKeys &= "{Asc " & $value & "}"
        $AnsiIndex += 1
    Next
    If $bSendKeys Then Send($szKeys)
    $pAnsiStringStruct =
0

    Return $szKeys
EndFunc
   ;==>_Send

Func SendByClipboard( Const $string, $BackupClipBoard = false )
    If $BackupClipBoard Then
        Local $bak = ClipGet()
    EndIf
    ClipPut($string)
    Send("^v")
    If $BackupClipBoard Then ClipPut($bak)
EndFunc

; 函數(shù): WideCharToMultiByte
; 用途:將 Unicode 字符串轉換為多字節(jié)字符串
; 參數(shù):$UnicodeString,待轉換的字符串,既可以是字符串字面值常量也可以是一個指
;                向包含 Unicode 字符數(shù)組的 DllStruct 元素的指針
;       $pMultiByte,用以保存轉換結果的地址,指向一個char/byte數(shù)組的 DllStruct
;                元素的指針
;       $iCodePage,代碼頁
; 返回值:寫入到 $pMultiByte的字節(jié)數(shù)
Func WideCharToMultiByte($UnicodeString, $pMultiByte, $iCodePage = 0)
    Local $aResult, $ParamType = "wstr"
    If IsPtr($UnicodeString) Then $ParamType = "ptr"
   
    $aResult = DllCall("Kernel32.dll", "int", "WideCharToMultiByte", "int", $iCodePage, "int", 0, _
            $ParamType, $UnicodeString, "int", -1, "int", 0, "int", 0, "int", 0, "int", 0)
    If @error Then Return SetError(@error, 0, 0)
    $aResult = DllCall("Kernel32.dll", "int", "WideCharToMultiByte", "int", $iCodePage, "int", 0, _
            $ParamType, $UnicodeString, "int", -1, "ptr", $pMultiByte, "int", $aResult[0], "int", 0, "int", 0)
    If @error Then Return SetError(@error, 1, 0)
    Return $aResult[0]
EndFunc
  ;==>WideCharToMultiByte


///////////////////////////////////////////////////////////////////////////////

AU3腳本(3.2.4.0 之前的版本)
(注意,最新版本(3.2.4.0+)已不再提供ANSI版本!因此請注意你的AutoIt版本):
#cs
運行腳本時需用 AutoIt3A.exe
將 AutoIt 目錄下的AutoIt3A.exe重命名為AutoIt3.exe即可(建議先備份AutoIt3.exe)
編譯腳本時需用 Aut2exeA.exe
#ce

Run
("notepad"
)
WinWaitActive("[CLASS:Notepad]"
)

_SendRaw("簡體中文And繁體中文")

Func _SendRaw($Keys
)
    Local $KeysInUnicode =
""
    Local $len = StringLen($Keys
)
    Local
$char1
    Local
$code1
    Local
$char2
    Local
$code2
    Local $index =
1
    While
True
        $code2 =
0
        $char1 = StringMid($Keys, $index,
1)
        $code1 = Asc($char1)
        If $code1 >= 129 And $code1 <= 254 And $index < $len
Then
            $char2 = StringMid($Keys, $index+1,
1)
            $code2 = Asc($char2)
            If $code2 >= 64 And $code2 <= 254
Then
                $code1 *=
256
                $code1 +=
$code2
           
EndIf
            $index +=
1
       
EndIf
        If $code1 <= 255 Then $code1 = "0" &
$code1
        $KeysInUnicode &= "{ASC " & $code1 &
"}"
        If $code2 > 0 And $code2 < 64
Then
            $code2 = "0" &
$code2
            $KeysInUnicode &= "{ASC " & $code2 &
"}"
       
EndIf
        $index +=
1
        If $index > $len Then
ExitLoop
   
WEnd
    Send($KeysInUnicode
)
EndFunc

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日本中文字幕在线精品| 欧美国产日产综合精品| 狠色婷婷久久一区二区三区| 国语久精品在视频在线观看 | 欧美不卡午夜中文字幕| 九九热最新视频免费观看| 欧美字幕一区二区三区| 亚洲熟女一区二区三四区| 久热久热精品视频在线观看| 人妻巨大乳一二三区麻豆| 久七久精品视频黄色的| 亚洲最新av在线观看| 深夜视频在线观看免费你懂| 色偷偷亚洲女人天堂观看| 懂色一区二区三区四区| 日本人妻精品有码字幕| 丝袜诱惑一区二区三区| 国产亚洲精品一二三区| 国产内射一级二级三级| 欧美熟妇喷浆一区二区| 欧美午夜视频免费观看| 亚洲av熟女国产一区二区三区站| 日本人妻熟女一区二区三区| 暴力三级a特黄在线观看| 午夜小视频成人免费看| 99热中文字幕在线精品| 亚洲精品福利入口在线| 亚洲综合伊人五月天中文| 亚洲欧美日本国产不卡| 国产精品久久女同磨豆腐| 中文字幕一区二区免费| 99视频精品免费视频| 熟女乱一区二区三区丝袜| 最近最新中文字幕免费| 亚洲国产成人精品一区刚刚| 久久精视频免费视频观看| 丁香六月啪啪激情综合区| 青青操日老女人的穴穴| 亚洲天堂精品一区二区| 冬爱琴音一区二区中文字幕| 欧美国产日产综合精品|