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); }
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); }
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; } } } }
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 ); } }