|
|
2013/2/23(Sat) 11:33:53|NO.52531
UTF-8で書かれたtxt文章ファイルを読み込んで、mesboxに表示するというプログラムで
Unicodeに対応しようとしています。
試しに
cnvstow tmp,"あいうえお"
val=cnvwtos(tmp)
dialog val
を実行してみたのですが、「あい」としか表示されません。
どのようにすれば表示できるでしょうか。
|
|
2013/2/23(Sat) 12:03:33|NO.52533
現在のテスト中のコードです。
文章途中で文字が区切れていたり、文字化けがあったりします。
#include "user32.as"
#include "kernel32.as"
#include "gdi32.as"
#define DT_WORDBREAK $00000010
#define DT_EXPANDTABS $00000040
#define MAX_PATH $00000104
#define INVALID_HANDLE_VALUE $FFFFFFFF
#define ERROR_NO_MORE_FILES $00000012
#define FILE_ATTRIBUTE_DIRECTORY $00000010
#define SW_SHOW $00000005
#define WS_CHILD $40000000
#define WS_VISIBLE $10000000
#define ES_MULTILINE $00000004
#define WS_BORDER $00800000
#define WS_VSCROLL $00200000
#define WS_HSCROLL $00100000
#define ES_READONLY $00000800
#define WS_EX_CLIENTEDGE $00000200
#define FW_NORMAL $00000190
#define DEFAULT_CHARSET $00000001
#define OUT_DEFAULT_PRECIS $00000000
#define CLIP_DEFAULT_PRECIS $00000000
#define DEFAULT_PITCH $00000000
#define FF_DONTCARE $00000000
#define WM_SETFONT $00000030
#define SYSTEM_FONT $0000000D
#define dwFileAttributes 0
#define nFileSizeLow 8
#define cFileName 11
filelist=""
cnvstow ln,"\n"
notesel utfx:noteload "utf8.txt"//<-UTF-8で保存されている文章
repeat notemax
x=""
noteget x,cnt
cnvstow x2,""+x
lstrcatW varptr(filelist),varptr(x2)
lstrcatW varptr(filelist),varptr(ln)
loop
style = WS_CHILD | WS_VISIBLE | ES_MULTILINE | WS_BORDER | WS_VSCROLL |WS_HSCROLL | ES_READONLY
CreateWindowExW WS_EX_CLIENTEDGE, "EDIT", varptr(filelist), style, 0, 0, GINFO_WINX, GINFO_WINY, hwnd, 1, hinstance, 0
hedit = stat
pandf = DEFAULT_PITCH | FF_DONTCARE
CreateFontW 16, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, pandf, MSGOTHIC
hfont = stat
SendMessageW hedit, WM_SETFONT, hfont, 1
stop
参考にしたサイト: http://winapple.blog49.fc2.com/blog-entry-81.html

