TrackBarのカスタムドロー
TrackBarの棒部分の色を変えたかったので、カスタムドローに挑戦してみる。
まずシンプルにトラックの背景色だけを変えてみる。
で、できたのがこれです。
namespace TrackBarTest { public class CustomTrackBar : TrackBar { [StructLayout(LayoutKind.Sequential)] protected struct NMHDR { public IntPtr hwndFrom; public uint idFrom; public uint code; } [StructLayout(LayoutKind.Sequential)] protected struct RECT { public int left; public int top; public int right; public int bottom; } [StructLayout(LayoutKind.Sequential)] protected struct NMCUSTOMDRAW { public NMHDR hdr; public uint dwDrawStage; public IntPtr hdc; public RECT rc; public uint dwItemSpec; public uint uItemState; public IntPtr lItemlParam; } protected const uint WM_REFLECT = 0x2000; protected const uint WM_NOTIFY = 0x004E; protected const uint NM_CUSTOMDRAW = 4294967284; //(uint)-12 protected const uint CDRF_DODEFAULT = 0x00000000; protected const uint CDRF_NEWFONT = 0x00000002; protected const uint CDRF_SKIPDEFAULT = 0x00000004; protected const uint CDRF_NOTIFYPOSTPAINT = 0x00000010; protected const uint CDRF_NOTIFYITEMDRAW = 0x00000020; protected const uint CDRF_NOTIFYSUBITEMDRAW = 0x00000020; protected const uint CDRF_NOTIFYPOSTERASE = 0x00000040; protected const uint CDDS_PREPAINT = 0x00000001; protected const uint CDDS_POSTPAINT = 0x00000002; protected const uint CDDS_PREERASE = 0x00000003; protected const uint CDDS_POSTERASE = 0x00000004; protected const uint CDDS_ITEM = 0x00010000; protected const uint CDDS_ITEMPREPAINT = (CDDS_ITEM | CDDS_PREPAINT); protected const uint CDDS_ITEMPOSTPAINT = (CDDS_ITEM | CDDS_POSTPAINT); protected const uint CDDS_ITEMPREERASE = (CDDS_ITEM | CDDS_PREERASE); protected const uint CDDS_ITEMPOSTERASE = (CDDS_ITEM | CDDS_POSTERASE); protected const uint TBCD_TICS = 0x0001; protected const uint TBCD_THUMB = 0x0002; protected const uint TBCD_CHANNEL = 0x0003; protected const uint CDIS_SELECTED = 0x0001; protected const uint CDIS_GRAYED = 0x0002; protected const uint CDIS_DISABLED = 0x0004; protected const uint CDIS_CHECKED = 0x0008; protected const uint CDIS_FOCUS = 0x0010; protected const uint CDIS_DEFAULT = 0x0020; protected const uint CDIS_HOT = 0x0040; protected const uint CDIS_MARKED = 0x0080; protected const uint CDIS_INDETERMINATE = 0x0100; protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == (WM_REFLECT + WM_NOTIFY)) { NMHDR nmhdr = (NMHDR)m.GetLParam(typeof(NMHDR)); if (nmhdr.code == NM_CUSTOMDRAW) { NMCUSTOMDRAW nmcd = (NMCUSTOMDRAW)m.GetLParam(typeof(NMCUSTOMDRAW)); if (nmcd.dwDrawStage == CDDS_PREPAINT) { m.Result = (IntPtr)(CDRF_DODEFAULT | CDRF_NOTIFYITEMDRAW); } else if (nmcd.dwDrawStage == CDDS_ITEMPREPAINT) { m.Result = (IntPtr)(CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT); } else if (nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT && nmcd.dwItemSpec == TBCD_CHANNEL) { using (Graphics g = this.CreateGraphics()) { g.FillRectangle(Brushes.Red, nmcd.rc.left + 1, nmcd.rc.top + 1, nmcd.rc.right - nmcd.rc.left - 2, nmcd.rc.bottom - nmcd.rc.top - 2); } m.Result = (IntPtr)CDRF_SKIPDEFAULT; } } } } } }
が、トラックをクリックしないと色が変わらない…
フォーカスを別のコントロールに写すと色が消える…
C++のサンプルはたくさんあったけど、C#のは無かったのはそもそも出来ないからなのだろうか。
一日悩んだけどどうにもならんかった。
もう自分でコントロール作ろう…