protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x2000 + 0x004E)         // [reflected] WM_NOTIFY
        {
            uint nmhdrCode = (uint)Marshal.ReadInt32(m.LParam, NmHdrCodeOffset);
            if (nmhdrCode == LVN_ITEMCHANGING)
            {
                NMLISTVIEW nmlv = (NMLISTVIEW)Marshal.PtrToStructure(m.LParam, typeof(NMLISTVIEW));
                if ((nmlv.uChanged & LVIF_STATE) != 0)
                {
                    bool currentSel = (nmlv.uOldState & LVIS_SELECTED) == LVIS_SELECTED;
                    bool newSel     = (nmlv.uNewState & LVIS_SELECTED) == LVIS_SELECTED;

                    if (newSel != currentSel)
                    {
                        ItemSelectionChangingEventArgs e = new ItemSelectionChangingEventArgs(nmlv.iItem, newSel, currentSel);
                        OnItemSelectionChanging(e);
                        m.Result = e.Cancel ? (IntPtr)1 : IntPtr.Zero;
                        return;
                    }
                }
            }
        }

        base.WndProc(ref m);
    }
Пример #2
0
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == OCM_NOTIFY)
            {
                NMHDR nm = (NMHDR)m.GetLParam(typeof(NMHDR));
                if (nm.code == LVN_ITEMCHANGING)
                {
                    NMLISTVIEW nmlv = (NMLISTVIEW)m.GetLParam(typeof(NMLISTVIEW));

                    ItemStateChanging(ref m, ref nmlv);
                }
            }
            base.WndProc(ref m);
        }
Пример #3
0
        private void ItemStateChanging(ref Message m, ref NMLISTVIEW nmlv)
        {
            if ((nmlv.uChanged & LVIF_STATE) == LVIF_STATE)
            {
                if ((nmlv.uOldState == LVIS_SELECTED) || //FROM ITEM
                    (nmlv.uNewState == LVIS_UNSELECTED))
                {
                    if (m_cancel)
                    {
                        m.Result = new IntPtr(1);
                        m_cancel = false;
                    }
                    else
                    {
                        if ((nmlv.uOldState == LVIS_SELECTED) && //FROM ITEM
                            (nmlv.uNewState == LVIS_UNSELECTED))
                        {
                            ItemChangingEventArgs e = new ItemChangingEventArgs(nmlv.iItem, this.Items[nmlv.iItem]);

                            OnItemDeselecting(e);
                            if (e.Cancel)
                            {
                                m.Result = new IntPtr(1);
                                m_cancel = true;
                            }
                        }
                    }
                }
                else if ((nmlv.uOldState == LVIS_UNSELECTED) || //TO ITEM
                         (nmlv.uNewState == LVIS_SELECTED) ||
                         (nmlv.uNewState == LVIS_SELECTED_FOCUSED))
                {
                    if (m_cancel)
                    {
                        m.Result = new IntPtr(1);
                        m_cancel = false;
                    }
                }
            }
        }
