CListBoxのオーナードロー時の枠線について – プログラミング – Home

CListBoxのオーナードロー時の枠...
 
通知
すべてクリア

[解決済] CListBoxのオーナードロー時の枠線について


古田
 古田
(@古田)
ゲスト
結合: 6年前
投稿: 6
Topic starter  

サイズ変更や色変更等のため、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キーイベントを見てフラグ立てるしか無いでしょうか?


引用未解決
トピックタグ
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

itemActionではなくitemStateで見ても同じですか?

https://msdn.microsoft.com/ja-jp/library/92fhtw0f.aspx
の説明より
「ItemState メンバーは、コントロールにフォーカスがあるかどうかを判断する場合にチ
ェックします。」


返信引用
古田
 古田
(@古田)
ゲスト
結合: 6年前
投稿: 6
Topic starter  

itemState は駄目ですね。

DrawFocusRect()はフォーカス枠線の描画と削除を兼ねているので
itemState の「フォーカスがある時」だけ行うと
「フォーカスが消えた時」に処理が走らず
枠線が消えなくなってしまいます。

AltキーやTabキーが押された後の
「フォーカス枠線を表示しなければならない」という状態が
フラグか何かで取得できれば良いのですが
今のところ見つからず困っています。

Win標準のCListBoxはそのような動きが出来ているので、
中身はどうやっているんでしょう・・・


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

https://msdn.microsoft.com/ja-jp/library/kc9hahtd.aspx

これを見る限りではitemActionとitemState両方見て判断のようですが…。


返信引用
古田
 古田
(@古田)
ゲスト
結合: 6年前
投稿: 6
Topic starter  

http://www.softist.com/programming/draw-combo/draw-combo.htm

私はここを参考に作成していたのですが、
MSDNの内容と異なるようですね。

// Focus
if (lpDrawItemStruct->itemAction & ODA_FOCUS)
pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);

MSDNの記述方法でも試してみましたが、
結果は変わりませんでした。
フォーカス時、Alt/Tabキー押す前でも枠が付いてしまいます。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

>フォーカス時、Alt/Tabキー押す前でも枠が付いてしまいます。
他のウインドウ等が重なったり、他のウインドウの作業をしても、
フォーカスになるkとがあります。
状況によって変わるのでむずかしいですね。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

修正です。
>フォーカスになるkとがあります。
フォーカスになることがあります。


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

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);
}
ですよね(^^;)
今ちょっと時間がなくて検証できず、ごめんなさい


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

http://lhsp.s206.xrea.com/misc/ownerdraw.html

これをみるとitemStateに追加情報が。
ODS_NOFOCUSRECTあたりではじけないかなあ
(このビットが立っていたら枠を描かない)。


返信引用
古田
 古田
(@古田)
ゲスト
結合: 6年前
投稿: 6
Topic starter  

教えていただいた内容で、期待通りの動作が実装できました。
ありがとうございます!

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と関係ないという訳でも無さそうですし・・・
ちゃんと書いておいて欲しいですね。


返信引用
古田
 古田
(@古田)
ゲスト
結合: 6年前
投稿: 6
Topic starter  

解決チェック付け忘れました


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました