リストビューのカスタムドローについて
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 は避けたいと考えています。
あるいは、上記のコーディングで、何かおかしいんじゃないかという部分がありましたら教えていただけませんでしょうか。
よろしくお願いします。
お礼
貴重な情報ありがとうございました。 早速試してみます。