Jump to content
Sign in to follow this  
hcchen5600

_INetMail() garbled multibyte characters (say Big5 Chinese

Recommended Posts

hcchen5600

(English)

(inet.au3) _INetMail() can not handle (Big5 coded) Chinese characters. They are garbled.

I checked, the root cause is _INetExplorerCapable() in inet.au3 does not consider multibyte

characters. So I tried and have fixed it. I change a file name inet_tw.au3 for your #include,

so we can use _INetMail() to send emails with Chinese subject and body.

(Chinese)

發信方法 _INetMail() 透過 mailto: 途徑發信有「中文亂碼」的新問題。

幾經研究,我已經把 autoit3 裡的 Inet.au3 改寫成 Inet_tw.au3 解決了中文亂碼的現象。試過我的繁中

Windows Vista 已經 OK。如果簡中也 OK,則可以進一步改檔名為 Inet_multibyte.au3 更適合。因為我的

修改是讓原本不考慮 multi-byte 的 _INetExplorerCapable() 考慮上了 multibyte 的情形,從而解決了中

文亂碼的問題。

Modify the original inet.au3 , change the _INetExplorerCapable() to below code.

Then rename it to inet_tw.au3.

Below Sample code works fine.

#include <INet_tw.au3>

$result = _INetMail("youremail@gmail.com", "subject 中文標題", "body 中文內容")

MsgBox(0,'E-Mail has been opened','The E-Mail has been opened and process identifier for the E-Mail client is ' & $result)

;===============================================================================
;
; Function Name:    _INetExplorerCapable()  
; Description:      Convert a string to IE capable line
; Parameter(s):     $s_IEString - String to convert to a capable IExplorer line with Chinese support (multibyte support)
; Requirement(s):   None
; Return Value(s):  On Success - Returns the converted string
;                   On Failure - Blank String and @error = 1
; Author(s):        hcchen5600 2010/04/26 15:03:33 
;                   Wes Wolfe-Wolvereness <Weswolf at aol dot com> 
;
;===============================================================================
;
Func _INetExplorerCapable($s_IEString)
    If StringLen($s_IEString) <= 0 Then
        Return ''
        SetError(1)
    Else
        Local $s_IEReturn
        Local $i_IECount, $i_MBCount
        Local $n_IEChar
        For $i_IECount = 1 To StringLen($s_IEString)
            
            ; 本來的寫法沒有考慮中文 (multibyte characters)
            ; $n_IEChar = '0x' & Hex(Asc(StringMid($s_IEString, $i_IECount, 1)), 2)
            ; If $n_IEChar < 0x21 Or $n_IEChar = 0x25 Or $n_IEChar = 0x2f Or $n_IEChar > 0x7f Then
            ;   $s_IEReturn = $s_IEReturn & '%' & StringRight($n_IEChar, 2)
            ; Else
            ;   $s_IEReturn = $s_IEReturn & Chr($n_IEChar)
            ; EndIf

            ; 把 multibyte characters 的情形也考慮進去 hcchen5600 2010/04/26 15:54:45 
            $n_IEChar = StringToBinary(StringMid($s_IEString, $i_IECount, 1)&' ')
            $n_IEChar = StringRegExpReplace($n_IEChar,"(..)(20)?+\z","\1") ; 剃掉尾巴多餘的 '20' hcchen5600 2010/04/26 08:39:28 
            If $n_IEChar < 0x21 Or $n_IEChar = 0x25 Or $n_IEChar = 0x2f then
                $s_IEReturn = $s_IEReturn & '%' & StringRight($n_IEChar, 2)
            ElseIf $n_IEChar > 0x7f Then
                For $i_MBCount = 3 To StringLen($n_IEChar) Step 2
                    $s_IEReturn &= '%' & BinaryToString(StringMid($n_IEChar, $i_MBCount, 2))
                Next
            Else
                $s_IEReturn = $s_IEReturn & Chr($n_IEChar)
            EndIf
        Next
        Return $s_IEReturn
    EndIf
EndFunc   ;==>_INetExplorerCapable
Edited by hcchen5600

Share this post


Link to post
Share on other sites
hcchen5600

My colleague told me that this solution works fine on simplified Chinese system also.

To me, the most important trick is this line,

$n_IEChar = StringToBinary(StringMid($s_IEString, $i_IECount, 1)&' ')

StringMid($s_IEString, $i_IECount, 1) returns 1 byte for none multibyte characters, 'a' 'b' 'c' '1' '2' '3' etc, but

retunrs two bytes for multibyte characters !! I am surprised, this is amazing to me. However, it works and is very

important to this solution.

To correctly translate a multibyte character to %AB%CD format by StringToBinary(), an extra space is needed. The strange

thing is that if there are two multibyte characters or three then two more and three more spaces are needed respectively!

This is strange to me, however it just works that way. So, for none multibyte characters we have to remove the unexpected

space. That's what the "$n_IEChar = StringRegExpReplace($n_IEChar,"(..)(20)?+\z","\1")" is for.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×