指定のフォントを表示するには?

解決


龍猫  2009-03-04 19:03:42  No: 33545

TImage の canvas に  TextOut を使って
中国語文字を表示したいのですがどうすればよいですか?

Form に Edit,Image,Button を配置し
Editに入力した中国語、韓国語などの文字(Editには正しく表示されます)
をImage に表示するだけです。

最終的には エディタのようにEdit無しでImageに文字を
描画できるようにしたいです。


とりあえず  2009-03-04 19:09:04  No: 33546

Image.CanvasのFontを変更してみたら?


龍猫  2009-03-04 19:25:40  No: 33547

とりあえず
いろいろフォントを変更してみましたが
文字化けしたままでした。


龍猫  2009-03-04 20:26:20  No: 33548

最終的にやりたいことを書きます。

現状では、中国語+日本語と韓国語+日本語  を
表示できるようにした単語帳もどきを作って
印刷したいのです。

ImageにしたのはMemo,RichEditだとフォント2種類の設定や
自由配置できないと思っただけです。


せめて  2009-03-04 23:07:29  No: 33549

OSとコンパイラのバージョン位書きましょうよ


D  2009-03-05 10:30:22  No: 33550

私は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にしたらどれもちゃんと表示されました。

ハングルのほかに中国語なども試してみましたが、ハングルだけの場合にだけ文字化けするような感じです。

多分龍猫さんとは環境が違うと思うのですが、参考までに。


龍猫  2009-03-05 19:08:32  No: 33551

環境は 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 に表示されるのは[?好]です


龍猫  2009-03-05 19:10:30  No: 33552

すみません。
正しく表示できないみたいです。

前記述の
[你好]の部分は正常に表示されている部分になります。


Uni  2009-03-05 21:33:33  No: 33553

相変わらずコンパイラのバージョンが不明ですが・・・
Delphi2007とDelphi2009では漢字コードまわりの処理が変更になってますのでバージョンをはっきりさせましょう。
[你好]はDelphi2009のMemo&Editでは正常に表示されるようです。
ただ、ExtTextOutWとTextOutWでうまくいかないのは仕様かもしれません。
http://support.microsoft.com/kb/145754/ja


龍猫  2009-03-06 04:26:45  No: 33554

すみません。
本題から、ずれて申し訳ありませんけど
コンパイラのバージョンってなんでしょうか?
そもそも、コンパイラって何でしょうか?
わからなくてすみません。

バージョン情報を調べると以下のように書いてありました。
[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でないと
対応できないということすか?

何もわからなくてすみません。


Uni  2009-03-06 05:39:39  No: 33555

コンパイラはこの場合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に個別に描く方法もありでしょう。


KHE00221  2009-03-06 09:43:12  No: 33556

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


D  2009-03-09 05:48:44  No: 33557

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;

だめかな、、


龍猫  2009-03-10 19:16:47  No: 33558

皆さんありがとうございます。

こちらでもいろいろ試しているのですが。
現状ではうまくいっていません。

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  あたりを使ってみましたが
型があっていないのかコンパイルでエラーが出てしまいます。


D  2009-03-11 05:44:26  No: 33559

>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文字の入力は貼り付けでしかできないかも知れませんが。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加