狙い
古いDLLは文字コードにCP932を使ってるものがあるが
web上に見受けられる文献にはこれらの遺物を利用する方法が見つからないのでここに記述する。
コード
call_msgbox.go
package main
import (
"syscall"
"unsafe"
"golang.org/x/text/encoding/japanese"
"golang.org/x/text/transform"
)
func cp932(str string) string {
r, _, err := transform.String(japanese.ShiftJIS.NewEncoder(), str)
if err != nil {
panic(err)
}
return r
}
func cp932ptr(str string) *byte {
return syscall.StringBytePtr(cp932(str))
}
func main() {
user32 := syscall.MustLoadDLL("user32.dll")
defer user32.Release()
MessageBoxA := user32.MustFindProc("MessageBoxA")
MessageBoxW := user32.MustFindProc("MessageBoxW")
//wide char = utf16le
MessageBoxW.Call(0,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("日本語の表示"))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("UTF16LEの場合"))),
0)
// cp932
MessageBoxA.Call(0,
uintptr(unsafe.Pointer(cp932ptr("日本語の表示"))),
uintptr(unsafe.Pointer(cp932ptr("CP932の場合"))),
0)
// UTF8もANSI互換なので英数字のみならば
MessageBoxA.Call(0,
uintptr(unsafe.Pointer(syscall.StringBytePtr("ascii only"))),
uintptr(unsafe.Pointer(syscall.StringBytePtr("utf8 is ANSI"))),
0)
}
反省点
あくまでCP932(いわゆるSJIS)用である。
ユーザーの入力をOSのANSI関数に渡す場合にはWideCharToMultiByteを利用して
UTF16へ変換 -> WideCharToMultiByte -> CP_ACP へ変換してやるべき
一言
uintptr(unsafe.Pointer(
が非常に冗長に感じる