Пример #4
0
        protected override bool OnShellViewNotify(NMHDR nmhdr, ref Message msg)
        {
            // Process WM.NOTIFY.  These are all notifications from the
            // SysListView32 control.  We will not get ANY of these on
            // Windows 7, which means every single one of them has to
            // have an alternative somewhere for the ItemsView control,
            // or it's not going to happen.
            switch (nmhdr.code)
            {
            case -12:     // NM_CUSTOMDRAW
                // This is for drawing alternating row colors.  I doubt
                // very much we'll find an alternative for this...
                return(HandleCustomDraw(ref msg));

            case LVN.ITEMCHANGED: {
                // There are two things happening here.
                // 1. Notify plugins of selection changing: Handled through
                //    undocumented WM_USER+163 message
                // 2. Redraw for Full Row Select: Not happening

                /*
                 *  // TODO
                 *
                 *  IntPtr ptr;
                 *  if(QTUtility.instanceManager.TryGetButtonBarHandle(this.hwndExplorer, out ptr)) {
                 *      QTUtility2.SendCOPYDATASTRUCT(ptr, (IntPtr)13, null, (IntPtr)GetItemCount());
                 *  }
                 */
                bool       flag        = !QTUtility.IsXP && QTUtility.CheckConfig(Settings.ToggleFullRowSelect);
                NMLISTVIEW nmlistview2 = (NMLISTVIEW)Marshal.PtrToStructure(msg.LParam, typeof(NMLISTVIEW));
                if (nmlistview2.uChanged == 8 /*LVIF_STATE*/)
                {
                    uint num5  = nmlistview2.uNewState & LVIS.SELECTED;
                    uint num6  = nmlistview2.uOldState & LVIS.SELECTED;
                    uint num7  = nmlistview2.uNewState & LVIS.DROPHILITED;
                    uint num8  = nmlistview2.uOldState & LVIS.DROPHILITED;
                    uint num9  = nmlistview2.uNewState & LVIS.CUT;
                    uint num10 = nmlistview2.uOldState & LVIS.CUT;
                    if (flag)
                    {
                        if (nmlistview2.iItem != -1 && ((num5 != num6) || (num7 != num8) || (num9 != num10)) && ShellBrowser.ViewMode == FVM.DETAILS)
                        {
                            PInvoke.SendMessage(nmlistview2.hdr.hwndFrom, LVM.REDRAWITEMS, (IntPtr)nmlistview2.iItem, (IntPtr)nmlistview2.iItem);
                        }
                    }
                    if (num5 != num6)
                    {
                        OnSelectionChanged();
                    }
                }
                break;
            }

            case LVN.INSERTITEM:
            case LVN.DELETEITEM:
                // Handled through undocumented WM_USER+174 message
                if (!QTUtility.CheckConfig(Settings.NoShowSubDirTips))
                {
                    HideSubDirTip(1);
                }
                if (QTUtility.CheckConfig(Settings.AlternateRowColors) && (ShellBrowser.ViewMode == FVM.DETAILS))
                {
                    PInvoke.InvalidateRect(nmhdr.hwndFrom, IntPtr.Zero, true);
                }
                ShellViewController.DefWndProc(ref msg);
                OnItemCountChanged();
                return(true);

            case LVN.BEGINDRAG:
                // This won't be necessary it seems.  On Windows 7, when you
                // start to drag, a MOUSELEAVE message is sent, which hides
                // the SubDirTip anyway.
                ShellViewController.DefWndProc(ref msg);
                HideSubDirTip(0xff);
                return(true);

            case LVN.ITEMACTIVATE: {
                // Handled by catching Double Clicks and Enter keys.  Ugh...
                NMITEMACTIVATE nmitemactivate = (NMITEMACTIVATE)Marshal.PtrToStructure(msg.LParam, typeof(NMITEMACTIVATE));
                Keys           modKeys        =
                    (((nmitemactivate.uKeyFlags & 1) == 1) ? Keys.Alt : Keys.None) |
                    (((nmitemactivate.uKeyFlags & 2) == 2) ? Keys.Control : Keys.None) |
                    (((nmitemactivate.uKeyFlags & 4) == 4) ? Keys.Shift : Keys.None);
                if (OnItemActivated(modKeys))
                {
                    return(true);
                }
                break;
            }

            case LVN.ODSTATECHANGED:
                // FullRowSelect doesn't look possible anyway, so whatever.
                if (!QTUtility.IsXP && QTUtility.CheckConfig(Settings.ToggleFullRowSelect))
                {
                    NMLVODSTATECHANGE nmlvodstatechange = (NMLVODSTATECHANGE)Marshal.PtrToStructure(msg.LParam, typeof(NMLVODSTATECHANGE));
                    if (((nmlvodstatechange.uNewState & 2) == 2) && (ShellBrowser.ViewMode == FVM.DETAILS))
                    {
                        PInvoke.SendMessage(nmlvodstatechange.hdr.hwndFrom, LVM.REDRAWITEMS, (IntPtr)nmlvodstatechange.iFrom, (IntPtr)nmlvodstatechange.iTo);
                    }
                }
                break;

            case LVN.HOTTRACK:
                // Handled through WM_MOUSEMOVE.
                if (QTUtility.CheckConfig(Settings.ShowTooltipPreviews) || !QTUtility.CheckConfig(Settings.NoShowSubDirTips))
                {
                    NMLISTVIEW nmlistview = (NMLISTVIEW)Marshal.PtrToStructure(msg.LParam, typeof(NMLISTVIEW));
                    int        iItem      = CorrectHotItem(nmlistview.iItem);
                    if (iHotItem != iItem)
                    {
                        OnHotItemChanged(iItem);
                        iHotItem = iItem;
                    }
                }
                break;

            case LVN.KEYDOWN: {
                // Handled through WM_KEYDOWN.
                NMLVKEYDOWN nmlvkeydown = (NMLVKEYDOWN)Marshal.PtrToStructure(msg.LParam, typeof(NMLVKEYDOWN));
                if (OnKeyDown((Keys)nmlvkeydown.wVKey))
                {
                    msg.Result = (IntPtr)1;
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            case LVN.GETINFOTIP: {
                // Handled through WM_NOTIFY / TTN_NEEDTEXT
                NMLVGETINFOTIP nmlvgetinfotip = (NMLVGETINFOTIP)Marshal.PtrToStructure(msg.LParam, typeof(NMLVGETINFOTIP));
                return(OnGetInfoTip(nmlvgetinfotip.iItem, GetHotItem() != nmlvgetinfotip.iItem));    // TODO there's got to be a better way.
            }

            case LVN.BEGINLABELEDIT:
                // This is just for file renaming, which there's no need to
                // mess with in Windows 7.
                ShellViewController.DefWndProc(ref msg);
                if (QTUtility.IsXP && !QTUtility.CheckConfig(Settings.ExtWhileRenaming))
                {
                    NMLVDISPINFO nmlvdispinfo = (NMLVDISPINFO)Marshal.PtrToStructure(msg.LParam, typeof(NMLVDISPINFO));
                    if (nmlvdispinfo.item.lParam != IntPtr.Zero)
                    {
                        using (IDLWrapper idl = ShellBrowser.ILAppend(nmlvdispinfo.item.lParam)) {
                            OnFileRename(idl);
                        }
                    }
                }
                break;

            case LVN.ENDLABELEDIT: {
                // TODO
                NMLVDISPINFO nmlvdispinfo2 = (NMLVDISPINFO)Marshal.PtrToStructure(msg.LParam, typeof(NMLVDISPINFO));
                OnEndLabelEdit(nmlvdispinfo2.item);
                break;
            }
            }
            return(false);
        }
		/// <summary>
		/// LVNs the delete item.
		/// </summary>
		/// <param name="nmPtr">The nm PTR.</param>
		private void LvnDeleteItem(
			NMLISTVIEW nmPtr )
		{
			this.OnItemDeleted( EventArgs.Empty );
		}
		/// <summary>
		/// LVNs the insert item.
		/// </summary>
		/// <param name="nmPtr">The nm PTR.</param>
		private void LvnInsertItem(
			NMLISTVIEW nmPtr )
		{
			this.OnItemInserted( EventArgs.Empty );
		}
		/// <summary>
		/// Provide the events that MS has "forgotten" to implement.
		/// </summary>
		/// <param name="nmPtr">The nm PTR.</param>
		private void LvnItemChanged(
			NMLISTVIEW nmPtr )
		{
			if ( !(
				(this.Items.Count == 0) ||
				(this.Items[this.Items.Count - 1] != null)
				) )
			{
				this.OnSelectedIndexChanged( EventArgs.Empty );
			}
		}