C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: IME入力中のキー入力を取得したい


(過去ログ 82 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■48585 / inTopicNo.1)  IME入力中のキー入力を取得したい
  
□投稿者/ やんまー (1回)-(2010/04/09(Fri) 01:33:57)

分類:[VB.NET/VB2005 以降] 

恐れ入ります。

IME入力中のキー入力を取得したいのですが、上手く出来ず困っています。

やりたい事はテキストボックスを2つ並べて
IMEで入力したら、もうひとつのテキストボックスにはおしたままのアルファベットを表示させたいのです。

【例】
 テキストボックス1:「あいうえお」
 テキストボックス2:「aiueo」


で、以下のようにWndProcメソッドを使ってみようと思ったのですが、
WM_IME_KEYDOWNやWM_IME_KEYUPはなにも反応が帰ってきません。


Protected Overrides Sub WndProc(ByRef m As Message)
Const WM_IME_ENDCOMPOSITION As Integer = &H10E
Const WM_IME_COMPOSITION As Integer = &H10D
Const WM_IME_KEYDOWN As Integer = &H290
Const WM_IME_KEYUP As Integer = &H291
'
MyBase.WndProc(m)
Select Case m.Msg
Case WM_IME_COMPOSITION
なにか処理
Case WM_IME_ENDCOMPOSITION
なにか処理
Case WM_IME_KEYDOWN
なにか処理
Case WM_IME_KEYUP
なにか処理
End Select
End Sub



WndProcを使う方法でも使わない方法でも構いません。
なにか方法はないでしょうか?

よろしくお願いいたします。
引用返信 編集キー/
■48586 / inTopicNo.2)  Re[1]: IME入力中のキー入力を取得したい
□投稿者/ Hongliang (596回)-(2010/04/09(Fri) 03:11:49)
2010/04/09(Fri) 03:13:41 編集(投稿者)

入力を受け取るコントロールの PreProcessMessage のオーバーライド(対象コントロールのクラスを派生させる必要があります)、または IMessageFilter.PreFilterMessage の実装で、m.Msg が WM_KEYDOWN(で、WParam が VK_PROCESSKEY)のときに Win32API の ImmGetVirtualKey 関数を使用すれば元のキーが取得できます。
// WM_IME_KEYDOWN を送るかどうかは IME 次第なのかな?

// ローマ字入力じゃなくてかな入力の場合の仕様、大丈夫ですか?
引用返信 編集キー/
■48599 / inTopicNo.3)  Re[2]: IME入力中のキー入力を取得したい
□投稿者/ やんまー (2回)-(2010/04/09(Fri) 12:34:53)
No48586 (Hongliang さん) に返信
> 2010/04/09(Fri) 03:13:41 編集(投稿者)
>
> 入力を受け取るコントロールの PreProcessMessage のオーバーライド(対象コントロールのクラスを派生させる必要があります)、または IMessageFilter.PreFilterMessage の実装で、m.Msg が WM_KEYDOWN(で、WParam が VK_PROCESSKEY)のときに Win32API の ImmGetVirtualKey 関数を使用すれば元のキーが取得できます。
> // WM_IME_KEYDOWN を送るかどうかは IME 次第なのかな?
>
> // ローマ字入力じゃなくてかな入力の場合の仕様、大丈夫ですか?


Hongliang 様

回答ありがとうございます。


PreProcessMessageとはこんな感じですかね??
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.preprocessmessage(VS.80).aspx

returnValue = instance.PreProcessMessage(msg)

のmsgが押されたキーなのですかね・・・

とりあえず試してみます!



> または IMessageFilter.PreFilterMessage の実装で、m.Msg が WM_KEYDOWN(で、WParam が VK_PROCESSKEY)のときに Win32API の ImmGetVirtualKey 関数を使用すれば元のキーが取得できます。

これは難しそうですね・・・

でも頑張ってみます!

どうしてもわからなかったらまたレスいたします。

よろしくお願いします。
引用返信 編集キー/
■48600 / inTopicNo.4)  Re[3]: IME入力中のキー入力を取得したい
□投稿者/ やんまー (3回)-(2010/04/09(Fri) 12:37:31)
あ、こちらなんですが、

> // WM_IME_KEYDOWN を送るかどうかは IME 次第なのかな?


IMEを使っていないときは単にkeypressで取れるので...


