キャレット問題

これも、ぎょえの時点から抱えてきた問題である。
キャレットは、テキスト入力位置が点滅するって言う当たり前の機能のことね。
当たり前の機能なのだが、キャレットを持つウィンドウってほとんどOS標準なもので、
自作のエディタウィンドウにキャレットを表示するやり方は解説が少なく手探り状態。
そもそも自前でキャレット表示する必要があるのは、テキストエディタのみだから、
さいわいTEditorというサンプルはある物の、他に常套手段みたいな物をみつけられない。
そのことについて。

CreateCaretとDestroyCaretで、好みの形のキャレットを作成&破棄する。
CreateCaretを何度も呼んだとしても、前回のキャレットを破棄して作るだけ。
フォーカスを持ったときのみCreateし、フォーカス消失時にDestroyしろってさ。
ま、そのルールは守れないのだが。
さらにこれとは別にShowCaretとHideCaretってのがあって、
Showした回数からHideした回数が引かれ、プラスの時だけキャレット表示するってさ。
CreateしててもShowがプラスにならないと非表示っていう感じだな。
そういう仕様なので、フォーカス取得と同時にCreateしてShow、
フォーカス消失時にHideしてDestroyって感じで簡単に済めば良かったんだがな。

フォントの大きさを変えればキャレットの大きさも変更するから再作成しなきゃいけないし、
ドラッグドロップが来たら非アクティブでもマウスの位置について行かなきゃいけない。
TEditorのドラッグドロップ拡張では、フォーカス無いのにあるかのようにみえるバグがあるし、
逆に消すタイミングを誤ると、よそのウィンドウのキャレットまで消しちゃったりするし、
何が起こってるのか謎で、キャレットをどう扱うかはずっと悩んできたこと。

付け焼き刃だが、MSDNでフォーカスがあるときだけキャレット表示しろとあるから、
真魚の場合はドラッグドロップでマウスが来た瞬間に無理矢理フォーカスを取得していた。
これでフォーカスが入ってきたときと出ていったときだけ処理するのでうまくいっていた。
でも、フォーカスだけ取得すればいいのにZオーダーも取得しようとするらしく、
マウスが真魚のウィンドウに通りかかっただけで前面に来る動作がウザかったりした。
よく、ドラッグドロップが来たら勝手に最前面に出るソフトってあるけど、
真魚の場合はそのように動作させたくてわざとやってるのではなく、
キャレットが思い通りの動作をしてくれなくて、仕方なく最前面に出てただけね。

で、意図しない動作をし続けていることにイライラが募ってきたので、思い切ってメスを入れた。
何が原因でどんな不具合が起こっていたのかすらつかめない状態のまま、
なんとなく修正いれ続けたら、ようやく好みの動作になった。
本当にたぶんだけど、CreateCaretは前回作成したキャレットを削除して再作成するが、
もう一回ShowCaretをしないと表示はされず、
内部で数えているShowやHideの回数に矛盾を来すっていう事だったんだと思う。
Createを呼ぶ前に、合計0になるまでHideして置かないといけないってことで解決。
これで、ドラッグドロップ時に無理矢理フォーカスを奪う動作をやめられる。
よかったよかった。

B00092QW4M
B00092QW4M

たぶん関連のある記事:

コメントは終了しています。