Windows XP SP3 + Visual Studio 2008 C++
で、リストビューを使用したダイアログベースのソフトを作っています。
リストビューには、ファイル名、ファイルサイズ、最終更新日時を「詳細」で表示させています。(よくあるファイル一覧です。)
エクスプローラと同じように、ファイル名等のテキストを
NTFS の圧縮ファイルは青
暗号化ファイルは緑
で表示させようと思い、カスタムドローを使用しています。
また、圧縮でもなく暗号化でもないファイルに対しては、ChooseFont() で選択された色 ( CHOOSEFONT 構造体の rgbColors ) を設定しています。
ChooseFont() で選択した色のうち、濃紺以外の色は問題なく表示されているのですが、なぜか、ChooseFont で濃紺 ( 0x00800000 ) を選択した場合だけ、第一列 ( ファイル名 ) のみ濃紺になり、第二列目以降 ( ファイルサイズ、最終更新日時 ) が、システム設定値 ( 黒 ) となります。
しかも、リストビューのスタイルを拡張スタイルの
LVS_EX_FULLROWSELECT ( 行選択モード? )
にすると、濃紺の場合でも、第二列目以降も正常に表示されます。
コーディングは、カスタムドローの部分だけを抜粋すると以下のような感じになっています。
LPNMLVCUSTOMDRAW pnmlvcd;
LVITEM lvi;
DWORD dwAttributes;
switch( message ) {
case NM_CUSTOMDRAW:
pnmlvcd = ( LPNMLVCUSTOMDRAW )lParam;
switch( pnmlvcd->nmcd.dwDrawStage ) {
case CDDS_PREPAINT:
SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_NOTIFYITEMDRAW );
return( TRUE );
case CDDS_ITEMPREPAINT:
lvi.mask = LVIF_PARAM;
lvi.iSubItem = 0;
lvi.iItem = pnmlvcd->nmcd.dwItemSpec; // 描画しようとしている行のインデックス
if( ListView_GetItem( hwndList, &lvi ) ) {
// 属性を取得
// lvi.lParam はファイルの情報を格納した構造体 FILEITEM へのポインタです。
dwAttributes = ( ( PFILEITEM )lvi.lParam )->dwAttributes;
if( 通常ファイルの場合 ) { // dwAttributes を使用して属性を判定
// ChooseFont で選択した色を設定
pnmlvcd->clrText = cfList.rgbColors;
SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_DODEFAULT );
return( TRUE );
} else if( 圧縮ファイルの場合 ) { // dwAttributes を使用して属性を判定
// 青
pnmlvcd->clrText = RGB( 0, 0, 0xff );
SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_DODEFAULT );
return( TRUE );
} else if( 暗号化ファイルの場合 ) { // dwAttributes を使用して属性を判定
// 緑
pnmlvcd->clrText = RGB( 0, 0xff, 0 );
SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_DODEFAULT );
return( TRUE );
}
}
}
break;
hwndMain はダイアログのウィンドウハンドル、hwndList はリストビューのウィンドウハンドルです。
(見やすくするため、スペースに全角スペースを使用しています。また、属性の判定部分は実際には dwAttributes との、&、| を使用しています。)
コーディング的には、ChooseFont() で何色が選択されようが知ったこっちゃないという感じなのですが・・・。
試しに、ChooseFont() で選択した色ではなく、RGB( 0, 0, 0x80 ) を指定しても同様の現象でした。
濃紺の場合でも、LVS_EX_FULLROWSELECT でなくても第二列目以降が正しい色で表示されるようにする方法はないでしょうか。
このリストビューは Drag & Drop のソース側の機能も実装していまして、その影響で、LVS_EX_FULLROWSELECT だと、Drag 操作による複数行選択の操作が難しくなるので、LVS_EX_FULLROWSELECT は避けたいと考えています。
あるいは、上記のコーディングで、何かおかしいんじゃないかという部分がありましたら教えていただけませんでしょうか。
よろしくお願いします。
A 回答 (1件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
カスタムドロー、その辺りまで試したことはありませんが…
CommCtrl.hに
#if (_WIN32_IE >= 0x0400)
#define CDDS_SUBITEM 0x00020000
#endif
なんてのがありますが……
case CDDS_ITEMPREPAINT:
だけだと、CDDS_SUBITEMのビットが設定されている場合は対応できません…よね?
_WIN32_IEが0x0400以上に設定されている必要はあるかと思われますが…
case (CDDS_SUBITEM | CDDS_ITEMPREPAINT):
case CDDS_ITEMPREPAINT:
lvi.mask = LVIF_PARAM;
とかやってみたらどうなりますかね?
この回答への補足
早速の回答ありがとうございます。
CDDS_ITEMPREPAINT に対して CDRF_DODEFAULT を返すと、それ以降のサブアイテムに対しては「デフォルト」の処理が行われるようで、CDDS_SUBITEM | CDDS_ITEMPREPAINT のメッセージは送られてきませんでした。
CDDS_ITEMPREPAINT に対して CDRF_NOTIFYSUBITEMDRAW を返すように、
case CDDS_ITEMPREPAINT:
pnmlvcd->clrText = cfList.rgbColors;
・・・
SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_NOTIFYSUBITEMDRAW );
return( TRUE );
case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
pnmlvcd->clrText = cfList.rgbColors;
・・・
SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_DODEFAULT );
return( TRUE );
とすることで CDDS_SUBITEM | CDDS_ITEMPREPAINT の場合の処理が実行されるようになりました。(ブレークポイントを設定して確認しました。)
が、状況は変わりませんでした。
case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
なしの場合でも、ありの場合でも、濃紺以外の色でしたらサブアイテムも設定した色で表示されていますので、Microsoft のバグのような気がしてきました・・・。
エクスプローラだとどうなるのか試してみましたところ、エクスプローラでも同じ現象が確認できました。
エクスプローラは、標準の状態ではNTFS圧縮ファイル、NTFS圧縮フォルダを青 ( RGB( 0, 0, 0xff ) ) で表示しますが、
レジストリのキー
HKEY_CURRENT_USER\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer
に
"AltColor"=hex:00,00,80,00
を追加して、Windows を再起動したところ、エクスプローラでもファイル名のみが濃紺で、サイズなどの項目は黒になりました。
リストビューコントロールのバグなのか、私が使用しているシステムがおかしくなっているのかはわかりませんが、少なくとも、自作プログラムのバグでないことはわかりましたので、この質問は締め切らせていただきます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/06 17:46
- Visual Basic(VBA) 動かなくなってしまった古いVBAを動くようにしたい 8 2022/09/20 13:57
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- Visual Basic(VBA) エクセルのマクロについて教えてください。 7 2023/07/04 09:18
- Windows 10 この現象も、Microsoft Explorer のお粗末な仕様のためか? 2 2023/06/09 15:06
- Visual Basic(VBA) Excelのマクロコードについて教えてください。 1 2022/03/27 13:25
- Excel(エクセル) Excel VBAどこが間違ってますか? 4 2023/07/17 10:04
- その他(IT・Webサービス) ホームページにカウント数を表示する 2 2022/10/28 10:37
- Excel(エクセル) フォルダ内のワードファイルをPDFに一括変換するVBA 3 2023/06/09 16:51
- Visual Basic(VBA) マクロVBA 1シートをまとめる 閉じ方 初心者 SOS! 1 2022/06/17 14:54
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
#include <Windows.h>というヘ...
-
binファイルを解凍したいの...
-
アクセス 壊れた? 「ファイ...
-
バッチ処理で追記コピーしたい
-
ファイルが開かれているかどう...
-
既に開いているエクセルを閉じ...
-
実行ファイル(.exeファイル)...
-
Word VBA MSGBOX 内で降順表示
-
iniファイル
-
exeファイルをデータ転送サービ...
-
公文書のxmlファイルの開き方が...
-
「ブルーファイル」と「グリー...
-
jarファイル
-
frm、frxファイル
-
【VBA】EXCELブックを開かずに...
-
C言語---ファイルに出力したデ...
-
WININET.DLL FtpCommand(TYPE)...
-
.NETアプリを作ったときの .man...
-
reaper音声ファイルについて
-
ハッシュ値を取る時はファイル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
アクセス 壊れた? 「ファイ...
-
#include <Windows.h>というヘ...
-
Latexで図番号だけを「図1.1」...
-
binファイルを解凍したいの...
-
.NETアプリを作ったときの .man...
-
ファイル構造が破損しているフ...
-
2つのファイルのバイナリをコン...
-
CSSを1ページに1枚作るのって変...
-
Word VBA MSGBOX 内で降順表示
-
公文書のxmlファイルの開き方が...
-
jarファイル
-
バッチ処理で追記コピーしたい
-
自分で作成した重要ファイルを...
-
ファイルは何で構成されている...
-
exeファイルをデータ転送サービ...
-
リンクの張り付けかたを教えて...
-
exeファイルの中身を見る方法は...
-
参照するファイルをワイルドカ...
-
CRCが一致する確率
-
C言語---ファイルに出力したデ...
おすすめ情報