トップページ > 記事閲覧
マルチスレッド時のIME入力
名前:だんごさん 日時: 2013/12/28 01:33

DxLibがマルチスレッドに未対応ながら様々な関数を用意していただき、大変助かっております。 そこで要望があるのですが、マルチスレッドの時にIMEの入力もできないでしょうか? Http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1683 を参考に設定してみましたが、確かにCheckHitKeyなどの関数は正常に取得できますが、 MakeKeyInputなどで入力はできませんでした。 身勝手ながら、もし差支えなければIMEの対応、もしくは既に入力方法があるなら教えていただけないでしょうか? よろしくお願いします。
メンテ

Page: 1 |

Re: マルチスレッド時のIME入力 ( No.1 )
名前:管理人 日時:2013/12/30 21:20

すみません、マルチスレッドでIME入力というシチュエーションが思いつきません、 どのようなことをされようとしているのでしょうか? よろしければ「正常に動作しないマルチスレッドでIME入力をするプログラム」を 載せて頂けないでしょうか?
メンテ
Re: マルチスレッド時のIME入力 ( No.2 )
名前:だんごさん 日時:2014/01/03 19:48

それが…正常に動作しないIME入力が実装できないというか、今作っているソフトしか症状が出ないので… 以前(Http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=3186)の時のプログラムをマルチスレッドにしたもので入力処理を行っています。 それとマルチスレッドじゃないときは入力処理を試してないので、ただ単にプログラム自体に問題があるかもしれません。 ちょっと探ってみます。
メンテ
Re: マルチスレッド時のIME入力 ( No.3 )
名前:だんごさん 日時:2014/01/06 00:19

問題のコードをメールで送信いたしました。
メンテ
Re: マルチスレッド時のIME入力 ( No.4 )
名前:管理人 日時:2014/01/06 22:58

