いつもお世話になってます、PATIOです。
WinXP(SP2)、IE6、VisualStudio2005 SP1の環境で
MFCを使用したアプリケーションを作成しています。
プロジェクトは「MFC アプリケーション」のSDIです。
CFormViewを使用しており、Viewには自作のコントロールと
プッシュボタン、スライダーバーを配置しています。
このViewを親にしてモーダルダイアログを表示しているのですが、
このダイアログ上に配置しているリストコントロールで表題の
現象が起きています。
選択状態でない場合は、アイコンが表示されています。
ところが選択状態になるとアイコンの部分がちょうどアイコンのサイズで
真っ白になってしまい、アイコンが見えなくなると言う現象が起きています。
リストコントロールはレポート形式に設定しており、
OnInitDialogで拡張スタイルのLVS_EX_FULLROWSELECT、LVS_EX_SUBITEMIMAGES、
LVS_EX_GRIDLINESを設定しています。
アイコンをプログラム内部で自動生成している部分があったので
その部分を外してみましたが、状況は変わりませんでした。
リソースから読み込んだアイコンを使っても状況は変わりません。
簡単なテストプログラムでは問題なく表示されているので
親ウインドウ等の周りの影響ではないかとうたがっています。
テストプログラムとの違いは親ウインドウに自作のコントロールが
貼り付けられており、これがGDI+を使って描画を行なっているという
事くらいです。
自分でも調査を続けていますが、何か有効な情報があればと思い、
書き込んでいます。
同様の現象に合われた方がいらっしゃいましたら、ぜひアドバイスをお願いします。
その後の調査でわかった事を幾つか。
全く新規にプロジェクトを起こして自作コントロール等を
配置したCFormViewからリストコントロールが乗っかっている
ダイアログを表示させましたが、アイコンの表示に問題は
起こりませんでした。
GDI+を疑っていましたが、どうやら見当違いだったようです。
色々試していますが、未だに原因は掴めていません。
こういう状況は今まで無かったので原因がわかっていません。
全く同じでなくても似たような体験をされた方がいらっしゃいましたら
ぜひ、情報をお願いします。
現状、雲を掴むような話で調査も思うような結果が出ていません。
追加情報。
常に選択状態を表示するように設定しているときにリストコントロールから
フォーカスが外れると選択色が灰色になりますが、この状態であれば、
アイコンは表示されています。
どうも、フォーカスがある状態の紺色で表示されているとアイコンが真っ白に
なって見えなくなってしまうようです。
正常に表示が出来ている場合は、アイコンの部分は網掛けのような感じで
アイコンが透けて見えるようになっていますが、この網掛けの部分が
真っ白になっていてアイコンが見えなくなっています。
アイコンはイメージリストを使って設定していると思いますが、
イメージリストを作成するときのパラメータに問題はないでしょうか?
レスありがとうございます。
現在のイメージリストの作成パラメータを以下に示します。
m_imgListは、ダイアログのメンバー変数でCImageListのインスタンスです。
m_imgList.Create(16, 16, ILC_COLOR32, 5, 5);
このパラメータで問題のプロジェクト以外ではきちんと表示されることが
確認できているのですが、変な部分があるでしょうか。
ちなみに内部でビットマップを生成してイメージリストを作成するロジックです。
CPaletteInfはパレットのRGB情報です。
m_paletteAraayは、CPaletteInfのCArrayでメンバー変数です。
m_lvwTestはCListCtrlのインスタンスでメンバー変数です。
CDC* pDC = GetDC();
CDC memDCMark;
CBitmap bmpMark;
CBitmap* pOldBmp;
CPen pen;
CPen* pOldPen;
CBrush brush;
CBrush* pOldBrush;
CRect rect(1, 3, 15, 13);
CPoint point(2, 2);
CPaletteInf inf;
int iLoop;
bmpMark.CreateCompatibleBitmap(pDC, 16, 16);
memDCMark.CreateCompatibleDC(pDC);
pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
pOldPen = memDCMark.SelectObject(&pen);
m_imgList.Create(16, 16, ILC_COLOR32, 5, 5);
for(iLoop = 0; iLoop < 16; iLoop++)
{
inf = m_paletteAraay[iLoop];
pOldBmp = memDCMark.SelectObject(&bmpMark);
memDCMark.FillSolidRect(CRect(0, 0, 16, 16), RGB(255, 255, 255));
brush.CreateSolidBrush(RGB(inf.GetRed(), inf.GetGreen(), inf.GetBlue()));
pOldBrush = memDCMark.SelectObject(&brush);
memDCMark.RoundRect(&rect, point);
memDCMark.SelectObject(pOldBmp);
memDCMark.SelectObject(pOldBrush);
brush.DeleteObject();
m_imgList.Add(&bmpMark, &bmpMark);
}
memDCMark.SelectObject(pOldPen);
m_lvwTest.SetImageList(&m_imgList, LVSIL_SMALL);
とりあえず、これでテストプログラム上では正常に動作しています。
原因が判明しました。
VisualStudio2005でMFCアプリケーションを選択し、ユニコードライブラリを
使わない設定にするとビジュアルスタイルのコントロールにならなくなります。
これに対する対策として追加のmanifestファイルを使う方法が以下の場所で
紹介されています。
MSDN フォーラム:XPでビジュアルスタイルが適応されない
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=270845&SiteID=7
この方法を使うと確かにビジュアルスタイルが使われるんですが、
その結果、リストコントロールのアイコンが選択時に見えなくなるようです。
追加のmanifestファイルをプロジェクトから外すとうまく行くようになりました。
とりあえず、MSDNフォーラムの方にも書き込んでおこうと思います。
MSDN フォーラムの方でやり取りがあったのでこっちにも展開しておきます。
まあ、あちらを見てもらえばやり取りも含めて読めますので簡単に書いておきます。
結局の話、追加のmanifestファイルの設定によって使用対象になるcomctl32 v6が
マルチバイトに対応した物では無いのでそもそも無理やり使っているのであり、
不具合が起こってもおかしくない状況であると言うことみたいです。
なので、基本的にマルチバイトで組む場合は、ビジュアルスタイルの適応は諦めるべき
という事になりそうですね。
単純なツールだけならこれでも良いんですけれど、
アプリになってしまうと使用しているライブラリにマルチバイト用の物がある場合も
あるのでけっこう厳しいかもしれません。
解決済みですがイメージリストの作成パラメータを
ILC_COLOR24に代えたらビジュアルスタイルを適用しても表示されました。
comctl32 v6を無理やり使っている状況は変わりませんが。
貴重な情報をありがとうございます。
もし使う機会があれば試してみようと思います。