/// /// Copyright © 2003-2008 JetBrains s.r.o. /// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder). /// using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Runtime.InteropServices; using System.Windows.Forms; using JetBrains.UI.Interop; using JetBrains.UI.RichText; namespace JetBrains.UI.Components.CustomListView { using RichText; /// /// Summary description for CustomListView. /// public class CustomListView : System.Windows.Forms.ListView { /// /// Item painter to use /// private IItemPainter myItemPainter; /// /// Gets or sets Item painter /// public IItemPainter ItemPainter { get { return myItemPainter; } set { myItemPainter = value; } } protected override void WndProc(ref Message m) { switch (m.Msg) { case Win32Declarations.OCM_NOTIFY: OnWmNotify(ref m); break; default: base.WndProc(ref m); break; } } /// /// Handles the WM_NOTIFY message of the parent control /// /// The message to handle /// Whether the message was handled private void OnWmNotify( ref Message m ) { // Marshal lParam into NMHDR: NMHDR hdr = new NMHDR(); hdr = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR)); switch (hdr.code) { case Win32Declarations.NM_CUSTOMDRAW: NMLVCUSTOMDRAW customDraw; customDraw = (NMLVCUSTOMDRAW)Marshal.PtrToStructure(m.LParam, typeof(NMLVCUSTOMDRAW)); OnCustomDraw(ref customDraw, ref m); break; default: base.WndProc( ref m ); break; } } public Size GetItemSize( ListViewItem item ) { try { using (Graphics g = CreateGraphics()) { return myItemPainter.GetSize(item, g); } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine("CustomListView.GetItemSize failed : " + ex, "UI"); return new Size(1,1); } } #region Drawing logic /// /// Erases Item /// private void EraseItem( ref NMLVCUSTOMDRAW customDraw ) { try { using (Graphics g = Graphics.FromHdc(customDraw.nmcd.hdc)) { Rectangle rect = new Rectangle(customDraw.nmcd.rc.left, customDraw.nmcd.rc.top, customDraw.nmcd.rc.right - customDraw.nmcd.rc.left, customDraw.nmcd.rc.bottom - customDraw.nmcd.rc.top); g.FillRectangle(new SolidBrush(BackColor), rect); } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine("CustomListView.EraseItem failed : " + ex, "UI"); } } /// /// Draws Item /// private void DrawItem( ref NMLVCUSTOMDRAW customDraw ) { try { ListViewItem item = this.Items[customDraw.nmcd.dwItemSpec]; if (myItemPainter != null && myItemPainter.IsHandled(item)) using (Graphics g = Graphics.FromHdc(customDraw.nmcd.hdc)) { myItemPainter.Draw(item, g, new Rectangle(0, 0, ClientSize.Width, 0)); } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine("CustomListView.DrawItem failed : " + ex, "UI"); } } #endregion /// /// Handles the NM_CUSTOMDRAW notification /// private void OnCustomDraw( ref NMLVCUSTOMDRAW customDraw, ref Message m ) { ListViewItem item; switch (customDraw.nmcd.dwDrawStage) { case Win32Declarations.CDDS_PREPAINT: m.Result = (IntPtr)(Win32Declarations.CDRF_NOTIFYITEMDRAW | Win32Declarations.CDRF_NOTIFYPOSTPAINT); break; case Win32Declarations.CDDS_ITEMPREPAINT: item = Items[customDraw.nmcd.dwItemSpec]; if (myItemPainter != null && item != null && myItemPainter.IsHandled(item)) { m.Result = (IntPtr)(Win32Declarations.CDRF_NOTIFYITEMDRAW | Win32Declarations.CDRF_NOTIFYPOSTPAINT); } else m.Result = (IntPtr)Win32Declarations.CDRF_NOTIFYITEMDRAW; break; case Win32Declarations.CDDS_ITEMPOSTPAINT: DrawItem(ref customDraw); break; case Win32Declarations.CDDS_POSTERASE: EraseItem(ref customDraw); break; default: m.Result = (IntPtr)Win32Declarations.CDRF_DODEFAULT; break; } } } }