Ejemplo n.º 1
0
        /// <summary>
        /// Override of WndProc to handle the context menu or column resize on column headers.
        /// Necessary because ListView eats almost all mouse events, and does not provide any that can be used to handling right
        /// clicks in the header.
        /// Also couldn't use class wizard to handle WM_NOTIFY because it won't add HDN_ITEMCLICKA and HDN_DIVIDERDBLCLICKW
        /// </summary>
        /// <param name="m">The Windows Message to process</param>
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
            case WM_CONTEXTMENU:
                Point pointClicked = PointToClient(MousePosition);
                int   index        = GetColumnIndexFromMousePosition(pointClicked);
                if (index >= 0)
                {
                    OnColumnRightClick(index, pointClicked);
                }
                break;

            case WM_NOTIFY:
                var nm = (NMHDR)m.GetLParam(typeof(NMHDR));

                // Notification names: standard, ANSI (A), and Unicode (W)
                const int HDN_FIRST            = 0 - 300;
                const int HDN_DIVIDERDBLCLICKA = HDN_FIRST - 5;
                const int HDN_DIVIDERDBLCLICKW = HDN_FIRST - 25;

                // Handle notifications for header column divider
                if (nm.code == HDN_DIVIDERDBLCLICKA || nm.code == HDN_DIVIDERDBLCLICKW)
                {
                    // nmheader.iItem is in the original column order, but the resizes are done in display order.
                    var nmheader       = (NMHEADER)m.GetLParam(typeof(NMHEADER));
                    int inDisplayOrder = m_orderForColumnsDisplay[nmheader.iItem];
                    m_bv.AdjustColumnWidthToMatchContents(inDisplayOrder);
                }
                // Handle all other notifications
                else
                {
                    base.WndProc(ref m);
                }
                break;

            default:
                base.WndProc(ref m);
                break;
            }
        }
Ejemplo n.º 2
0
        const int NM_LCLICKUP = NM_FIRST - 16;          // Left Click Mouse Up

        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Overrides <see cref="M:System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message@)"/>.
        /// </summary>
        /// <param name="m">The Windows <see cref="T:System.Windows.Forms.Message"/> to process.</param>
        /// ------------------------------------------------------------------------------------
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
            case WM_NOTIFY:
                Win32.NMHEADER nmhdr = (Win32.NMHEADER)m.GetLParam(typeof(Win32.NMHEADER));
                switch (nmhdr.hdr.code)
                {
                case HDN_DIVIDERDBLCLICKW:                                 // double-click on line between column headers.
                    // adjust width of column to match item of greatest length.
                    m_bv.AdjustColumnWidthToMatchContents(nmhdr.iItem);
                    break;

                default:
                    base.WndProc(ref m);
                    break;
                }
                //Debug.WriteLine("DhListView.WndProc: WM_NOTIFY code = " + nmhdr.hdr.code);
                switch (nmhdr.hdr.code)
                {
                case HDN_BEGINTRACKA:
                case HDN_BEGINTRACKW:
                    if (m_bv.m_xbv.Vc.HasSelectColumn)
                    {
                        int iCol = nmhdr.iItem;
                        // We want to prevent the user from resizing the checkbox column (LT-3938)
                        if (iCol == 0)
                        {
                            m.Result = (IntPtr)1;                                       // Disable tracking.
                        }
                    }
                    m_suppressColumnWidthChanges = true;
                    break;

                case HDN_ITEMDBLCLICKW:                         // double-click on line between items collapses it.
                    // However, we never get this notification, because we're not treating the
                    // column headers as buttons. Sigh.
                    break;

                case HDN_ENDTRACK:
                    m_bv.AdjustColumnWidths(true);
                    m_suppressColumnWidthChanges = false;
                    break;

                case HDN_ITEMCHANGED:
                    // No longer needed. HDN_DIVIDERDBLCLICKW above helps to
                    // avoid the the problem of someone double-clicking the
                    // separator and messing up the check mark column irretrievably.
                    if (!m_suppressColumnWidthChanges && !m_fInAdjustWidth)
                    {
                        m_bv.AdjustColumnWidths(true);
                    }
                    break;

                case NM_RCLICK:
                    // HDN_ITEMCLICK never shows up for a right click, although it does for a
                    // left click.
                    // NM_RCLICK shows up okay, but gives no useful information for where the
                    // right click occurred!  We have to get the current mouse position, and
                    // compare it to the column boundaries across the window.
                    Point pt_rclick   = this.PointToClient(Control.MousePosition);
                    int   icol_rclick = GetColumnIndexFromMousePosition(pt_rclick);
                    if (icol_rclick >= 0)
                    {
                        OnColumnRightClick(icol_rclick, pt_rclick);
                        return;
                    }
                    break;

                case HDN_ENDDRAG:
                    // We don't have a new display order until AFTER the HDN_ENDDRAG event.
                    // so flag for further handling (on NM_CLICKUP).
                    m_fColumnDropped = true;                              // flag for further handling during NM_LCLICKUP.
                    return;

                case NM_LCLICKUP:
                    // first handle the special case where the user may have dragged and dropped
                    // something into the location of the "select column".
                    if (m_bv.m_xbv.Vc.HasSelectColumn &&
                        m_fColumnDropped && this.ColumnOrdersOutOfSync)
                    {
                        this.MaintainSelectColumnPosition();
                    }
                    // if displayed columns are (still) out of sync with Columns collection,
                    // then we re-sync with that reordering and let the browse view know the new order.
                    if (m_fColumnDropped && this.ColumnOrdersOutOfSync)
                    {
                        this.OnColumnDisplayReordered();
                        // reset our drag-n-drop event flag.
                        m_fColumnDropped = false;
                    }
                    return;

                default:
                    break;
                }
                break;

            default:
                base.WndProc(ref m);
                break;
            }
        }