| |
|
2013/2/23(Sat) 12:07:46|NO.52534
試しに の部分は使用する分、文字列型で変数を確保しておけばOK
sdim tmp
cnvstow tmp, "あいうえお"
val = cnvwtos(tmp)
dialog val
mesboxでUnicodeを使うためには、UTF-8ではなくUTF-16にする必要があります。
cnvstowやcnvwtosはShift_JIS(CP932)とUTF-16の変換にしか使えませんのでご注意を。
また、mesboxで指定した変数に直接UTF-16の文字列を入れることはできません。
(文字化けします。objprm等も同様)
Win32APIのSendMessageWでWM_SETTEXTを送ってあげることで、扱うことができます。
#uselib "user32.dll"
#func SendMessageW "SendMessageW" int, int, int, int
#define WM_GETTEXT 0x000D
#define WM_SETTEXT 0x000C
font "メイリオ", 32, 16
objmode 2
sdim dummy
mesbox dummy, 640, 360
hMesbox = objinfo(stat, 2)
objsize 320, 40
button gosub "ハートを書き込む", *write_hearts
button gosub "笑顔を書き込む", *write_egao
stop
*write_hearts
// ハート
utf16 = 0x00002661
// http://msdn.microsoft.com/ja-jp/library/cc411022.aspx
// http://chokuto.ifdef.jp/urawaza/message/WM_SETTEXT.html
SendMessageW hMesbox, WM_SETTEXT, 0, varptr(utf16)
return
*write_egao
// 笑顔
utf16 = 0x0000263a
SendMessageW hMesbox, WM_SETTEXT, 0, varptr(utf16)
return
|
|
2013/2/23(Sat) 12:08:02|NO.52535
inoviaさん、ありがとうございます。
sdim tmp
cnvstow tmp, "あいうえお"
val = cnvwtos(tmp)
dialog val は文字化けしました。
ハートと笑顔のソースは、笑顔のみ表示できました。
なるほど・・・UTF-8をUTF-16に変更すれば、文章をそのまま表示できそうですね。
やってみます。
|
|
2013/2/23(Sat) 12:15:57|NO.52536
>ハートと笑顔のソースは、笑顔のみ表示できました。
もしかして、今の実行環境は英語版のWindowsですかね?
そうなるとメイリオフォントはないと思うので、適当なフォントが選択されている可能性があり、
現在使用されているフォントにハートがないために表示されていないだけかもしれません。
|
|
2013/2/23(Sat) 12:24:21|NO.52537
>>英語版のWindows
そうです。英語にはMeiryo UIというフォントがあります。
それにしてもUTF-16(=Unicode?)への変換は面倒です。
文章をrepeatnotemaxして行を読みこむ ⇒ 文字列を一文字ずつに区切り、それをUTF16に ⇒ 結合
という方法で試しています。
|
|
2013/2/23(Sat) 13:22:21|NO.52538
これでも文字化けしました。
UTF8.txtの中身: あえいうえおあお (最後に改行なし)
utfresult=""
notesel utftest:noteload "UTF8.txt":repeat notemax
noteget buf,cnt
sdim uni:cnvstow uni,buf
repeat
value = wpeek(uni, cnt * 2)
if value = 0 : break
x1=cnvwtos(value)//一文字
cnvstow x2,""+x1
mes x2
x3=cnvwtos(x2)
utfresult+=""+x3+"\n"
loop
loop
dialog utfresult
結果
---------------------------
---------------------------
ã
‚
ã
ˆ
ã
„
ã
†
ã
ˆ
ã
Š
ã
‚
ã
Š
---------------------------
OK
---------------------------
最終的にはmesboxに表示したいので、最初はSendMessageW hMesbox, WM_SETTEXT, 0, varptr(utf16)
を使おうとしたのですが、
SendMessageW hMesbox, WM_SETTEXT, 0, varptr(utf16)
SendMessageW hMesbox, WM_SETTEXT, 0, varptr(utf16)
のように2回繰り返しても一文字しか表示されませんでした。
|
|
2013/2/23(Sat) 13:28:13|NO.52539
もしかして、
> mesboxでUnicodeを使うためには、UTF-8ではなくUTF-16にする必要があります。
> cnvstowやcnvwtosはShift_JIS(CP932)とUTF-16の変換にしか使えませんのでご注意を。
HSP自身が読み込んだときに、文字列を自動的にShift_JISと認識しないのでしょうか・・・?
であれば、UTF-8 >(どこかにあったモジュール)> Shift_JIS >(cnv命令)> UTF-16
ということでしょうか。
|
|
2013/2/23(Sat) 15:31:50|NO.52542
UTF-8からUTF-16に変換するのにShift_JISを通してしまうと、
一部文字が文字化けします。(ハートとか)
MultiByteToWideChar関数を使うと直接変換できます。
#uselib "user32.dll"
#func SendMessageW "SendMessageW" int, int, int, int
#define WM_GETTEXT 0x000D
#define WM_SETTEXT 0x000C
#module
#uselib "kernel32"
#cfunc MultiByteToWideChar "MultiByteToWideChar" int, int, sptr, int, sptr, int
#define CP_UTF8 65001
#deffunc UTF8toUTF16 var utf8, var utf16
size = MultiByteToWideChar(CP_UTF8, 0, varptr(utf8), -1, 0, 0)
sdim utf16, size*2+2
return MultiByteToWideChar(CP_UTF8, 0, varptr(utf8), -1, varptr(utf16), size)
#deffunc DeleteUTF8BOM var utf8
// BOMチェック
if (lpeek(utf8, 0) & 0x00FFFFFF) == 0xBFBBEF{
dupptr tmp, varptr(utf8) + 3, 1, 2
utf8 = tmp
}
return
#global
title "UTF-8のテキストを読み込んでみるテスト"
dialog "txt", 16, "UTF-8のテキスト"
if stat == 0 : end
fname = refstr
notesel utf8
noteload fname
// BOMがある場合は削除
DeleteUTF8BOM utf8
// UTF-8からUTF-16に変換
UTF8toUTF16 utf8, utf16
sdim dummy
mesbox dummy, 640, 480, 1, 0
hMesbox = objinfo(stat, 2)
SendMessageW hMesbox, WM_SETTEXT, 0, varptr(utf16)

| |
|
2013/2/23(Sat) 16:35:04|NO.52543
英語OSで完璧に表示できました!
わからない関数が使われているので、それぞれ学んでみます。
inoviaさん、どうもありがとうございました。
|
|