メールを拝見しました マルチスレッドは関係ありませんでした 頂いたプログラムではオリジナルのウインドウを作成してそれを SetUserWindow で 指定していますが、この場合ウインドウメッセージは全て自前で行う必要があります そして文字入力はウインドウメッセージの処理なので、その処理が WndProc にないので文字入力もできないというわけです 解決方法としては、WndProc に文字入力に対応するメッセージ処理を 入れるしかありません main.cpp の関数宣言の辺りに namespace DxLib { // IMEメッセージのコールバック関数 extern LRESULT IMEProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) ; } ; を記述を加えて、WndProc関数の switch( msg ) の中に // 文字コードメッセージ case WM_CHAR : // 文字をバッファにコピー if( wParam == 10 ) { StockInputChar( ( TCHAR )CTRL_CODE_CR ) ; } else { if( wParam >= 0x20 || wParam == CTRL_CODE_BS || wParam == CTRL_CODE_TAB || wParam == CTRL_CODE_CR || wParam == CTRL_CODE_DEL || wParam == CTRL_CODE_ESC || wParam == CTRL_CODE_COPY || wParam == CTRL_CODE_PASTE || wParam == CTRL_CODE_CUT || wParam == CTRL_CODE_ALL ) StockInputChar( ( TCHAR )wParam ) ; } break ; // IMEメッセージが来た場合は独自関数に渡す case WM_IME_SETCONTEXT : case WM_IME_STARTCOMPOSITION : case WM_IME_ENDCOMPOSITION : case WM_IME_COMPOSITION : case WM_IME_NOTIFY: return IMEProc( hWnd , msg , wParam , lParam ) ; という記述( DXライブラリ内部の文字入力関係のメッセージ処理をそのままコピー&ペーストしたもの )を 加えたところ文字入力ができましたので、よろしければお試しになってみてください
メンテ
Re: マルチスレッド時のIME入力 ( No.5 )
名前:だんごさん(解決) 日時:2014/01/07 00:48

無事入力ができました SetUseWindow関数を使っても入力はProcessMessage関数が処理しているのだと勝手に勘違いしていました。 いつもありがとうございます。
メンテ
Re: マルチスレッド時のIME入力 ( No.6 )
名前:だんごさん 日時:2014/01/07 23:09

すみません、少し質問があります。 DxLibの入力変換時に一覧が出る時と出ないときがありますが、あれは仕様なのでしょうか? 例えば、「時間差」や「迂闊」と変換しようとしても一覧が出ませんが、「封筒」や「蜜柑(みかん)」は出ます。 もしかしたら変換する文字は関係ないのかもしれないですが、 以前から何かと気になっていたので、追加で質問させていただきました。
メンテ
Re: マルチスレッド時のIME入力 ( No.7 )
名前:管理人 日時:2014/01/09 01:04

私の手元では「時間差」や「迂闊」も一覧が出てきます 何度かスペースキーで変換を繰り返していると出てくると思うのですが、 何度スペースキーを押しても一覧が出てこないのでしょうか?
メンテ
Re: マルチスレッド時のIME入力 ( No.8 )
名前:だんごさん 日時:2014/01/09 02:19

はい、私がDxLibに出会ってからずっとでした。 私は作る側でしたし、たまに表示するしそこまで気にしてませんでしたが、今回作成するソフトは自分専用なので…。 スペースキーを押すと、押すたびに変換されますが一覧が出ない状態です。(ログにエラーはありませんでした) それからSetUserWindowで自前で処理を行う場合、IMEのカーソル操作を矢印キーでできないものなんでしょうか? 矢印キーの操作ができないので処理を書き忘れたかと調べましたが分からず… 毎回質問だらけで大変申し訳ないです。ご迷惑おかけしますm(__)m
メンテ
Re: マルチスレッド時のIME入力 ( No.9 )
名前:管理人 日時:2014/01/11 15:25

> はい、私がDxLibに出会ってからずっとでした。 >  > 私は作る側でしたし、たまに表示するしそこまで気にしてませんでしたが、今回作成するソフトは自分専用なので…。 > スペースキーを押すと、押すたびに変換されますが一覧が出ない状態です。(ログにエラーはありませんでした) DXライブラリ側で想定していないタイミングで変換候補情報が変化しているのかもしれません 変換候補情報があるかどうかを常に画面に表示し続けるプログラムを作成してみましたので よろしければ実行してみてください https://dxlib.xsrv.jp/temp/ImmGetCandidateListTest.zip 起動すると文字入力状態になりますので、件の変換候補リストが出ない状態にしてみてください、 その際に画面下の「ImmGetCandidateList の戻り値 : 」の表示が 0 になっているかどうか教えて頂けないでしょうか? もし 0 になっていたらライブラリ側ではどうしようも無いのですが、0以外でしたら変換候補情報があるのに ライブラリが認識していないということなので対処のしようがあります > それからSetUserWindowで自前で処理を行う場合、IMEのカーソル操作を矢印キーでできないものなんでしょうか? > 矢印キーの操作ができないので処理を書き忘れたかと調べましたが分からず… すみません、WndProc に入れるべき処理が足りていませんでした、 WndProc に以下の処理を // キー押下メッセージ case WM_KEYDOWN: { int VKey = ( int )wParam ; char *CCode = ( char * )CtrlCode ; // コントロール文字コードに対応するキーが // 押されていたらバッファに格納する while( *CCode ) { if( *CCode == VKey ) { // バッファに文字コードを代入 StockInputChar( ( TCHAR )*( CCode + 1 ) ) ; break ; } CCode += 2 ; } } break ; あと前回追加して頂いた namespace DxLib { // IMEメッセージのコールバック関数 extern LRESULT IMEProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) ; } ; の部分に一行追加して namespace DxLib { // IMEメッセージのコールバック関数 extern LRESULT IMEProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) ; extern char CtrlCode[ 10 ][ 2 ] ; } ; にしてください、カーソル移動ができるようになります
メンテ
Re: マルチスレッド時のIME入力 ( No.10 )
名前:だんごさん 日時:2014/01/11 21:44

プログラムを実行してみました。 結果、一覧の出ない文字を変換してみましたが、0のままでした。 カーソルの件については無事動作しました。 ありがとうございます。
メンテ
Re: マルチスレッド時のIME入力 ( No.11 )
名前:管理人 日時:2014/01/12 01:32

0のままでしたか・・・ となるとOSが「変換候補を表示する必要が無い」と、してしまっているということになります 何かのAPIで「OSが変換候補を表示すべきとする条件」の設定を変更することができるかもしれませんが 時間が掛かりそうなのですぐに対応することはできません、すみません
メンテ
Re: マルチスレッド時のIME入力 ( No.12 )
名前:だんごさん(解決) 日時:2014/01/12 13:59

IMEでもそれぞれ条件が違うんですね。 一覧の対応はできなくとも変換がとりあえずできれば問題ないので大丈夫です。 ありがとうございました。
メンテ
Re: マルチスレッド時のIME入力 ( No.13 )
名前:koga2020 日時:2015/05/10 06:50

1年以上前の内容へのレスとなりすみません。 ここで管理人様が提示されている ImmGetCandidateListTest.exeですが、これを元に表示や操作を発展させたものを作りたいのです。 このexeですが、ソースを公開して頂くことはできますでしょうか? ゲームのキャラクタ移動の基本を元に、文字入力欄のキーリピートを模したものを作ろうとしたのですが、どうしてもリピートが微妙なものとなってしまっています。 参考にさせて頂けると助かります。
メンテ
Re: マルチスレッド時のIME入力 ( No.14 )
名前:管理人 日時:2015/05/10 11:43

ImmGetCandidateListTest.exe のソースは以下のようになっています #include "DxLib.h" #include "Windows/DxWinAPI.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { HWND hWnd ; HIMC Imc ; DWORD Size ; int InputHandle ; ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() == -1 ) return -1 ; hWnd = GetMainWindowHandle() ; // 描画先を裏にする SetDrawScreen( DX_SCREEN_BACK ) ; // 文字入力ハンドルを作る InputHandle = MakeKeyInput( 50 , FALSE , FALSE , FALSE ) ; // 作成した文字入力ハンドルをアクティブにする SetActiveKeyInput( InputHandle ) ; // メインループ while( ProcessMessage() == 0 ) { // 文字入力が終了している場合は再スタート&再アクティブ if( CheckKeyInput( InputHandle ) != 0 ) { ReStartKeyInput( InputHandle ) ; SetActiveKeyInput( InputHandle ) ; } // 画面の初期化 ClearDrawScreen() ; // 入力モードを描画 DrawKeyInputModeString( 640 , 480 ) ; // 入力途中の文字列を描画 DrawKeyInputString( 0 , 0 , InputHandle ) ; // 入力コンテキストを取得 Imc = WinAPIData.ImmFunc.ImmGetContextFunc( hWnd ) ; if( Imc != NULL ) { // 候補リストの情報を受け取るのに必要な容量を描画 DrawFormatString( 0, 232, GetColor( 255,255,255 ), "ImmGetCandidateList の戻り値 : %d ", WinAPIData.ImmFunc.ImmGetCandidateListFunc( Imc , 0 , NULL , 0 ) ) ; // 候補リストの数を描画 WinAPIData.ImmFunc.ImmGetCandidateListCountFunc( Imc, &Size ) ; DrawFormatString( 0, 248, GetColor( 255,255,255 ), "ImmGetCandidateListCount の引数 lpdwListCount に代入された値 : %d", Size ) ; // 入力コンテキストを解放 WinAPIData.ImmFunc.ImmReleaseContextFunc( hWnd, Imc ); } else { DrawString( 0, 248, "ImmGetContext 失敗", GetColor( 255,255,255 ) ) ; } // 裏画面の内容を表画面に反映させる ScreenFlip() ; } // 文字入力ハンドルをを削除する DeleteKeyInput( InputHandle ) ; // DXライブラリの後始末 DxLib_End() ; // 終了 return 0 ; } DXライブラリ内部のデータを使用していて、普通のDXライブラリのパッケージだけではビルドできません このプログラムは不具合を確認するためのテストコードで koga2020さんが求められているものとは大分異なると思います・・・
メンテ
Re: マルチスレッド時のIME入力 ( No.15 )
名前:koga2020 日時:2015/05/11 08:26

ソースを見せて頂きましてありがとうございます。 やりたいことはファイル選択のとき、ファイル一覧選択欄とファイル名欄の2つがあり、矢印キーはファイル一覧の選択位置移動、文字やBSキーはファイル名欄の文字編集、というようにしたいのです。 シューティングゲームで例えると、漢字入力をすると特殊機能が発動するゲーム(漢字入力中は弾を打てない制限あり)のようなイメージ・処理になると思います。 先ほど質問させて頂いたexeを実行してみたところ、これを参考にして左右の矢印で入力欄内のカーソル移動をしないタイプを作れれば・・・と思ってしまいました。 文字入力とBSキーのみが有効となるようなオリジナル入力欄を作るとしたら、一からいろいろ、例えばすべての入力キー別(256配列のもので)に処理を作り、キーリピートの管理を作るような感じだと思っっていましたので、既存の似たような処理があれば参考にできればと思いました。 先に見せて頂いたソースにあるMakeKeyInputやDrawKeyInputStringなどのライブラリの内部処理を参考にするのが、目的に近い感じに思いました。 もっと調べてみます。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存