Thread: ListView - remove FocusCues

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    244

    ListView - remove FocusCues

    hi!

    i'm currently designing an advanced ListView. it already has the ability of sorting by columns and vista style usind
    Code:
    SetWindowTheme(Handle, "Explorer", null);
    it looks like that: http://xload.dev-ch.de/c2a96e3bc372e855/screen348.jpg

    but the focus cues are really bothering me. they appear when i press up/down key for example.

    i tired:
    - overriding ShowFocusCues
    - pinvoke with WM_CHANGEUISTATE
    - can't remember, sitting all day here...

    does anyone know how i can remove them?
    thanks.

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    What is your goal? Do you want not to have focus at all? Implement the GotFocus() event and give focus to something else so the focus never stays on your list.

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    that woudld work. it would make it impossible to select items. i just want to remove the dotted lines called FocusCues... see the pic i have posted

  4. #4
    Registered User
    Join Date
    Mar 2009
    Location
    england
    Posts
    209
    Hi there.

    To me, the obvious way forward would be to paint your own row entries, in doing so completely bypassing the focus cue (or to be precise, being responsible for displaying the focus cue for youself). You'd also be responsible for displaying selected items and hot tracking.

    This code shows how you might paint the listview to look normal, minus focusing/hot tracking/selected item:

    Code:
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication2
    {
        class LView : ListView
        {
            public LView()
            {
                this.OwnerDraw = true;
                this.DoubleBuffered = true;
            }
    
            protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e)
            {
                e.DrawDefault = true;
            }
    
            protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
            {
                e.Graphics.DrawString(e.Item.SubItems[e.ColumnIndex].Text, this.Font, Brushes.Black, new PointF(e.Bounds.X + 3, e.Bounds.Y));
            }
        }
    }
    Last edited by theoobe; 07-09-2010 at 04:02 AM.

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    thanks, i know how to custom paint the stuff. i have some practice in it. but the goal for this listview was to look just native, the way it looks in explorer, too. so i didn't want to custom paint it. the reason is that 2k style, luna and aero all look different and my current listview fits in every os. this should stay that way, but the focus cues are somehow bothering...

    new update: i found out that when i was using the WM_CHANGEUISTATE api more often like when a key was pressed, it works (almost...)


    here is my listview: sortable, vista style, fully functional.
    happy sharing!

    Code:
    using System.Collections;
    using System.Runtime.InteropServices;
    
    namespace System.Windows.Forms
    {
    	public class exListView : ListView
    	{
    		private int _SortColumnIndex = -1;
    		public int SortColumnIndex
    		{
    			get
    			{
    				return _SortColumnIndex;
    			}
    			set
    			{
    				SetSortIcon(_SortColumnIndex, value);
    				_SortColumnIndex = value;
    			}
    		}
    		internal ColumnAttributes[] ColumnAttributes = new ColumnAttributes[100];
    
    		public exListView()
    		{
    			ListViewItemSorter = new exListViewItemSorter();
    			for (int i = 0; i < ColumnAttributes.Length; i++)
    			{
    				ColumnAttributes[i] = new ColumnAttributes(ColumnSortAlgorithm.String);
    			}
    			SendMessage(Handle, 0x127, 0x10001, 0);
    		}
    
    		protected override void OnHandleCreated(EventArgs e)
    		{
    			base.OnHandleCreated(e);
    			SetWindowTheme(Handle, "Explorer", null);
    			SortColumnIndex = _SortColumnIndex;
    		}
    		protected override void OnClick(EventArgs e)
    		{
    			base.OnClick(e);
    			SendMessage(Handle, 0x127, 0x10001, 0);
    		}
    		protected override void OnColumnClick(ColumnClickEventArgs e)
    		{
    			base.OnColumnClick(e);
    			Sorting = e.Column == _SortColumnIndex ? (Sorting == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending) : SortOrder.Ascending;
    			SortColumnIndex = e.Column;
    			Sort();
    		}
    		protected override void OnKeyUp(KeyEventArgs e)
    		{
    			base.OnKeyUp(e);
    			SendMessage(Handle, 0x127, 0x10001, 0);
    		}
    		private void SetSortIcon(int previous, int current)
    		{
    			IntPtr header = SendMessage(Handle, 0x101f, IntPtr.Zero, IntPtr.Zero);
    			HDITEM item;
    
    			if (previous != -1 && previous != current)
    			{
    				item = new HDITEM();
    				item.mask = 4;
    				SendMessage(header, 0x120b, (IntPtr)previous, ref item);
    				item.fmt &= ~0x0200 & ~0x0400;
    				SendMessage(header, 0x120c, (IntPtr)previous, ref item);
    			}
    			item = new HDITEM();
    			item.mask = 4;
    			SendMessage(header, 0x120b, (IntPtr)current, ref item);
    			if (Sorting == SortOrder.Ascending)
    			{
    				item.fmt &= ~0x0200;
    				item.fmt |= 0x0400;
    			}
    			else
    			{
    				item.fmt &= ~0x0400;
    				item.fmt |= 0x0200;
    			}
    			SendMessage(header, 0x120c, (IntPtr)current, ref item);
    			previous = current;
    			SetWindowTheme(Handle, "explorer", null);
    		}
    		public void SetColumnAttributes(int column, ColumnSortAlgorithm sortAlgorithm)
    		{
    			ColumnAttributes[column] = new ColumnAttributes(sortAlgorithm);
    		}
    
    		[StructLayout(LayoutKind.Sequential)]
    		private struct HDITEM
    		{
    			public int mask;
    			public int cxy;
    			[MarshalAs(UnmanagedType.LPTStr)]
    			public string pszText;
    			public IntPtr hbm;
    			public int cchTextMax;
    			public int fmt;
    			public int lParam;
    			public int iImage;
    			public int iOrder;
    		}
    		[DllImport("user32.dll")]
    		static private extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    		[DllImport("user32.dll")]
    		static private extern IntPtr SendMessage(IntPtr Handle, int msg, IntPtr wParam, ref HDITEM lParam);
    		[DllImport("user32.dll")]
    		public extern static int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
    		[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
    		static private extern int SetWindowTheme(IntPtr hWnd, string textSubAppName, string textSubIdList);
    	}
    
    	public class ColumnAttributes
    	{
    		public ColumnSortAlgorithm SortAlgorithm { get; set; }
    
    		public ColumnAttributes(ColumnSortAlgorithm sortAlgorithm)
    		{
    			SortAlgorithm = sortAlgorithm;
    		}
    	}
    	public enum ColumnSortAlgorithm
    	{
    		String,
    		Number,
    		NumberOfSubItemTag,
    		IPAddress,
    		TextLength
    	}
    
    	public class exListViewItemSorter : IComparer
    	{
    		public int Compare(object x, object y)
    		{
    			try
    			{
    				ListViewItem lx = (ListViewItem)x, ly = (ListViewItem)y;
    				exListView view = (exListView)lx.ListView;
    				if (view.Sorting == SortOrder.None) return 0;
    				int col = view.SortColumnIndex;
    				string tx = lx.SubItems[col].Text, ty = ly.SubItems[col].Text;
    
    				int compare = 0;
    				switch (view.ColumnAttributes[col].SortAlgorithm)
    				{
    					case ColumnSortAlgorithm.String:
    						compare = tx.CompareTo(ty);
    						break;
    					case ColumnSortAlgorithm.Number:
    						compare = Convert.ToInt32(tx).CompareTo(Convert.ToInt32(ty));
    						break;
    					case ColumnSortAlgorithm.NumberOfSubItemTag:
    						string tax = "", tay = "";
    						if (col == 0)
    						{
    							tax = Convert.ToString(lx.Tag);
    							tay = Convert.ToString(ly.Tag);
    						}
    						else
    						{
    							tax = Convert.ToString(lx.SubItems[col].Tag);
    							tay = Convert.ToString(ly.SubItems[col].Tag);
    						}
    						compare = Convert.ToInt32(tax).CompareTo(Convert.ToInt32(tay));
    						break;
    					case ColumnSortAlgorithm.IPAddress:
    						string[] ip1 = tx.Split('.');
    						string[] ip2 = ty.Split('.');
    						for (int i = 0; i < 4; i++)
    						{
    							if (ip1[i] != ip2[i])
    							{
    								compare = Convert.ToInt32(ip1[i]).CompareTo(Convert.ToInt32(ip2[i]));
    								break;
    							}
    						}
    						break;
    					case ColumnSortAlgorithm.TextLength:
    						compare = tx.Length.CompareTo(ty.Length);
    						break;
    				}
    				return view.Sorting == SortOrder.Ascending ? compare : -compare;
    			}
    			catch
    			{
    				return 0;
    			}
    		}
    	}
    }
    Last edited by Devils Child; 07-09-2010 at 07:23 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Running remove() gets permission denied error...
    By edomingox in forum C Programming
    Replies: 4
    Last Post: 01-11-2009, 12:55 PM
  2. ListView Refresh, Update
    By de4th in forum C++ Programming
    Replies: 1
    Last Post: 12-23-2006, 09:13 AM
  3. Replies: 6
    Last Post: 07-10-2006, 12:05 AM
  4. Troubles with ListView and Toolbar
    By cornholio in forum Windows Programming
    Replies: 8
    Last Post: 11-14-2005, 01:26 AM
  5. Listview??
    By SuperNewbie in forum C# Programming
    Replies: 4
    Last Post: 02-13-2003, 03:34 AM