public override bool PreProcessMessage(ref Message msg)
        {
            if (msg.Msg == WM_KEYDOWN)
            {
                if (focusedItem != null && items.Count > 0)
                {
                    Keys keyData = ((Keys) (int) msg.WParam) | ModifierKeys;
                    Keys keyCode = ((Keys) (int) msg.WParam);

                    if (keyData == Keys.Down)
                    {
                        if (focusedIndex < items.Count-1)
                        {
                            focusedItem.Focused = false;
                            focusedItem.Selected = false;
                            focusedIndex++;

                            items[focusedIndex].Focused = true;
                            items[focusedIndex].Selected = true;
                            focusedItem = items[focusedIndex];

                            MakeSelectedVisible();

                            Invalidate(this.ClientRectangle);
                        }

                        return true;
                    }
                    else if (keyData == Keys.Up)
                    {
                        if (focusedIndex > 0)
                        {
                            focusedItem.Focused = false;
                            focusedItem.Selected = false;
                            focusedIndex--;

                            items[focusedIndex].Focused = true;
                            items[focusedIndex].Selected = true;
                            focusedItem = items[focusedIndex];

                            MakeSelectedVisible();

                            Invalidate(this.ClientRectangle);
                        }

                        return true;
                    }
                }
            }

            return base.PreProcessMessage(ref msg);
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if (!isFocused)
            {
                this.Focus();

                if (!captureFocusClick)
                    return;
            }

            lastClickedPoint = new Point(e.X, e.Y);

            // determine if a header was pressed
            if (headerStyle != ColumnHeaderStyle.None)
            {
                if (MouseInRect(e, headerRect) && e.Button == MouseButtons.Left)
                {
                    for (int i=0; i<columns.Count; i++)
                    {
                        columns[i].Pressed = false;
                        if (MouseInRect(e, columnSizeRects[i]) && items.Count > 0)
                        {
                            if (columns[i].ScaleStyle == ColumnScaleStyle.Slide)
                            {
                                // autosize column
                                if (e.Clicks == 2 && e.Button == MouseButtons.Left && items.Count > 0)
                                {
                                    int mwid = 0;
                                    int twid = 0;
                                    for (int j=0; j<items.Count; j++)
                                    {
                                        if (i > 0 && items[j].SubItems.Count > 0)
                                            twid = GetStringWidth(items[j].SubItems[i-1].Text) + 10;
                                        else if (i == 0)
                                            twid = GetStringWidth(items[j].Text) + 10;
                                        twid += 5;
                                        if (twid > mwid)
                                            mwid = twid;
                                    }

                                    twid = GetStringWidth(columns[i].Text);
                                    if (twid > mwid)
                                        mwid = twid;

                                    mwid += 5;

                                    columns[i].Width = mwid;
                                }
                                    // scale column
                                else
                                {
                                    colScaleMode = true;
                                    colScaleWid = columnRects[i].Width;
                                    scaledCol = i;
                                }
                            }
                        }
                        else if (MouseInRect(e, columnRects[i]) && !MouseInRect(e, columnSizeRects[i]))
                        {
                            columns[i].Pressed = true;
                            lastColPressed = i;
                        }
                    }
                    Invalidate();
                    return;
                }
            }

            // determine if a row was pressed
            bool selChange = false;
            if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
            {
                if (MouseInRect(e, rowsRect) && items.Count>0)
                {
                    GenerateRowRects();
                    //focusedIndex = -1;
                    if (multiSelectMode == MultiSelectMode.Single)
                    {
                        selectedIndices.Clear();
                        selectedItems.Clear();

                        for (int i=0; i<items.Count; i++)
                        {

                            items[i].Focused = false;
                            items[i].Selected = false;
                            if (MouseInRect(e, rowRects[i]))
                            {
                                items[i].Focused = true;
                                items[i].Selected = true;
                                focusedIndex = firstSelected = i;

                                // set selected items and indices collections
                                selectedIndices.Add(i);
                                selectedItems.Add(items[i]);

                                MakeSelectedVisible();
                            }
                        }
                        OnSelectedIndexChanged(new EventArgs());
                    }
                    else if (multiSelectMode == MultiSelectMode.Range)
                    {
                        for (int i=0; i<items.Count; i++)
                        {
                            if (firstSelected == -1)
                            {
                                items[i].Focused = true;
                                items[i].Selected = true;
                                firstSelected = focusedIndex = i;

                                // set selected items and indices collections
                                selectedIndices.Clear();
                                selectedIndices.Add(i);

                                selectedItems.Clear();
                                selectedItems.Add(items[i]);

                                MakeSelectedVisible();

                                OnSelectedIndexChanged(new EventArgs());
                            }
                            else
                            {
                                // unfocus the previously focused item
                                if (focusedIndex >= 0 && focusedIndex < items.Count)
                                    items[focusedIndex].Focused = false;

                                if (MouseInRect(e, rowRects[i]))
                                {
                                    lastSelected = focusedIndex = i;
                                }

                                if (lastSelected >= 0 && lastSelected < firstSelected)
                                {
                                    selectedIndices.Clear();
                                    selectedItems.Clear();
                                    for (int j=0; j<items.Count; j++)
                                    {
                                        if (j <= firstSelected && j >= lastSelected)
                                        {
                                            items[j].Selected = true;

                                            // set selected items and indices collections
                                            selectedIndices.Add(j);
                                            selectedItems.Add(items[j]);
                                            selChange = true;
                                        }
                                        else
                                            items[j].Selected = false;

                                        if (j == lastSelected)
                                            items[j].Focused = true;
                                        else
                                            items[j].Focused = false;
                                    }
                                }
                                else if (lastSelected >= 0 && lastSelected > firstSelected)
                                {
                                    selectedIndices.Clear();
                                    selectedItems.Clear();
                                    for (int j=0; j<items.Count; j++)
                                    {
                                        if (j >= firstSelected && j <= lastSelected)
                                        {
                                            items[j].Selected = true;

                                            // set selected items and indices collections
                                            selectedIndices.Add(j);
                                            selectedItems.Add(items[j]);
                                            selChange = true;
                                        }
                                        else
                                            items[j].Selected = false;

                                        if (j == lastSelected)
                                            items[j].Focused = true;
                                        else
                                            items[j].Focused = false;
                                    }
                                }
                                else
                                {
                                    selectedIndices.Clear();
                                    selectedItems.Clear();
                                    for (int j=0; j<items.Count; j++)
                                    {
                                        if (j == firstSelected && j == lastSelected)
                                        {
                                            items[j].Selected = true;
                                            items[j].Focused = true;
                                            selectedIndices.Add(j);
                                            selectedItems.Add(items[j]);
                                            selChange = true;
                                        }
                                        else
                                        {
                                            items[j].Selected = false;
                                            items[j].Focused = false;
                                        }
                                    }
                                }
                            }

                            if (selChange)
                            {
                                MakeSelectedVisible();
                                OnSelectedIndexChanged(new EventArgs());
                            }
                        }
                    }
                    else if (multiSelectMode == MultiSelectMode.Selective)
                    {
                        for (int i=0; i<items.Count; i++)
                        {
                            if (MouseInRect(e, rowRects[i]))
                            {
                                // unfocus the previously focused item
                                if (focusedIndex >= 0 && focusedIndex < items.Count)
                                    items[focusedIndex].Focused = false;

                                if (items[i].Selected)
                                {
                                    items[i].Focused = false;
                                    items[i].Selected = false;
                                    selectedIndices.Remove(i);
                                    selectedItems.Remove(items[i]);

                                    MakeSelectedVisible();

                                    OnSelectedIndexChanged(new EventArgs());
                                }
                                else
                                {
                                    items[i].Focused = true;
                                    items[i].Selected = true;
                                    selectedIndices.Add(i);
                                    selectedItems.Add(items[i]);

                                    MakeSelectedVisible();

                                    OnSelectedIndexChanged(new EventArgs());
                                }
                                focusedIndex = i;
                            }
                        }
                    }

                    if (focusedIndex >= 0)
                        focusedItem = items[focusedIndex];
                    else
                        focusedItem = null;

                    Invalidate();
                    return;
                }
            }
        }