[delphi-users:2995] IME、文字変換の状態を取得したい

420 views
Skip to first unread message

じゃぺ

unread,
Feb 5, 2013, 3:28:07 AM2/5/13
to delphi...@freeml.com
川上です
連投になりますが、お知恵を拝借したく ^^;

フォーム上でF7を画面の移動に割り当ててるんですが、(これは変えたくない)
カナ変換しようとすると画面が切り替わってしまうため、変換中の場合は
F7での画面移動を無効にする方法を探しています。


とりあえず変換中の状態を取得しようとこちら↓を参考にコードを書いてみたの
ですが
http://leed.issp.u-tokyo.ac.jp/~takeuchi/delphi/browse.cgi?index=072207
現在フォームにはTEditが無数に(10~100くらい)あるため、
それぞれに対して
OriginalProc := Memo1.WindowProc;
Memo1.WindowProc := MemoSubclassProc;
のようなコードをかかずにできないか、と考えています。


配列を使おうとしましたが、

procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
setlength(OriginalProc,ComponentCount);
for i := 0 to ComponentCount-1 do begin
if(Components[i] is TEdit) then begin
x:=i;
OriginalProc[i] := TEdit(Components[i]).windowProc;
TEdit(Components[i]).WindowProc := SubclassProc;
end;
end;
KeyPreview:=True;
end;

procedure TForm1.SubclassProc(var Msg: TMessage);
begin
case Msg.Msg of
WM_IME_ENDCOMPOSITION:begin
label1.Caption:= '1';
end;
WM_IME_COMPOSITION:begin
label1.Caption:= '0';
end;
end;
OriginalProc[x](Msg); // 多分ここが正しくない
end;
のxところで躓いてしまいました。(OS機能呼び出しの失敗)


よろしくお願いします。



MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
使い方はいろいろ♪一部のメンバーだけにMLメールを送ろう!
http://ad.freeml.com/cgi-bin/sa.cgi?id=j2fDE
------------------------------------------------------[freeml byGMO]--

hosokawa

unread,
Feb 5, 2013, 4:34:52 AM2/5/13
to delphi...@freeml.com
川上さん
こんばんは。

細川です。

全ての Edit に対して、SubClass 化して~というのは大変だと思います。

SetWindowsHookEx の WH_CALLWNDPROC フックを使うのはいかがでしょう?
簡易ですが、↓ Unit を作ってみました。

https://github.com/freeonterminate/delphi/blob/master/uIMEStartEnd.pas

使い方は簡単です。

uIMEStartEnd を uses して AddIMEEventListener でイベントハンドラを設定します。
そうすると、IME の開始・終了で、設定したイベントハンドラが呼ばれます。


-----------------------------------------------------------------------------
■例

uses
uIMEStartEnd;

procedure TForm1.FormCreate(Sender: TObject);
begin
// イベントハンドラ設定
AddIMEEventListener(IMEEventHandler);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
// イベントハンドラ削除
RemoveIMEEventListener(IMEEventHandler);
end;

procedure TForm1.IMEEventHandler(const iWnd: HWND; const iStart: Boolean);
begin
// iStart が True の時、IME 変換開始
// iWnd には対象の Window Handle が入っている

if (iStart) then
Writeln('START')
else
Writeln('END');
end;

-----------------------------------------------------------------------------


ちなみに、川上さんの現状のソースをざっと見た感じ、x の中身がどうなってるのか判
らないので、何が間違えているのか判らないです。

それでは。
Regards,
HOSOKAWA Jun
[S/G] SERIALGAMES Inc.
TEL: 03-5812-0980
FAX: 03-5812-0970
twitter: http://twitter.com/serialgames
twitter: http://twitter.com/flaver_sg
mailto: j...@serialgames.co.jp
fla:ver http://flaver.jp/
WebCapS http://www.serialgames.co.jp/fun.html#WebCapSeria


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
メンバーで使える掲示板を活用しよう!
http://ad.freeml.com/cgi-bin/sa.cgi?id=j2gKB
------------------------------------------------------[freeml byGMO]--

じゃぺ

unread,
Feb 5, 2013, 4:48:54 AM2/5/13
to delphi...@freeml.com
細川様

ありがとうございます。
早速確認させて頂きます。

> ちなみに、川上さんの現状のソースをざっと見た感じ、x の中身がどうなってるのか判
> らないので、何が間違えているのか判らないです。

FormCreateで
x:=i;として、その下で
OriginalProc[i] := TEdit(Components[i]).windowProc;
TEdit(Components[i]).WindowProc := SubclassProc;
を実行しているので、xにiを入れたその都度、
SubclassProcの最後のOriginalProc[x](Msg);
にxが入って実行されると思ったのですが違ったようです。
(実際はFormCreateがすべて終わってからSubclassProcが
動いていました。)

取り急ぎ御礼まで
MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
メールだけでみんなを招待できる便利機能♪
http://ad.freeml.com/cgi-bin/sa.cgi?id=j2gYl
------------------------------------------------------[freeml byGMO]--

じゃぺ

