Many moons ago I wrote a Delphi program that could tell the exact character in a ListBox, as you clicked on it with a mouse. I found a little info on the NET that lets you get at least the item in a ListBox using C#. I made it work and still need to expand it to the character level. Looks interesting anyway and could be used for other components.

// respond to a MouseDown event inside a ListBox
// shows item in the ItemHeight-range of mouse y-position
// with the proper font this could be expanded to show character at mouse x-position
// 
// MS Visual C# .NET by vegaseat  06feb2005
//
// this is a Windows Application

using System;
using System.Windows.Forms;

namespace ListBoxMouse1
{
  public class MainForm : System.Windows.Forms.Form
  {
    private System.Windows.Forms.Label label1;
    private System.Windows.Forms.ListBox listBox1;
    
    public MainForm()
    {
      InitializeComponent();
      // now set this particular event handler to function ButtonDown()
      this.listBox1.MouseDown += new System.Windows.Forms.MouseEventHandler( this.ButtonDown ); 
    }
		
    // program entry point
    public static void Main(string[] args)
    {
      Application.Run(new MainForm());
    }
		
    #region Windows Forms Designer generated code
    private void InitializeComponent() 
    {
      this.listBox1 = new System.Windows.Forms.ListBox();
      this.label1 = new System.Windows.Forms.Label();
      this.SuspendLayout();
      // 
      // listBox1
      // 
      this.listBox1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(224)), ((System.Byte)(192)));
      this.listBox1.ItemHeight = 16;
      this.listBox1.Location = new System.Drawing.Point(8, 16);
      this.listBox1.Name = "listBox1";
      this.listBox1.Size = new System.Drawing.Size(240, 196);
      this.listBox1.TabIndex = 0;
      // 
      // label1
      // 
      this.label1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(255)), ((System.Byte)(192)));
      this.label1.Location = new System.Drawing.Point(16, 224);
      this.label1.Name = "label1";
      this.label1.Size = new System.Drawing.Size(232, 112);
      this.label1.TabIndex = 1;
      this.label1.Text = "label1";
      // 
      // MainForm
      // 
      this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
      this.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(192)), ((System.Byte)(192)), ((System.Byte)(0)));
      this.ClientSize = new System.Drawing.Size(320, 344);
      this.Controls.Add(this.label1);
      this.Controls.Add(this.listBox1);
      this.Name = "MainForm";
      this.Text = "MouseDown in a ListBox";
      this.Load += new System.EventHandler(this.MainFormLoad);
      this.ResumeLayout(false);
    }
    #endregion
		
    // respond to mouse events in the listBox
    private void ButtonDown(object sender, MouseEventArgs mea)
    {
      // the 0 based index of the row/item clicked
      int nDx = 0; 
       
      if ( mea.Button == MouseButtons.Right ) 
      { 
        label1.Text = "Right Button Clicked\n";
      }
      else if ( mea.Button == MouseButtons.Left ) 
      { 
        label1.Text = "Left Button Clicked\n";
      }
 
      // calculate the index of the selected item or show error
      nDx = mea.Y / listBox1.ItemHeight;
      label1.Text = label1.Text +
        "Item height = " + listBox1.ItemHeight.ToString()+ "\n" +
        "X position  = " + mea.X.ToString() + "\n" +
        "Y position  = " + mea.Y.ToString() + "\n" +
        "Index       = " + nDx.ToString();
 
      if ( listBox1.Items.Count <= nDx )
      {
        label1.Text = label1.Text + "\nRow clicked past items loaded";
      }
      else
      {
        label1.Text = label1.Text + "\nIndex       = " + listBox1.Items[nDx];
        //highlight the selected row/item
        listBox1.SetSelected(nDx,true);
      }
    }		
		
    // load the listBox with some names
    void MainFormLoad(object sender, System.EventArgs e)
    {
      listBox1.Items.Add("Helmut");
      listBox1.Items.Add("Helga");
      listBox1.Items.Add("Andreas");
      listBox1.Items.Add("Volger");
      listBox1.Items.Add("Kurt");
      listBox1.Items.Add("Erich");
      listBox1.Items.Add("Bjorn");
      listBox1.Items.Add("Lena");
      listBox1.Items.Add("Kristina");
      listBox1.Items.Add("Ulrike");
      listBox1.Items.Add("Heidrun");
    }
  }
}
The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.