キャレットの作成と廃棄のタイミングは?

解決


ギャラ  2009-03-20 04:22:26  No: 69855

ここではお初になります、よろしくお願いいたします。
api で自作editコントロールの作成中にタイトル内容の疑問が
湧き上がりました。

自分で調べたところ、ウィンドウのフォーカスを得るか失うかで、
CreateCaret, DestroyCaret を実行すればよい事が分かりました。

ひらがな入力をされた場合、
文字変換ウィンドウが現れ、そこに、キャレットが表示されます。
(本当にキャレットなのかちょっと疑問)

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

と照らし合わせると、

WM_KILLFOCUS を受け取っていないけど、キーボードフォーカスは、
変換ウィンドウに移っているように見える。
(WM_KILLFOCUS が来ていないから、フォーカスは親のまま?)

フォーカスが2つ存在しているように見える。(親と変換ウィンドウに一つずつ)

の2点が、矛盾しているように感じます。
このことを考えるとキャレットを破棄したほうが良いのかどうか迷ってしまいます。
変換ウィンドウが現れたとき、どのように変化、または動作をしているか、
(自ずとキャレットをどう扱えば良いか分かる程度)ご教授お願いします。

もし、ここでキャレットを破棄する必要があるとしたら、
WM_IME_STARTCOMPOSITION を受け取って、破棄。
WM_IME_ENDCOMPOSITION を受け取って、生成。
で良いのでしょうか?

環境:
Visual Studio 2005


仲澤@失業者  2009-03-23 19:09:07  No: 69856

まず、キャレット(カレット)はメッセージキューに対して1つ作成
できるので、複数のキャレットが同時に存在するのは当たり前です。
2つ以上のキャレットが同時に表示されると、UI上好ましくないと
いうだけのことです。また、これはフォーカスの有り無しとも無関係に
作成破棄できてしまいます。従って、キャレットを保持する
アプリケーションは、Windowsの指針に従って
  1.フォーカスを失ったとき。
  2.アクティブでなくなったとき。
の両タイミング時にキャレットを「非表示」にすべきです。

次に、キャレットの破棄タイミングは、本来的には
  1.そのキャレットを使用している当該のメッセージキューが
      最後のメッセージを受け取る直前。
が理想的ですが、実際にはウインドウクラス自体は破棄されないため
(破棄を確認できないため)、当該のメッセージを利用しているHWND
毎に、作成、破棄を行うしかありません。結果的に
WM_DESTROYを受け取った瞬間ということになると思います。

さて、フォーカスの喪失もアクティブの喪失も通知されないまま
他のウインドウがキャレットの表示を開始した場合は、どの様に
するべきかは意見が分かれるところだと思いますが、自分は
  1.カレットは複数存在する場合がありえる
という立場から「何もすべきではない」と考えます。
参考になれば幸いです。


ギャラ  2009-03-24 04:44:25  No: 69857

非常に分かりやすい説明ありがとうございます。
キャレットが2つ以上あるとルール違反で、
何らかのバグを抱える可能性があるのではないかと不安でしたが、
おかげで解消出来ました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加