サイズ変更や色変更等のため、CListBoxをオーナードローしています。
基本的には、CListBoxの動作を踏襲したいのですが、
枠線の描画で困っている点があるので質問させてください。
void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDC dc;
dc.Attach(lpDIS->hDC);
if ( lpDIS->itemAction & ODA_FOCUS )
{
dc.DrawFocusRect(lpDIS->rcItem);
}
dc.Detach();
}
このようにすると、フォーカスを当てるだけで点線枠がついてしまいます。
標準のCListBoxは、フォーカスしただけでは点線枠はつかず
AltキーやTabキーを押すと点線枠が付くようになります。
AltキーやTabキーが押された場合だけ点線枠を付けるには
どうしたら良いでしょうか?
Alt/Tabキーイベントを見てフラグ立てるしか無いでしょうか?
itemActionではなくitemStateで見ても同じですか?
https://msdn.microsoft.com/ja-jp/library/92fhtw0f.aspx
の説明より
「ItemState メンバーは、コントロールにフォーカスがあるかどうかを判断する場合にチ
ェックします。」
itemState は駄目ですね。
DrawFocusRect()はフォーカス枠線の描画と削除を兼ねているので
itemState の「フォーカスがある時」だけ行うと
「フォーカスが消えた時」に処理が走らず
枠線が消えなくなってしまいます。
AltキーやTabキーが押された後の
「フォーカス枠線を表示しなければならない」という状態が
フラグか何かで取得できれば良いのですが
今のところ見つからず困っています。
Win標準のCListBoxはそのような動きが出来ているので、
中身はどうやっているんでしょう・・・
http://www.softist.com/programming/draw-combo/draw-combo.htm
私はここを参考に作成していたのですが、
MSDNの内容と異なるようですね。
// Focus
if (lpDrawItemStruct->itemAction & ODA_FOCUS)
pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
MSDNの記述方法でも試してみましたが、
結果は変わりませんでした。
フォーカス時、Alt/Tabキー押す前でも枠が付いてしまいます。
>フォーカス時、Alt/Tabキー押す前でも枠が付いてしまいます。
他のウインドウ等が重なったり、他のウインドウの作業をしても、
フォーカスになるkとがあります。
状況によって変わるのでむずかしいですね。
修正です。
>フォーカスになるkとがあります。
フォーカスになることがあります。
MSDNは
// If this item has the focus, draw a red frame around the
// item's rect.
if ((lpDrawItemStruct->itemAction | ODA_FOCUS) &&
(lpDrawItemStruct->itemState & ODS_FOCUS))
{
CBrush br(RGB(255, 0, 0));
dc.FrameRect(&lpDrawItemStruct->rcItem, &br);
}
ってなってますけど
// If this item has the focus, draw a red frame around the
// item's rect.
if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&
(lpDrawItemStruct->itemState & ODS_FOCUS))
{
CBrush br(RGB(255, 0, 0));
dc.FrameRect(&lpDrawItemStruct->rcItem, &br);
}
ですよね(^^;)
今ちょっと時間がなくて検証できず、ごめんなさい
http://lhsp.s206.xrea.com/misc/ownerdraw.html
これをみるとitemStateに追加情報が。
ODS_NOFOCUSRECTあたりではじけないかなあ
(このビットが立っていたら枠を描かない)。
教えていただいた内容で、期待通りの動作が実装できました。
ありがとうございます!
if ( (lpDIS->itemAction | ODA_FOCUS) &&
(lpDIS->itemState & ODS_FOCUS) &&
!(lpDIS->itemState & ODS_NOFOCUSRECT) )
{
pDC->DrawFocusRect(rcItem);
}
しかし、同じ英語のMSDNでも、DRAWITEMSTRUCTの内容が異なりますね。
https://msdn.microsoft.com/en-us/library/92fhtw0f.aspx
https://msdn.microsoft.com/en-us/library/ms673121.aspx
前者がComboboxと関係ないという訳でも無さそうですし・・・
ちゃんと書いておいて欲しいですね。
解決チェック付け忘れました