none
Windows10 2004 以降のMicrosoft IMEで発生するフリーズについて RRS feed

  • 質問

  • Windows10 2004 以降で提供されている新しい Microsoft IME(日本語または中国語)を
    使用すると、一部のアプリでフリーズが発生します。

    状況としては以下の通りです。(20H2 の最新版でも状況は変わらず)

     ・マウス、キー入力を全く受け付けなくなる
     ・ビジー状態にはなっていない
     ・タスクバーからアプリを終了することは可能

    自作のアプリでも発生するため、原因を調査したところ、GetMessageを使用したメッセージループで、
    以下のIDのメッセージをDispatchMessageしなかった場合にフリーズが発生することを確認できました。

     メッセージID:96(0x0060)
     メッセージID:49223(0xC047)

    ただ、何のメッセージかは調べてもわかりませんでした。

       ※逆アセンブル上で追跡したところウィンドウプロシージャまで処理が進んでいなかったので、
        アプリ側では何もしていない可能性が高いです。

        フリーズ中に何度も発行されていたので、IME内部で何らかのリトライ処理を
        繰り返してるのではと推測しています。

    出来ればIMEの不具合として修正してほしいですが、いつになるかわからないため、
    プログラム側での修正を行おうとしています。

    以下の点について、何か情報をいただけると助かります。

     ・メッセージ96/49223 が何のメッセージか
     ・他にDispatchMessageしないとフリーズするメッセージはないか

       ※質問先を間違えている場合はご指摘ください。

    • 編集済み ff221 2020年11月2日 5:50
    2020年11月2日 5:47

すべての返信

  • GetMessage で取り出しておいて、なかったことにするという方がアプリケーションとして致命的のように思えますが…。

    https://docs.microsoft.com/ja-jp/windows/win32/winmsg/wm-app

    0 ~ WM_USER - 1 は System message です。
    定義されている内でご自身で処理したい場合は処理すれば良いと思いますが、そうでないものは握りつぶしてはならないでしょう。

    0xC000 ~ 0xFFFF は RegisterWindowMessage で登録されたものです。
    値は状況によって変わりますので、その値自体に特別な意味はありませんが、登録されたメッセージが処理されないことによって、うまく動かないものが出てきても文句は言えません。

    GetMessage は受け取りたいメッセージの範囲をフィルターできるので、特定メッセージしか処理しないなら引数でそのレンジを指定するべきでしょう。

    2020年11月2日 12:29
    モデレータ
  • アドバイスありがとうございます。やはりDispatchMessageしないことに問題があるのですね。
    今まで問題なく動作していたため気にしていませんでした。

    GetMessage のフィルターの場合、離れた範囲の指定が難しいですが、
    対応方法できなくはなさそうなので、試してみます。
    2020年11月2日 14:10
  • Azuleanさんの回答に少し付け加えさせていただくと、

    GetMessage()を繰り返す、いわゆる「メッセージループ」の実装では、
    取得した全てのメッセージについて、TranslateMessage()、およびDispatchMessage()を実施すべきです。
    既知でないメッセージについては特に「重要」です。
    加えて、メインのコールバック関数で処理対象としなかったメッセージについてはすべて、
    デフォルトプロシージャ
    DefWindowProc()に渡さなければなりません。

    コールバックの戻り値が評価されず、かつ、
    DefWindowProc()が何もしない事が知られている一部の既知のメッセージにおいては、結果としてGetMessage()直後に無かったことにすることは可能ですが、極力そうしないで実装するべきだと考えます。


    2020年11月4日 1:21