TImage の canvas に TextOut を使って
中国語文字を表示したいのですがどうすればよいですか?
Form に Edit,Image,Button を配置し
Editに入力した中国語、韓国語などの文字(Editには正しく表示されます)
をImage に表示するだけです。
最終的には エディタのようにEdit無しでImageに文字を
描画できるようにしたいです。
Image.CanvasのFontを変更してみたら?
とりあえず
いろいろフォントを変更してみましたが
文字化けしたままでした。
最終的にやりたいことを書きます。
現状では、中国語+日本語と韓国語+日本語 を
表示できるようにした単語帳もどきを作って
印刷したいのです。
ImageにしたのはMemo,RichEditだとフォント2種類の設定や
自由配置できないと思っただけです。
OSとコンパイラのバージョン位書きましょうよ
私はDelphi6 Pro、XP SP2なのですがテストしてみました。
procedure TForm1.Button1Click(Sender: TObject);
var
lrc_Rect: TRect;
ls_Text: WideString;
begin
Image1.Canvas.Font.Assign(Edit1.Font);
Image2.Canvas.Font.Assign(Edit1.Font);
Image3.Canvas.Font.Assign(Edit1.Font);
ls_Text := WideChar($BBF8);
ls_Text := ls_Text + WideChar($C548);
Image1.Canvas.FillRect(Image1.ClientRect);
TextOutW(Image1.Canvas.Handle, 0, 0, PWideChar(ls_Text), Length(ls_Text));
Image2.Canvas.FillRect(Image2.ClientRect);
lrc_Rect := Image2.ClientRect;
DrawTextW(Image2.Canvas.Handle, PWideChar(ls_Text), -1, lrc_Rect, DT_NOPREFIX);
Image3.Canvas.FillRect(Image3.ClientRect);
ExtTextOutW(Image3.Canvas.Handle, 0, 0, 0, @lrc_Rect, PWideChar(ls_Text), Length(ls_Text), nil);
end;
としてみたところ。
Edit1のフォントがMS Pゴシックの場合、どれも文字化け。
それ以外のフォント(シンボル系以外)だとDrawTextWはちゃんと表示されますがTextOutWとExtTextOutWは文字化けしました。
そしてls_Textを
ls_Text := 'あ';
ls_Text := ls_Text + WideChar($BBF8);
ls_Text := ls_Text + WideChar($C548);
のようにしてみたらどれもちゃんと表示されました。
ハングルだけだとアウトで日本語が混じるとOKなようです。
ハングル+英数記号もアウトでした。
ハングルだけの場合も改行が入ったりする場合はOKでした。
さらにEdit1のフォントをMS UI Gothicにしたらどれもちゃんと表示されました。
ハングルのほかに中国語なども試してみましたが、ハングルだけの場合にだけ文字化けするような感じです。
多分龍猫さんとは環境が違うと思うのですが、参考までに。
環境は WindowsVista で RadStudio を使用です
Form の Font は [MSゴシック・標準・10]
Edit, Button ともに ParentFont です。
IME設定は
現在は中国語簡体字のみ追加登録
起動時に
Edit1 にIMEから入力する「你好」と入力すると
Edit1 に文字化けしないで表示されます。
ボタンを押すと
Image1.Canvas.Font.Assign(Edit1.Font);
Image1.Canvas.TextOut(0, 100, Edit1.Text);
を実行するのですが、Image1に表示されるのは[?好]です
1.[Ctrl]+[C]でコピーして
RichEdit に貼り付けると[ト羲テ]と表示され、
Memo に貼り付けると[你好]と表示されます
2.ボタンを押したときに
Edit1.Text := '你好';
を追加すると
Edit1 に表示されるのは[?好]です
すみません。
正しく表示できないみたいです。
前記述の
[你好]の部分は正常に表示されている部分になります。
相変わらずコンパイラのバージョンが不明ですが・・・
Delphi2007とDelphi2009では漢字コードまわりの処理が変更になってますのでバージョンをはっきりさせましょう。
[你好]はDelphi2009のMemo&Editでは正常に表示されるようです。
ただ、ExtTextOutWとTextOutWでうまくいかないのは仕様かもしれません。
http://support.microsoft.com/kb/145754/ja
すみません。
本題から、ずれて申し訳ありませんけど
コンパイラのバージョンってなんでしょうか?
そもそも、コンパイラって何でしょうか?
わからなくてすみません。
バージョン情報を調べると以下のように書いてありました。
[11.0.2804.9245]のことでしょうか?
CodeGear(TM) Delphi(R) 2007 for Win32(R) R2 Version 11.0.2804.9245 Copyright (c) 2007 CodeGear(TM). All Rights Reserved.
それともバージョン情報メニューのバージョン情報のボタンを
押したときのバージョンでしょうか?
300行以上あるみたいなのですべて書くのはちょっと無理みたいです。
それから、Delphi2007では対応できなくて、Delphi2009でないと
対応できないということすか?
何もわからなくてすみません。
コンパイラはこの場合Delphiですね
バージョンは[11.0.2804.9245]ですがDelphi2007と書いても今回の場合は大丈夫です。
目的は「中国語+日本語と韓国語+日本語」を表示できればよいっみたいですのでUNICODEベースで処理するのが簡単だと思います。
Delphi2009ならUNICODE対応なので、そのままMemoやRichEditで表示できると思います。
でもDelphi2007をお使いの様ですのでその場合は簡単にはUNICODEで利用できません。
以前はTNTWareの[TNT Unicode Controls]というのがFreeであったのですが現在は有料となっています。(http://www.tmssoftware.com/site/tmsuni.asp)
ここで(http://mh-nexus.de/en/tntunicodecontrols.php)別バージョンが入手可能なようですが目的にあってるかは分かりません。
また上の「D」さんのようにWideStringを使用してTImageに個別に描く方法もありでしょう。
FontName だけ変えて Charset を変えてない気がするんだけど?
var
WP : PWChar;
WS : WideString;
begin
WS := WideChar($BBF8) + WideChar($C548);
Canvas.Font.Name := 'MS Pゴシック';
Canvas.Font.Size := 32;
Canvas.Font.Charset := GB2312_CHARSET;
WP := PWideChar (WS);
TextOutW(Canvas.Handle,0,0,WP,Length(WP));
end;
でハングル表示できるけど
XP + BDS 2006
KHE00221さん。
>FontName だけ変えて Charset を変えてない気がするんだけど?
>でハングル表示できるけど
Charsetですか。確かにこれでハングルもちゃんと表示されますね。
でもなんでGB2312なんだろう、、と思って他のも試してみたところ、
CHINESEBIG5_CHARSET
GB2312_CHARSET
HANGEUL_CHARSET
THAI_CHARSET
これらでもちゃんと表示されました。
それはそうと。
龍猫さんの書き込みからするとEditやMemoはUnicode文字の入力と表示は対応してるようなのですが、Delphi2007+Vistaの環境だとそうなのでしょうか。
だとするとGetWindowTextW APIを使えばいけるのかもしれません。
function GetText(hHandle: HWND): WideString;
//ウィンドウハンドルhHandleのテキストを返す
var
li_Len: Integer;
lp_Text: PWideChar;
begin
Result := '';
li_Len := GetWindowTextLengthW(hHandle) + 1;
if (li_Len > 0) then begin
lp_Text := AllocMem(li_Len * 2);
try
GetWindowTextW(hHandle, lp_Text, li_Len);
Result := WideString(lp_Text);
finally
FreeMem(lp_Text);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
lrc_Rect: TRect;
begin
Image1.Canvas.FillRect(Image1.ClientRect);
lrc_Rect := Image1.ClientRect;
DrawTextW(Image1.Canvas.Handle, PWideChar(GetText(Edit1.Handle)), -1, lrc_Rect, DT_NOPREFIX);
end;
だめかな、、
皆さんありがとうございます。
こちらでもいろいろ試しているのですが。
現状ではうまくいっていません。
procedure TForm1.DrawCanvas(Image: TImage; X: Integer; Y: Integer; WS : WideString);
begin
TextOutW(Image.Canvas.Handle, X, Y, PWideChar(WS), Length(PWideChar(WS)));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DrawCanvas(Image1, 10, 30, WideChar($BBF8) + WideChar($C548));
DrawCanvas(Image1, 10, 10, WideChar($4F60) + WideChar($597D));
end;
上記コードでImageに 韓国語、中国語が表示されています。
フォントの指定はしていませんが、Formのフォントは
[MS ゴシック、標準、10、日本語] です。
Edit1.Textの入力について
Edit1.Text := 'xxx';
コードで入力したときのEdit1 の表示は文字化けします。
IMEから直接入力したときの表示は文字化けしません。
Edit1.Text のデータを表示する方法がわかりません。
Utf8ToUnicode とか UTF8Decode あたりを使ってみましたが
型があっていないのかコンパイルでエラーが出てしまいます。
>IMEから直接入力したときの表示は文字化けしません。
IMEから直接入力したときに文字化けしていないということでEdit1はUnicodeで文字列を保持しているのかもしれません。
ただ、Delphi 2007のTEditのTextプロパティはWideStringではなくAnsiStringなので、たとえEdit1がUnicodeで文字列を保持していたとしてもTextプロパティで取得したのではAnsiStringに変換された文字列にしかなりません。
ということでGetWindowTextW APIを使えばUnicodeのままで取得できるかもしれないなと思ってGetTextを例示したのですが、だめだったようですね。
となると解決策は
・Delphi 2009にバージョンアップする
・Delphi for .NETにする(Unicodeに対応しています)
・Uniさんが紹介されているTNTWareを利用する
・CreateWindowW APIでUnicode対応のEditコントロールを作る
これらのどれかになるのではないでしょうか。
Delphi for .NETが無償で利用できるので特に問題がなければお勧めかなと。
ちなみにCreateWindowW APIの場合。
type
TForm1 = class(TForm)
...
private
{ Private 宣言 }
F_hEdit: HWND;
public
{ Public 宣言 }
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//Unicode対応エディットコントロール
F_hEdit := CreateWindowW(
'EDIT',
nil,
WS_CHILD
or ES_AUTOHSCROLL
or ES_NOHIDESEL
or WS_VISIBLE,
8, //Left
8, //Top
121, //Width
20, //Height
Handle, //親ウィンドウ
0,
0,
nil
);
//フォントのセット
if (F_hEdit <> 0) then begin
SendMessageW(F_hEdit, WM_SETFONT, WPARAM(GetStockObject(DEFAULT_GUI_FONT)), 0);
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
DestroyWindow(F_hEdit);
end;
文字列の取得は先に例示したGetText関数を使います。
procedure TForm1.Button1Click(Sender: TObject);
begin
DrawCanvas(Image1, 10, 30, GetText(F_hEdit));
end;
こんな感じで。
もしかしたらUnicode文字の入力は貼り付けでしかできないかも知れませんが。
ツイート | ![]() |