> // ローマ字入力じゃなくてかな入力の場合の仕様、大丈夫ですか?

あ!
そこまで考えていませんでした。
とりあえずそこは気にしないでOKです。

# た → q  でOKです ^^;
引用返信 編集キー/
■48604 / inTopicNo.5)  Re[3]: IME入力中のキー入力を取得したい
□投稿者/ Hongliang (597回)-(2010/04/09(Fri) 13:08:23)
> returnValue = instance.PreProcessMessage(msg)
>
> のmsgが押されたキーなのですかね・・・

いえ、違います。
「PreProcessMessage または PreFilterMessage」の中で、「m.Msg が WM_KEYDOWN で WParam が VK_PROCESSKEY のとき」に、「Win32API の ImmGetVirtualKey 関数を使用する」んです。
引用返信 編集キー/
■48642 / inTopicNo.6)  Re[4]: IME入力中のキー入力を取得したい
□投稿者/ やんまー (4回)-(2010/04/10(Sat) 23:08:59)
うー、うまくいきませんでした・・・


http://msdn.microsoft.com/ja-jp/library/ms171537.aspx

のあたりを参考にして、
とりあえず、IME入力中のキー入力に反応出来るかを試してみたのですが・・・

protected Overridable sub PreProcessMessage (ByRef m As Message )
Const WM_IME_KEYDOWN As Integer = &H290
Const WM_IME_KEYUP As Integer = &H291

MyBase.PreProcessMessage(m)
Select Case m.Msg
Case WM_IME_KEYDOWN
処理
Case WM_IME_KEYUP
処理
End Select
End sub


見よう見まねでこのように書いたのですが、
やはり反応ありませんです・・・


引用返信 編集キー/
■48674 / inTopicNo.7)  Re[5]: IME入力中のキー入力を取得したい
□投稿者/ やんまー (5回)-(2010/04/12(Mon) 12:52:04)
頭を冷やしてリベンジしました。

  Public Overrides Function PreProcessMessage (ByRef m As Message ) As Boolean
   msgbox("キーが押された!")
   Return MyBase.PreProcessMessage(m)
  End Function

で、反応できることを確認しました。
で次に、

   Dim keyCode As Keys = CType(m.WParam, Keys) And Keys.KeyCode
   msgbox(keyCode.ToString())

としてみました。
すると・・・VK_PROCESSKEY ・・・とかでました!ので、
おおおお!あとは「「Win32API の ImmGetVirtualKey 関数を使用する」」だけだーと思ったのですが、詰まってしまいました。

ググッてみたところ
http://vsug.jp/tabid/63/forumid/48/threadid/3485/scope/posts/Default.aspx
がありまして、

f (msg.Msg.Equals(WM_KEYDOWN)) {
if (msg.WParam.ToInt32().Equals(VK_PROCESSKEY)) {
int key =int Win32.ImmGetVirtualKey(this.Handle);
if (key.Equals(VK_Add)) {
IntPtr Imc = (IntPtr)Win32.ImmGetContext(this.Handle);
Win32.ImmReleaseContext(this.Handle, (int)Imc);
//目的の処理
return true;
}
}
てな感じでしたので、やってみたんですが、、、、VBの情報ってあまりないのですね。。。



とりあえず経過報告です。。。。



引用返信 編集キー/
■48679 / inTopicNo.8)  Re[6]: IME入力中のキー入力を取得したい
□投稿者/ Hongliang (599回)-(2010/04/12(Mon) 13:28:37)
> VBの情報ってあまりないのですね。。。
.NET 以後の VB は、C# と基本的に同じです。文法が違うだけ。
// 片方にしか存在しないフィーチャーもいくつかはありますが。
C# VB 変換 とかで検索すればコンバータも見つかります。慣れれば脳内でも簡単に変換できるようになります。

> IntPtr Imc = (IntPtr)Win32.ImmGetContext(this.Handle);
> Win32.ImmReleaseContext(this.Handle, (int)Imc);
これは、リンク先のさらにリンク先(ailight.jp の掲示板)を見に行くと分かりますが、ImmNotifyIME 関数を呼び出すのに必要な IME のコンテキストハンドルを入手するためのコードです。
コンテキストハンドルが不要ならわざわざ呼び出す必要はありません。
引用返信 編集キー/
■48684 / inTopicNo.9)  Re[4]: IME入力中のキー入力を取得したい
□投稿者/ 魔界の仮面弁士 (1609回)-(2010/04/12(Mon) 13:55:29)
No48604 (Hongliang さん) に返信
> 「PreProcessMessage または PreFilterMessage」の中で、「m.Msg が WM_KEYDOWN で WParam が VK_PROCESSKEY のとき」に、「Win32API の ImmGetVirtualKey 関数を使用する」んです。