unread,
Feb 5, 2013, 4:51:34 AM2/5/13
to delphi...@freeml.com
ちなみに、
FInImeComposition
http://docwiki.embarcadero.com/Libraries/XE2/ja/Vcl.Controls.TWinControl.FInImeComposition
というものを見つけ、
if(Edit1.FInImeComposition)then begin
といったコードを書いたところ、
「プロテクトシンボル TWinControl.FInImeComposition にアクセスできません」
というエラーがでてコンパイルできませんでした。

これはDelphi2007,XEでは使えないというわけではなく、
派生とか、継承とかそういった(この辺りニガテです・・・)
ことが必要なのでしょうか。

川上


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
練習や試合の予定調整は「とっとと決め太郎」におまかせ!
http://ad.freeml.com/cgi-bin/sa.cgi?id=j2haD
------------------------------------------------------[freeml byGMO]--

hosokawa

unread,
Feb 5, 2013, 5:03:09 AM2/5/13
to delphi...@freeml.com
川上さん

細川です。

x := i のコードを見落としていました。
これでは、ダメです。
最終的に x の中身は最後に見つかった TEdit のインデックスになるので、配列になっ
ている意味が全くありません。


FInImeComposition は可視性が protected なので、どうしても参照したいのであれば

type
TDummyEdit = class(TEdit);

と新しい Edit クラスを定義して

TDummyEdit(Edit1).FInImeComposition とすれば見られます。

これらを使うよりは、uIMEStartEnd.pas を使った方が簡単だと思います……。



On Tue, 5 Feb 2013 18:48:53 +0900 (JST)
毎日豪華プレゼントキャンペーン開催中!くまポン
http://ad.freeml.com/cgi-bin/sa.cgi?id=j2hmF
------------------------------------------------------[freeml byGMO]--

じゃぺ

unread,
Feb 5, 2013, 5:52:59 AM2/5/13
to delphi...@freeml.com
細川様
ありがとうございます。

DelphiXEで試したところ、
interface
uses
// Winapi.Windows; を
Windows; に

implementation
uses
// Winapi.Messages, Vcl.Controls, System.Generics.Collections; を
Messages, Controls, Generics; に変更したところコンパイルが通り、
希望通りの動作が実現しましたが(usesの変更は)問題ないでしょうか。

さらに、これはDelphi2007で実行することは厳しいでしょうか。
(System.Generics.Collectionsが無さそうですね)


また、FInImeComposition についても解説ありがとうございます。
新しいクラスを定義すれば使えるのですね。


(2013/02/05 18:34), hosokawa wrote:
MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
いつでもどこでもメールチェック!freemlのスマートフォンアプリ
http://ad.freeml.com/cgi-bin/sa.cgi?id=j2hVA
------------------------------------------------------[freeml byGMO]--

hosokawa

unread,
Feb 5, 2013, 10:13:16 AM2/5/13
to delphi...@freeml.com
川上さん
こんばんは。
細川です。

そのように変えても、何ら問題ないです。

また、Generics は、単にイベントハンドラを管理するためだけに使っているので、
Delphi 2007 では、普通の TList を使うようにしてみてください。
具体的には

現)GHandlers: TList<TIMEStartEndNotifyEvent>;
改)GHandlers: TList;

現)GHandlers := TList<TIMEStartEndNotifyEvent>.Create;
改)GHandlers := TList.Create;

こんな感じです。
他にも、for in 文の所とかも変える必要があります。


On Tue, 5 Feb 2013 19:52:58 +0900 (JST)
--
HOSOKAWA Jun <j...@serialgames.co.jp>


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
かわいいベジモンがたくさん!自分だけの農場を作ろう!
http://ad.freeml.com/cgi-bin/sa.cgi?id=j2lHL
------------------------------------------------------[freeml byGMO]--

hirodel

unread,
Feb 8, 2013, 4:43:30 AM2/8/13
to delphi...@freeml.com
お世話様です 加藤です
FastReport4.0に乗り換えテストしてます
(QuickReportの場合)
procedure TQrNewMitumori.QRDBText11Print(sender: TObject;  var Value: String);
begin
if Value='0' then
  Value:='';
end;
FastReport4.0でも同じ事をしたいのですが出来るのでしょうか?

hirodel

unread,
Feb 20, 2013, 10:14:07 PM2/20/13
to delphi...@freeml.com
加藤です
Windows7
DelphiXE_ent
 
TStringGridの
DrawCellでカラム内の左右寄せをしています
クラシックテーマではうまく行きますが
Aeroテーマなどにすると[0]カラムと「0,1」セルだけがダブリ文字になってしまいします
 
with StringGrid1 do
  begin
    begin
     //カラム内の左右寄せ
     if ACol in [1] then
     begin
      Canvas.FillRect(Rect);
      Rect.Right := Rect.Right - 3;
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_LEFT OR DT_VCENTER OR DT_SINGLELINE);
     end
     else
     begin
      Canvas.FillRect(Rect);
      Rect.Right := Rect.Right - 3;
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_RIGHT OR DT_VCENTER OR DT_SINGLELINE);
    end;
 
    end;
 
宜しくお願い致します。
Reply all
Reply to author
Forward
0 new messages