環境
・VS2008
・MFC
検索でたどり着きました
http://rarara.cafe.coocan.jp/cgi-bin/lng/vc/vclng.cgi?print+201111/11110015.txt
の過去の内容を元に、チェックボックスをグレーアウトする事はできました。
しかし、Vistaや7ではチェック状態のグレーアウトが綺麗に表示されません。
(通常のグレーアウトと違って、もの凄く汚くグレーアウトしてしまう)
XPやVistaでのクラシック表示では綺麗に表示されるのですが、
この方法以外で綺麗にグレーアウトさせることはできないでしょうか?
かなり昔の記事ですが、お答え頂いた方、いらっしゃいましたら
ご教授お願いします
エアロでアイコン部分が汚いということでしょうか。
残念ながら、私にはエアロ環境がありませんので、試すことができません。
なぜ、あんな方法をとったのかというと、
イメージリストにグレイイメージを追加する方法を試したことがありますが、
そうすると、マウスでクリックしたときに、イメージが順に変わってしまう
(追加したグレイイメージも表示されてしまう)からでした。
NM_CLICKを細工すれば、イメージリスト追加のやり方でもできるのか、
あるいは、イメージリストを自力でグレイで描くか、
どなたか、ご助力願います。
「Windows Aero」 ではなく、「Windows Vistaベーシック」でも同じ現象が起こるので
Aeroは関係ないかもしれませんが、Vistaと7特有の問題みたいです。
過去ログの、
case CDDS_ITEMPOSTPAINT:
{
NMCUSTOMDRAW* nmcd = (NMCUSTOMDRAW*)lParam;
RECT rc;
ListView_GetItemRect(hwndListView, nmcd->dwItemSpec,
&rc, LVIR_ICON);
// state iconのrectを計算(ここはいい加減です)
rc.right = rc.left;
rc.left = 0;
// iconの上を灰色で塗る
SetROP2(nmcd->hdc, R2_MERGEPEN);
HGDIOBJ hOld = SelectObject(nmcd->hdc,
GetSysColorBrush(COLOR_GRAYTEXT));
Rectangle(nmcd->hdc, rc.left, rc.top, rc.right, rc.bottom);
SelectObject(nmcd->hdc, hOld);
}
break;
}
の
SelectObject(nmcd->hdc, GetSysColorBrush(COLOR_GRAYTEXT));
を
SelectObject(nmcd->hdc, CreateSolidBrush(RGB(180,180,180));
※RGB(180,180,180)はグレーウィンドウの色を計った値
としてみて、数値を変えてみましたがVista/7では何故か
RGB関数での微調整ができないみたいです。
180を150と変えても、同じような見た目になってしまいます。
※100にすると大分薄くなりますが、それでも見た目が汚いです.
NMHDR構造体 / NMCUSTOMDRAW構造体のメンバで、[uItemState]で
アイテムの状態が入っているようですが、これを書きかえることでは
状態を変化させられないでしょうか?
少なくとも、下のように自分がやってみた限りではやり方が悪いのかダメでした・・・
nmcd->uItemState = CDISGRAYED;
参考: http://lhsp.s206.xrea.com/misc/customdraw.html
グレイアウトが汚いとは、アイコン部分で会ってますか。
どんな感じで汚いのでしょうか。
当方、Windows7(非エアロ)でそれっぽく見えたので、
「まぁこれでいいでしょう」という判断です。
詳しく言うと、R2_MERGEPENなので、
赤色はRGB(255, 0, 0) -> RGB(255, 180, 180)に変わるだけで、
白っぽい赤になり、グレイではありません。
本当にグレイにしたければ、DrawThemeBackgroundを使って、
イメージリストにイメージを追加するほうが良いと思います。
上書き手法の改訂版
# ここでは、アイコンを上書きしています。
# アイコンの位置合わせが面倒なので、お勧めしません。
void DrawDisabled(HWND hWnd, HDC hdc, const RECT& rect,
int iPartId, int iStateId)
{
HTHEME hTheme = OpenThemeData(hWnd, LButton);
if(hTheme) // IsAppThemed(), IsThemeActive()が必要かどうか不明です
{
RECT rc = rect;
DrawThemeBackground(hTheme, hdc, iPartId, iStateId, &rc, 0);
CloseThemeData(hTheme);
}
else
{
UINT uState;
if(iPartId == BP_CHECKBOX)
{
uState = DFCS_BUTTONCHECK | DFCS_FLAT;
switch(iStateId)
{
case CBS_UNCHECKEDDISABLED:
DrawFrameControl(hdc, &rc, DFC_BUTTON,
uState | DFCS_INACTIVE);
break;
case CBS_CHECKEDDISABLED:
DrawFrameControl(hdc, &rc, DFC_BUTTON,
uState | DFCS_CHECKED | DFCS_INACTIVE);
break;
}
}
}
}
case CDDS_ITEMPOSTPAINT:
{
NMCUSTOMDRAW* nmcd = (NMCUSTOMDRAW*)lParam;
RECT rc;
ListView_GetItemRect(hwndListView, nmcd->dwItemSpec,
&rc, LVIR_ICON);
// state iconのrectを計算(ここはいい加減です)
rc.right = rc.left;
rc.left = 0;
UINT state = ListView_GetItemState(hwndListView, nmcd->dwItemSpec,
LVIS_STATEIMAGEMASK);
int iStateId = state == INDEXTOSTATEIMAGEMASK(2)
? CBS_CHECKEDDISABLED : CBS_UNCHECKEDDISABLED;
DrawDisabled(hwndListView, nmcd->hdc, rc, BP_CHECKBOX, iStateId);
}
break;
遅くなってすみません
やはり上手く表示するのに時間がかかってしまう、ということで
今回はチェックボックス表示なしになってしまいました。
わざわざサンプルを作っていただいたのにすみません。
勉強のため、時間がある時にロマさんのサンプルも試してみることにします。
ありがとうございました。