書いてみました。

Public Class Form1
    Private WithEvents TextBox1 As Sample
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        TextBox1 = New Sample()
        Controls.Add(TextBox1)
    End Sub
    Private Sub TextBox1_VirtualKeyPressed(ByVal sender As Object, ByVal e As KeyEventArgs) Handles TextBox1.VirtualKeyPressed
        Debug.Print(e.KeyData.ToString())
    End Sub
    Private Class Sample
        Inherits TextBox
        Private Declare Function ImmGetVirtualKey Lib "imm32" (ByVal hwnd As IntPtr) As Keys
        Public Event VirtualKeyPressed As KeyEventHandler
        Public Overrides Function PreProcessMessage(ByRef msg As Message) As Boolean
            Const WM_KEYDOWN As Integer = &H100
            If msg.Msg = WM_KEYDOWN AndAlso msg.WParam = CType(Keys.ProcessKey, IntPtr) Then
                RaiseEvent VirtualKeyPressed(Me, New KeyEventArgs(ImmGetVirtualKey(Handle)))
            End If
            Return MyBase.PreProcessMessage(msg)
        End Function
    End Class
End Class

引用返信 編集キー/
■48782 / inTopicNo.10)  Re[7]: IME入力中のキー入力を取得したい
□投稿者/ やんまー (6回)-(2010/04/14(Wed) 13:42:13)
Hongliang さん

ありがとうございます!ご返信遅くなりまして申し訳ありません。


> C# VB 変換 とかで検索すればコンバータも見つかります。


そうなんですね!探してみます!



>>IntPtr Imc = (IntPtr)Win32.ImmGetContext(this.Handle);
>>Win32.ImmReleaseContext(this.Handle, (int)Imc);
> これは、リンク先のさらにリンク先(ailight.jp の掲示板)を見に行くと分かりますが、ImmNotifyIME 関数を呼び出すのに必要な IME のコンテキストハンドルを入手するためのコードです。
> コンテキストハンドルが不要ならわざわざ呼び出す必要はありません。


うう・・・

ちょっと難しいです。

勉強します。。。


引用返信 編集キー/
■48894 / inTopicNo.11)  Re[5]: IME入力中のキー入力を取得したい
□投稿者/ やんまー (8回)-(2010/04/15(Thu) 21:48:54)
魔界の仮面弁士 さま


ああ!
御丁寧にありがとうございます。
早速試させていただきます!!!!!


引用返信 編集キー/
■48895 / inTopicNo.12)  Re[6]: IME入力中のキー入力を取得したい
□投稿者/ やんまー (9回)-(2010/04/15(Thu) 22:59:59)
魔界の仮面弁士 さま


ありがとうございます!!!

ばっちり動作しました!

ちょっと意外だったのですが、大文字になるんですね?!?!


うまく出来る方法を教えていただいてうれしいです!
引用返信 編集キー/
■48897 / inTopicNo.13)  Re[7]: IME入力中のキー入力を取得したい
□投稿者/ 魔界の仮面弁士 (1624回)-(2010/04/15(Thu) 23:37:08)
No48895 (やんまー さん) に返信
> ちょっと意外だったのですが、大文字になるんですね?!?!

違います。
「文字入力」を拾っているわけでは無く、
「キー入力」を拾っている事に注意して下さい。


それぞれのキーからは、大文字/小文字/カナなどを入力できるわけですが、
わかるのは「どのキーが押されたのか」という事であり、それによって
どの文字が入力されたかという情報が取れているわけではありません。

その代わりに、矢印キー/ファンクションキー/変換キー/無変換キーなどといった
文字としては拾えないキー入力も拾うことができます。
引用返信 編集キー/
■48919 / inTopicNo.14)  Re[8]: IME入力中のキー入力を取得したい
□投稿者/ やんまー (10回)-(2010/04/16(Fri) 12:33:50)
皆様ありがとうございました。

解決です!!
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -