過去ログを拝見してEditに入力された漢字のふりがなを取得する方法はあったのですが、例えばDelphiでCSV形式のデータをインポートした時に、インポートした漢字のふりがなを取得する良い方法はありませんか?
やはり、IMEで変換して入力した文字しかふりがなを取得することはできないのでしょうか?
1)IMEの再変換機能を利用しても出来そうですね。
2)私は IMEの機能ではなく'KAKASI' のkakasi.dll をDelphiから呼び出して使用しています。
詳細は調べてみてください。
早速の返信ありがとうございます。
>1)IMEの再変換機能を利用しても出来そうですね。
これは、プログラムで一旦対象の文字をEditに入れて、その文字を反転させて再変換し、ふりがなを取得するということですか?
結構ややこしそうですね。
>2)私は IMEの機能ではなく'KAKASI' のkakasi.dll をDelphiから呼び出して使用しています。
kakasiについて色々と調べて見たのですが、Delphiからの呼び出し方が分かりません。使い方を教えて頂けませんか?
動的リンクだとちょっと長くなるのでとりあえず静的リンクの例
以下のユニットをサンプルAPPに追加してください
使用するための最低限の定義です
//-----------------------------------------------------------------------------
unit u_kakasi; // ファイル名は u_kakasi.pas とした
interface
function kakasi(AText: string; Arg: string = ''): string;
// kakasi.dllの関数定義
function kakasi_getopt_argv(argc:integer; argv:pointer):Integer; cdecl; external 'kakasi.dll';
function kakasi_do(P: PChar):PChar; cdecl; external 'kakasi.dll';
function kakasi_close_kanwadict:Integer; cdecl; external 'kakasi.dll';
function kakasi_free(P: PChar):Integer; cdecl; external 'kakasi.dll';
implementation
uses
Windows, SysUtils, Classes;
//---------------------------------------------------------------------
// -JK -HK
function kakasi_setarg(Arg: string): Integer;
var
Argc: Integer;
Argv: array [0..31] of string;
procedure AddArg(S: string);
begin
S := Trim(S);
if (Length(S) > 0) and (Argc <= High(Argv)) then
begin
Argv[Argc] := S;
inc(Argc);
end;
end;
var
n: Integer;
begin
Argc := 0;
AddArg('kakasi');
with TStringList.Create do
try
Delimiter := ' ';
DelimitedText := Arg;
for n := 0 to Count-1 do
AddArg(Strings[n]);
kakasi_close_kanwadict;
Result := kakasi_getopt_argv(Argc, @Argv);
finally
Free;
end;
end;
function kakasi(AText: string; Arg: string = ''): string;
var
P:PChar;
begin
Result := AText;
if Length(Arg) > 0 then
kakasi_setarg(Arg);
P := nil;
try
P := kakasi_do(PChar(AText));
if P <> nil then
Result := P;
finally
kakasi_free(P);
end;
end;
end.
//-----------------------------------------------------------------------------
条件)
1)環境変数'KANWADICTPATH'と'ITAIJIDICTPATH'が適切にシステムに登録されていること
2)'KAKASI'インストールディレクトリの kakasi.exe で変換が正常に動作する環境となっていること
3)kakasi.dllはDelphiのサンプルディレクトリと同じ場所かパスの効いている所にあること
使用例)
Delphi-Appで
Memo2.Text := kakasi(Memo1.Text, '-JH -KH');
ですべての漢字・カタカナをひらがなに変換します
オプションについては kakasi.sjis を参照してください。
正式には動的リンクで組んだ方が良いでしょう。
ご存知と思いますが
環境変数'KANWADICTPATH'と'ITAIJIDICTPATH'をシステムに登録するには
WindowsXPの例
1)マイコンピュータのプロパティ(右クリック)で「システムのプロパティを表示」
2)「詳細設定」タブを選択
3)「環境変数」のボタンを押す
4)「ユーザ環境変数」か「システム環境変数」のどちらかに'KANWADICTPATH'と'ITAIJIDICTPATH'を登録
例)
ITAIJIDICTPATH=c:\kakasi\share\kakasi\itaijidict
KANWADICTPATH=c:\kakasi\share\kakasi\kanwadict
補足)
kakasi.dllの呼び出し規約について
上記サンプルでも分りますが DLLの呼び出し規約が一般的な stdcall ではなく cdecl になっているので注意してください。
stdcallで定義するとメモリー関連のエラーが出ます。
返信が遅くなり大変申し訳ありません!
よみさんに丁寧に教えて頂いたおかげで、見事に要件を満たすことが出来ました。ありがとうございました。
ただ、環境変数にパスを通したりDLLを配置したりと少し手間がかかりますね。
DLLを扱ったことが無いので、静的リンクと動的リンクの違いがあまりわかっていないのですが、動的リンクにするとこれらの設定はいらなくなるのですか?
>静的リンクと動的リンクの違いが・・・
「静的リンク」には別の意味があるので DLLの静的ロードと動的ロードと訂正します。
「静的ロード」の場合は使用する DLLが見つからない場合はアプリケーションまで制御が回らずにシステムでエラー表示して終了します。
アプリ側で何らかのエラーメッセージを出したい場合やDLLがなくても他の作業は実行したい場合にはこれで困りますので「動的ロード」を使用してアプリ側でエラーチェックを行います。
ですので「動的ロード」にしたからといってkakasi.dllの環境変数の設定が必要なくなるということにはならないですね。
環境変数の設定は kakasi.dll の仕様で必須です。
その気になればソースが公開されていますのでオプションで指定できるように変更することは可能です。
また、CやC++の場合は kakasiにlibファイルが用意されていますので「静的リンク」を行えば kakasi.dllは必要なくなりますが、Delphiの場合はLibファイルのリンクが出来ないためDLLを利用する「動的リンク」(静的・動的ロード)しか利用できません。
(無理やりやろうと思えばDelphiで.OBJファイルをリンクすることが出来るので出来なくはない)
ということで kakasi.dllと環境変数の設定は Delphiの場合は面倒ですが必要となります。
例外)
辞書ファイル(kanwadict/itaijidict)が 'c:\kakasi\share\kakasi\' の中にある場合は環境変数が設定されていなくても動作します。
それ以外の場所にある時は環境変数で設定する必要があります。
kakasi.dllはアプリと同じディレクトリにある場合にはパスが設定されていなくても構いません。
つまり辞書が "c:\kakasi\share\kakasi\' にあり kakasi.dll がアプリと同じディレクトリにある場合はkakasi関連の設定はせずとも動作します。
返信が遅くなり大変申し訳ありません!
またまた懇切丁寧に教えて頂きありがとうございます。
説明が非常に分かり易いため、思った通りの環境を簡単に構築することが出き感謝してます。
ありがとうございました。