こんにちは。
Unicode文字(WideChar)が半角で描かれるのか全角で描かれるのかを区分けしたくて
以下のコードで取得できる
HiByte=00で区別できるかと思ったのですが
半角カタカナを読み込ませたところ
HiByteがFFでした
Unicode文字(WideChar)が半角で描かれるのか全角で描かれるのかは
HiByteが00か、FFか、で判断してよいものでしょうか?
教えてください。よろしくお願いします。
調査のためのコードです。
procedure TForm1.Button1Click(Sender: TObject);
var
swork: WideString;
msg: AnsiString;
i: Integer;
Buffer: Char;
begin
// WideStringの内容をチェック
swork := 'ABCあいうアイウエオアイウエオ';
msg := '元の文字列=' + swork + #13#10;
for i := 1 to Length(swork) do
begin
Buffer := Char(HiByte(word(swork[i])));
msg := msg + IntToHex(Ord(Buffer), 2) + ' ';
Buffer := Char(LoByte(word(swork[i])));
msg := msg + IntToHex(Ord(Buffer), 2) + ' ';
end;
ShowMessage(msg);
end;
半角カタカナが消えてしまっていますが、
二つめのアイウエオは半角カタカナです。
HiByteなどでチェックしたいわけではなく
他にもよい判断方法ご存じでしたら
教えてください。
目的によると思いますが、
1.半角、全角が含まれているかどうか
2.半角 - 全角 変換が行いたい
のであればLCMapStringWなんていうWindowsAPIがあります。
string に代入して長さ見てみたらいいんじゃないでしょうか
お返事ありがとうございます。
目的は、WideStringでの半角80桁折り返し処理、ですので(もちろん80は可変)
文字列を頭から検索していって80桁目になったかどうかを調べるために
WideCharの1文字が半角か全角かを知りたいのです。
LCMapStringWではちょっと処理が遠い気がします。
stringに代入、、、うーん、高速化という意味でもUnicodeのみの処理という
意味でも、少し避けたいところです。
わがままですいません。
GetCharWidth32W か GetTextExtentPoint32W で調べる。
でも GetCharWidth32W は正しい値を取得できない場合がある。
Unicodeの場合、固定幅フォントでも 半角:全角=1:2とはかぎらないのが困りものですが…
半角より幅が広いけど全角より狭い文字があったり、全角よりも幅が広い文字があったり…
単純にACSII文字と半角カナが知りたいのであれば、
case Ord(wc) of // var wc: WideChar;
$20..$7F, $FF61..$FF9F:
// 処理
end;
で、判断できます。
$20..$7F, $FF61..$FF9F についてはちゃんと調べていませんが…
ちなみにHIBYTEの$FFには全角アルファベットも含まれていますよ。
ACSII -> ASCII の間違い。
なるほど、そういうアプローチもあるわけですね。
文字幅を微妙なところまで考え出すと非常に複雑ですね.....
大変勉強になりました。ありがとうございます。
ヒントいただきましていろいろ探して
Unicode対応 文字コード表
http://ash.jp/code/unitbl1.htm
を参考にみて、
次の関数を作って望みのものができました。
Delphiでは
『\』の扱いは参考のページとは違って $005C として表現されるようです。
『~』は参考ページ通り $203E でした。
type TWideCharByteLength = (wcblSingle, wcblMulti);
function WideCharByteLength(source: WideChar): TWideCharByteLength;
var
Buffer: word;
begin
Buffer := Ord(source);
case Buffer of
$0020..$007F, $203E, $FF61..$FF9F:
begin
Result := wcblSingle;
end;
else
begin
Result := wcblMulti;
end;
end;
end;
ファーストテストコードは次のようになります。
(カタカナや記号は全部半角)
procedure Check(A, B: Variant); overload;
begin
if not(A = B ) then
begin
Assert(False, 'エラーです');
end;
end;
procedure testWideCharByteLength;
begin
Check(wcblSingle, WideCharByteLength(WideChar(WideString('a')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('g')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('z')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('A')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('G')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('Z')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('\')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('[')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString(']')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('^')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('`')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('_')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('~')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('{')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('|')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('}')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('。')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('「')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('」')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('、')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('・')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヲ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ァ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ィ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ゥ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ェ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ォ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ャ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ュ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ョ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ッ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ー')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ア')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('イ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ウ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('エ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('オ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('カ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('キ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ク')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ケ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('コ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('サ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('シ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ス')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('セ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ソ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('タ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('チ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ツ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('テ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ト')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ナ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ニ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヌ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ネ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ノ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ハ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヒ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('フ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヘ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ホ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('マ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ミ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ム')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('メ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('モ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヤ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ユ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヨ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ラ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('リ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ル')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('レ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ロ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ワ')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('ン')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('゛')[1])));
Check(wcblSingle, WideCharByteLength(WideChar(WideString('゜')[1])));
Check(wcblMulti, WideCharByteLength(WideChar(WideString('a')[1])));
Check(wcblMulti, WideCharByteLength(WideChar(WideString('A')[1])));
end;
あ、解決時はチェックでした....(^〜^;)
ツイート | ![]() |