Exemplo n.º 1
0
		protected override void OnMouseUp(MouseEventArgs e)
		{
			// Detect which column was clicked and handle accordingly
			const int LVM_FIRST = 0x1000;
			const int LVM_SUBITEMHITTEST = LVM_FIRST + 57;

			NativeMethods.LVHITTESTINFO hitInfo = new NativeMethods.LVHITTESTINFO();
			hitInfo.pt = new Point(e.X, e.Y);
			IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NativeMethods.LVHITTESTINFO)));
			Marshal.StructureToPtr(hitInfo, pointer, true);
			Message message = Message.Create(Handle, LVM_SUBITEMHITTEST, IntPtr.Zero, pointer);
			DefWndProc(ref message);
			hitInfo = (NativeMethods.LVHITTESTINFO)Marshal.PtrToStructure(
				pointer, typeof(NativeMethods.LVHITTESTINFO));
			Marshal.FreeHGlobal(pointer);

			if(hitInfo.iItem >=0 && hitInfo.iSubItem == 1)
			{
				// Flip the load on startup flag
				PluginListItem item = (PluginListItem)Items[hitInfo.iItem];
				item.PluginInfo.IsLoadedAtStartup = !item.PluginInfo.IsLoadedAtStartup;
				Invalidate();
				return;
			}

			base.OnMouseUp(e);
		}
Exemplo n.º 2
0
        /// <summary>
        /// Perform a hit test using the Windows control's SUBITEMHITTEST message.
        /// This provides information about group hits that the standard ListView.HitTest() does not.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        protected OlvListViewHitTestInfo LowLevelHitTest(int x, int y) {
            // If it's not even in the control, don't bother with anything else
            if (!this.ClientRectangle.Contains(x, y))
                return new OlvListViewHitTestInfo(null, null, 0, null);

            //if (Control.ModifierKeys == Keys.Control)
            //    System.Diagnostics.Debugger.Break();

            // Call the native hit test method, which is a little confusing.
            NativeMethods.LVHITTESTINFO lParam = new NativeMethods.LVHITTESTINFO();
            lParam.pt_x = x;
            lParam.pt_y = y;
            int index = NativeMethods.HitTest(this, ref lParam);

            // Setup the various values we need to make our hit test structure
            bool isGroupHit = (lParam.flags & (int)HitTestLocationEx.LVHT_EX_GROUP) != 0;
            OLVListItem hitItem = isGroupHit || index == -1 ? null : this.GetItem(index);
            OLVListSubItem subItem = (this.View == View.Details && hitItem != null) ? hitItem.GetSubItem(lParam.iSubItem) : null;

            // Figure out which group is involved in the hit test. This is a little complicated:
            // If the list is virtual:
            //   - the returned value is list view item index
            //   - iGroup is the *index* of the hit group.
            // If the list is not virtual:
            //   - iGroup is always -1.
            //   - if the point is over a group, the returned value is the *id* of the hit group.
            //   - if the point is not over a group, the returned value is list view item index.
            OLVGroup group = null;
            if (this.ShowGroups && this.OLVGroups != null) {
                if (this.VirtualMode) {
                    group = lParam.iGroup >= 0 && lParam.iGroup < this.OLVGroups.Count ? this.OLVGroups[lParam.iGroup] : null;
                } else {
                    if (isGroupHit) {
                        foreach (OLVGroup olvGroup in this.OLVGroups) {
                            if (olvGroup.GroupId == index) {
                                group = olvGroup;
                                break;
                            }
                        }
                    }
                }
            }
            OlvListViewHitTestInfo olvListViewHitTest = new OlvListViewHitTestInfo(hitItem, subItem, lParam.flags, group);
            // System.Diagnostics.Debug.WriteLine(String.Format("HitTest({0}, {1})=>{2}", x, y, olvListViewHitTest));
            return olvListViewHitTest;
        }
Exemplo n.º 3
0
        private unsafe void WmReflectNotify(ref Message m) {

            NativeMethods.NMHDR* nmhdr = (NativeMethods.NMHDR*)m.LParam;

            switch (nmhdr->code) {
                case NativeMethods.NM_CUSTOMDRAW:
                    CustomDraw(ref m);
                    break;

                case NativeMethods.LVN_BEGINLABELEDITA:
                case NativeMethods.LVN_BEGINLABELEDITW: {
                        NativeMethods.NMLVDISPINFO_NOTEXT nmlvdp = (NativeMethods.NMLVDISPINFO_NOTEXT)m.GetLParam(typeof(NativeMethods.NMLVDISPINFO_NOTEXT));
                        LabelEditEventArgs e = new LabelEditEventArgs(nmlvdp.item.iItem);
                        OnBeforeLabelEdit(e);
                        m.Result = (IntPtr)(e.CancelEdit ? 1 : 0);
                        listViewState[LISTVIEWSTATE_inLabelEdit] = !e.CancelEdit;
                        break;
                    }

                case NativeMethods.LVN_COLUMNCLICK: {
                        NativeMethods.NMLISTVIEW nmlv = (NativeMethods.NMLISTVIEW)m.GetLParam(typeof(NativeMethods.NMLISTVIEW));
                        listViewState[LISTVIEWSTATE_columnClicked] = true;
                        columnIndex = nmlv.iSubItem;
                        break;
                    }

                case NativeMethods.LVN_ENDLABELEDITA:
                case NativeMethods.LVN_ENDLABELEDITW: {
                        listViewState[LISTVIEWSTATE_inLabelEdit] = false;
                        NativeMethods.NMLVDISPINFO nmlvdp = (NativeMethods.NMLVDISPINFO)m.GetLParam(typeof(NativeMethods.NMLVDISPINFO));
                        LabelEditEventArgs e = new LabelEditEventArgs(nmlvdp.item.iItem, nmlvdp.item.pszText);
                        OnAfterLabelEdit(e);
                        m.Result = (IntPtr)(e.CancelEdit ? 0 : 1);
                        // from msdn:
                        //   "If the user cancels editing, the pszText member of the LVITEM structure is NULL"
                        if (!e.CancelEdit && nmlvdp.item.pszText != null)
                            Items[nmlvdp.item.iItem].Text = nmlvdp.item.pszText;
                        break;
                    }

                case NativeMethods.LVN_ITEMACTIVATE:
                    OnItemActivate(EventArgs.Empty);
                    break;

                case NativeMethods.LVN_BEGINDRAG: {
                    // the items collection was modified while dragging
                    // that means that we can't reliably give the user the item on which the dragging started
                    // so don't tell the user about this operation...
                    // vsWhidbey 235027
                    if (!this.ItemCollectionChangedInMouseDown) {
                        NativeMethods.NMLISTVIEW nmlv = (NativeMethods.NMLISTVIEW)m.GetLParam(typeof(NativeMethods.NMLISTVIEW));
                        LvnBeginDrag(MouseButtons.Left, nmlv);
                    }

                    break;
                }

                case NativeMethods.LVN_BEGINRDRAG: {
                    // the items collection was modified while dragging
                    // that means that we can't reliably give the user the item on which the dragging started
                    // so don't tell the user about this operation...
                    // vsWhidbey 235027
                    if (!this.ItemCollectionChangedInMouseDown) {
                        NativeMethods.NMLISTVIEW nmlv = (NativeMethods.NMLISTVIEW)m.GetLParam(typeof(NativeMethods.NMLISTVIEW));
                        LvnBeginDrag(MouseButtons.Right, nmlv);
                    }
                    break;
                }


                case NativeMethods.LVN_ITEMCHANGING: {
                        NativeMethods.NMLISTVIEW* nmlv = (NativeMethods.NMLISTVIEW*)m.LParam;
                        if ((nmlv->uChanged & NativeMethods.LVIF_STATE) != 0) {
                            // Because the state image mask is 1-based, a value of 1 means unchecked,
                            // anything else means checked.  We convert this to the more standard 0 or 1
                            CheckState oldState = (CheckState)(((nmlv->uOldState & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) == 1 ? 0 : 1);
                            CheckState newState = (CheckState)(((nmlv->uNewState & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) == 1 ? 0 : 1);

                            if (oldState != newState) {
                                ItemCheckEventArgs e = new ItemCheckEventArgs(nmlv->iItem, newState, oldState);
                                OnItemCheck(e);
                                m.Result = (IntPtr)(((int)e.NewValue == 0 ? 0 : 1) == (int)oldState ? 1 : 0);
                            }
                        }
                        break;
                    }

                case NativeMethods.LVN_ITEMCHANGED: {
                        NativeMethods.NMLISTVIEW* nmlv = (NativeMethods.NMLISTVIEW*)m.LParam;
                        // Check for state changes to the selected state...
                        if ((nmlv->uChanged & NativeMethods.LVIF_STATE) != 0) {
                            // Because the state image mask is 1-based, a value of 1 means unchecked,
                            // anything else means checked.  We convert this to the more standard 0 or 1
                            CheckState oldValue = (CheckState)(((nmlv->uOldState & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) == 1 ? 0 : 1);
                            CheckState newValue = (CheckState)(((nmlv->uNewState & NativeMethods.LVIS_STATEIMAGEMASK) >> 12) == 1 ? 0 : 1);

                            if (newValue != oldValue) {
                                ItemCheckedEventArgs e = new ItemCheckedEventArgs(Items[nmlv->iItem]);
                                OnItemChecked(e);
                            }

                            int oldState = nmlv->uOldState & NativeMethods.LVIS_SELECTED;
                            int newState = nmlv->uNewState & NativeMethods.LVIS_SELECTED;
                            // Windows common control always fires
                            // this event twice, once with newState, oldState, and again with
                            // oldState, newState.
                            // Changing this affects the behaviour as the control never
                            // fires the event on a Deselct of an Items from multiple selections.
                            // So leave it as it is...
                            if (newState != oldState) {
                                if (this.VirtualMode && nmlv->iItem == -1)
                                {
                                    if (this.VirtualListSize > 0) {
                                        ListViewVirtualItemsSelectionRangeChangedEventArgs lvvisrce = new ListViewVirtualItemsSelectionRangeChangedEventArgs(0, this.VirtualListSize-1, newState != 0);
                                        OnVirtualItemsSelectionRangeChanged(lvvisrce);
                                    }
                                }
                                else
                                {
                                    // APPCOMPAT
                                    // V1.* users implement virtualization by communicating directly to the native ListView and
                                    // by passing our virtualization implementation.
                                    // In that case, the native list view may have an item under the mouse even if our wrapper thinks the item count is 0.
                                    // And that may cause GetItemAt to throw an out of bounds exception.
                                    // See VSW 418791.

                                    if (this.Items.Count > 0) {
                                        ListViewItemSelectionChangedEventArgs lvisce = new ListViewItemSelectionChangedEventArgs(this.Items[nmlv->iItem],
                                                                                                                                 nmlv->iItem,
                                                                                                                                 newState != 0);
                                        OnItemSelectionChanged(lvisce);
                                    }
                                }
                                // VSWhidbey 549967 - Delay SelectedIndexChanged event because the last item isn't present yet.
                                if (this.Items.Count == 0 || this.Items[this.Items.Count - 1] != null)
                                {
                                    this.listViewState1[LISTVIEWSTATE1_selectedIndexChangedSkipped] = false;
                                    OnSelectedIndexChanged(EventArgs.Empty);
                                }
                                else
                                {
                                    this.listViewState1[LISTVIEWSTATE1_selectedIndexChangedSkipped] = true;
                                }
                            }
                        }
                        break;
                    }

                case NativeMethods.NM_CLICK:
                    WmNmClick(ref m);
                    // FALL THROUGH //
                    goto case NativeMethods.NM_RCLICK;

                case NativeMethods.NM_RCLICK:
                    NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();
                    int displayIndex = GetIndexOfClickedItem(lvhi);

                    MouseButtons button = nmhdr->code == NativeMethods.NM_CLICK ? MouseButtons.Left : MouseButtons.Right;
                    Point pos = Cursor.Position;
                    pos = PointToClientInternal(pos);

                    if (!ValidationCancelled && displayIndex != -1) {
                        OnClick(EventArgs.Empty);
                        OnMouseClick(new MouseEventArgs(button, 1, pos.X, pos.Y, 0));
                    }
                    if (!listViewState[LISTVIEWSTATE_mouseUpFired])
                    {
                        OnMouseUp(new MouseEventArgs(button, 1, pos.X, pos.Y, 0));
                        listViewState[LISTVIEWSTATE_mouseUpFired] = true;
                    }
                    break;

                case NativeMethods.NM_DBLCLK:
                    WmNmDblClick(ref m);
                    // FALL THROUGH //
                    goto case NativeMethods.NM_RDBLCLK;

                case NativeMethods.NM_RDBLCLK:
                    NativeMethods.LVHITTESTINFO lvhip = new NativeMethods.LVHITTESTINFO();
                    int index = GetIndexOfClickedItem(lvhip);

                    if (index != -1) {
                        //just maintain state and fire double click.. in final mouseUp...
                        listViewState[LISTVIEWSTATE_doubleclickFired] = true;
                    }
                    //fire Up in the Wndproc !!
                    listViewState[LISTVIEWSTATE_mouseUpFired] = false;
                    //problem getting the UP... outside the control...
                    //
                    CaptureInternal = true;
                    break;

                case NativeMethods.LVN_KEYDOWN:
                    if (CheckBoxes) {
                        NativeMethods.NMLVKEYDOWN lvkd = (NativeMethods.NMLVKEYDOWN)m.GetLParam(typeof(NativeMethods.NMLVKEYDOWN));
                        if (lvkd.wVKey == (short)Keys.Space) {
                            ListViewItem focusedItem = FocusedItem;
                            if (focusedItem != null) {
                                bool check = !focusedItem.Checked;
                                if (!VirtualMode) {
                                    foreach(ListViewItem item in SelectedItems) {
                                        if (item != focusedItem) {
                                            item.Checked = check;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;

                case NativeMethods.LVN_ODCACHEHINT:
                    // tell the user to prepare the cache:
                    NativeMethods.NMLVCACHEHINT cacheHint = (NativeMethods.NMLVCACHEHINT) m.GetLParam(typeof(NativeMethods.NMLVCACHEHINT));
                    OnCacheVirtualItems(new CacheVirtualItemsEventArgs(cacheHint.iFrom, cacheHint.iTo));
                    break;

                default:
                    if (nmhdr->code == NativeMethods.LVN_GETDISPINFO) {
                        // we use the LVN_GETDISPINFO message only in virtual mode
                        if (this.VirtualMode && m.LParam != IntPtr.Zero) {
                            // we HAVE to use unsafe code because of a bug in the CLR: WHIDBEY bug 20313
                            NativeMethods.NMLVDISPINFO_NOTEXT dispInfo= (NativeMethods.NMLVDISPINFO_NOTEXT) m.GetLParam(typeof(NativeMethods.NMLVDISPINFO_NOTEXT));

                            RetrieveVirtualItemEventArgs rVI = new RetrieveVirtualItemEventArgs(dispInfo.item.iItem);
                            OnRetrieveVirtualItem(rVI);
                            ListViewItem lvItem = rVI.Item;
                            if (lvItem == null)
                            {
                                throw new InvalidOperationException(SR.GetString(SR.ListViewVirtualItemRequired));
                            }

                            lvItem.SetItemIndex(this, dispInfo.item.iItem);
                            if ((dispInfo.item.mask & NativeMethods.LVIF_TEXT) != 0) {
                                string text;
                                if (dispInfo.item.iSubItem == 0) {
                                    text = lvItem.Text;                                         // we want the item
                                }
                                else {
                                    if (lvItem.SubItems.Count <= dispInfo.item.iSubItem) {
                                        throw new InvalidOperationException(SR.GetString(SR.ListViewVirtualModeCantAccessSubItem));
                                    }
                                    else {
                                        text = lvItem.SubItems[dispInfo.item.iSubItem].Text;            // we want the sub item
                                    }
                                }

                                // use the buffer provided by the ComCtrl list view.
                                if (dispInfo.item.cchTextMax <= text.Length) {
                                    text = text.Substring(0, dispInfo.item.cchTextMax - 1);
                                }

                                if (Marshal.SystemDefaultCharSize == 1) {
                                    // ANSI. Use byte
                                    byte[] buff = System.Text.Encoding.Default.GetBytes(text + "\0");
                                    Marshal.Copy(buff, 0, dispInfo.item.pszText, text.Length + 1);
                                } else {
                                    char[] buff = (text + "\0").ToCharArray();
                                    Marshal.Copy(buff, 0, dispInfo.item.pszText, text.Length + 1);
                                }
                            }

                            if ((dispInfo.item.mask & NativeMethods.LVIF_IMAGE) != 0 && lvItem.ImageIndex != -1) {
                                dispInfo.item.iImage = lvItem.ImageIndex;
                            }

                            if ((dispInfo.item.mask & NativeMethods.LVIF_INDENT) != 0) {
                                dispInfo.item.iIndent = lvItem.IndentCount;
                            }

                            /* [....]: Couldn't make this work. The dispInfo.item.iSubItem received for the subitems' text
                                       are invalid
                            if ((dispInfo.item.mask & NativeMethods.LVIF_COLUMNS) != 0) {
                                int cColumns = this.columnHeaders != null ? this.columnHeaders.Length : 0;
                                dispInfo.item.cColumns = cColumns;
                                if (cColumns > 0) {
                                    dispInfo.item.puColumns = Marshal.AllocHGlobal(cColumns * Marshal.SizeOf(typeof(int)));
                                    int[] columns = new int[cColumns];
                                    for (int c = 0; c < cColumns; c++) {
                                        columns[c] = c + 1;
                                    }
                                    Marshal.Copy(columns, 0, dispInfo.item.puColumns, cColumns);
                                }
                            }
                            */

                            /* [....]: VirtualMode and grouping seem to be incompatible.
                                       dispInfo.item.mask never includes NativeMethods.LVIF_GROUPID.
                                       Besides, trying to send LVM_ENABLEGROUPVIEW to the listview fails in virtual mode.
                            if (this.GroupsEnabled && (dispInfo.item.mask & NativeMethods.LVIF_GROUPID) != 0)
                            {
                                dispInfo.item.iGroupId = GetNativeGroupId(lvItem);
                                #if DEBUG
                                    Debug.Assert(SendMessage(NativeMethods.LVM_ISGROUPVIEWENABLED, 0, 0) != IntPtr.Zero, "Groups not enabled");
                                    Debug.Assert(SendMessage(NativeMethods.LVM_HASGROUP, dispInfo.item.iGroupId, 0) != IntPtr.Zero, "Doesn't contain group id: " + dispInfo.item.iGroupId.ToString(CultureInfo.InvariantCulture));
                                #endif
                            }
                            */

                            if ((dispInfo.item.stateMask & NativeMethods.LVIS_STATEIMAGEMASK) != 0) {
                                dispInfo.item.state |= lvItem.RawStateImageIndex;
                            }
                            Marshal.StructureToPtr(dispInfo, (IntPtr) m.LParam, false);

                        }
                    }
                    else if (nmhdr->code == NativeMethods.LVN_ODSTATECHANGED) {
                        if (VirtualMode && m.LParam != IntPtr.Zero) {
                            NativeMethods.NMLVODSTATECHANGE odStateChange = (NativeMethods.NMLVODSTATECHANGE) m.GetLParam(typeof(NativeMethods.NMLVODSTATECHANGE));
                            bool selectedChanged = (odStateChange.uNewState & NativeMethods.LVIS_SELECTED) != (odStateChange.uOldState & NativeMethods.LVIS_SELECTED);
                            if (selectedChanged) {
                                // we have to substract 1 from iTo due to an imbecility in the win32 ListView control
                                // see vsWhidbey 275717 - especially the ListView_CalcMinMaxIndex method.
                                // in Vista, 275717 is fixed in windows OS side, we have don't need to work around here any more.
                                int iTo = odStateChange.iTo;
                                if (!UnsafeNativeMethods.IsVista) {
                                    iTo--;
                                }
                                ListViewVirtualItemsSelectionRangeChangedEventArgs lvvisrce = new ListViewVirtualItemsSelectionRangeChangedEventArgs(odStateChange.iFrom, iTo, (odStateChange.uNewState & NativeMethods.LVIS_SELECTED) != 0);
                                OnVirtualItemsSelectionRangeChanged(lvvisrce);
                            }
                        }
                    }
                    else if (nmhdr->code == NativeMethods.LVN_GETINFOTIP) {
                        if (ShowItemToolTips && m.LParam != IntPtr.Zero) {
                            NativeMethods.NMLVGETINFOTIP infoTip = (NativeMethods.NMLVGETINFOTIP) m.GetLParam(typeof(NativeMethods.NMLVGETINFOTIP));
                            ListViewItem lvi = Items[infoTip.item];
                            if (lvi != null && !string.IsNullOrEmpty(lvi.ToolTipText)) {

                                // MSDN:
                                // Setting the max width has the added benefit of enabling multiline
                                // tool tips!
                                //
                                
                                UnsafeNativeMethods.SendMessage(new HandleRef(this, nmhdr->hwndFrom), NativeMethods.TTM_SETMAXTIPWIDTH, 0, SystemInformation.MaxWindowTrackSize.Width);

                                if (Marshal.SystemDefaultCharSize == 1) {
                                    // ANSI. Use byte.
                                    // we need to copy the null terminator character ourselves
                                    byte[] byteBuf = System.Text.Encoding.Default.GetBytes(lvi.ToolTipText + "\0");
                                    Marshal.Copy(byteBuf, 0, infoTip.lpszText, Math.Min(byteBuf.Length, infoTip.cchTextMax));
                                } else {
                                    // UNICODE. Use char.
                                    // we need to copy the null terminator character ourselves
                                    char[] charBuf = (lvi.ToolTipText + "\0").ToCharArray();
                                    Marshal.Copy(charBuf, 0, infoTip.lpszText, Math.Min(charBuf.Length, infoTip.cchTextMax));
                                }
                                Marshal.StructureToPtr(infoTip, (IntPtr) m.LParam, false);
                            }
                        }
                    }
                    else if (nmhdr->code == NativeMethods.LVN_ODFINDITEM) {
                        if (VirtualMode) {
                            NativeMethods.NMLVFINDITEM nmlvif = (NativeMethods.NMLVFINDITEM) m.GetLParam(typeof(NativeMethods.NMLVFINDITEM));

                            if ((nmlvif.lvfi.flags & NativeMethods.LVFI_PARAM) != 0) {
                                m.Result = (IntPtr) (-1);
                                return;
                            }

                            bool isTextSearch = ((nmlvif.lvfi.flags & NativeMethods.LVFI_STRING) != 0) ||
                                                ((nmlvif.lvfi.flags & NativeMethods.LVFI_PARTIAL) != 0);

                            bool isPrefixSearch = (nmlvif.lvfi.flags & NativeMethods.LVFI_PARTIAL) != 0;

                            string text = String.Empty;
                            if (isTextSearch) {
                                text = nmlvif.lvfi.psz;
                            }

                            Point startingPoint = Point.Empty;
                            if ((nmlvif.lvfi.flags & NativeMethods.LVFI_NEARESTXY) != 0) {
                                startingPoint = new Point(nmlvif.lvfi.ptX, nmlvif.lvfi.ptY);
                            }

                            SearchDirectionHint dir = SearchDirectionHint.Down;
                            if ((nmlvif.lvfi.flags & NativeMethods.LVFI_NEARESTXY) != 0) {
                                // We can do this because SearchDirectionHint is set to the VK_*
                                dir = (SearchDirectionHint) nmlvif.lvfi.vkDirection;
                            }

                            int startIndex = nmlvif.iStart;
                            if (startIndex >= this.VirtualListSize) {
                                // we want to search starting from the last item. Wrap around the first item.
                                startIndex = 0;
                            }


                            SearchForVirtualItemEventArgs sviEvent = new SearchForVirtualItemEventArgs(
                                                                         isTextSearch,
                                                                         isPrefixSearch,
                                                                         false, /* includeSubItemsInSearch */
                                                                         text,
                                                                         startingPoint,
                                                                         dir,
                                                                         nmlvif.iStart);

                            OnSearchForVirtualItem(sviEvent);
                            if (sviEvent.Index != -1) {
                                m.Result = (IntPtr) sviEvent.Index;
                            } else {
                                m.Result = (IntPtr) (-1);
                            }
                        }
                    }
                break;
            }
        }
Exemplo n.º 4
0
        protected override void WndProc(ref Message m) {

            switch (m.Msg) {
                case NativeMethods.WM_REFLECT + NativeMethods.WM_NOTIFY:
                    WmReflectNotify(ref m);
                    break;
                case NativeMethods.WM_LBUTTONDBLCLK:

                    // Ensure that the itemCollectionChangedInMouseDown is not set
                    // before processing the mousedown event.  
                    this.ItemCollectionChangedInMouseDown = false;
                    CaptureInternal = true;
                    WmMouseDown(ref m, MouseButtons.Left, 2);
                    break;

                case NativeMethods.WM_LBUTTONDOWN:

                    // Ensure that the itemCollectionChangedInMouseDown is not set
                    // before processing the mousedown event.  
                    this.ItemCollectionChangedInMouseDown = false;
                    WmMouseDown(ref m, MouseButtons.Left, 1);
                    downButton = MouseButtons.Left;
                    break;

                case NativeMethods.WM_LBUTTONUP:
                case NativeMethods.WM_RBUTTONUP:
                case NativeMethods.WM_MBUTTONUP:

                    // see the mouse is on item
                    //
                    NativeMethods.LVHITTESTINFO lvhip = new NativeMethods.LVHITTESTINFO();
                    int index = GetIndexOfClickedItem(lvhip);

                    if (!ValidationCancelled && listViewState[LISTVIEWSTATE_doubleclickFired] && index != -1) {
                        listViewState[LISTVIEWSTATE_doubleclickFired] = false;
                        OnDoubleClick(EventArgs.Empty);
                        OnMouseDoubleClick(new MouseEventArgs(downButton, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                    }
                    if (!listViewState[LISTVIEWSTATE_mouseUpFired])
                    {
                        OnMouseUp(new MouseEventArgs(downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                        listViewState[LISTVIEWSTATE_expectingMouseUp] = false;
                    }

                    this.ItemCollectionChangedInMouseDown = false;

                    listViewState[LISTVIEWSTATE_mouseUpFired] = true;
                    CaptureInternal = false;
                    break;
                case NativeMethods.WM_MBUTTONDBLCLK:
                    WmMouseDown(ref m, MouseButtons.Middle, 2);
                    break;
                case NativeMethods.WM_MBUTTONDOWN:
                    WmMouseDown(ref m, MouseButtons.Middle, 1);
                    downButton = MouseButtons.Middle;
                    break;
                case NativeMethods.WM_RBUTTONDBLCLK:
                    WmMouseDown(ref m, MouseButtons.Right, 2);
                    break;
                case NativeMethods.WM_RBUTTONDOWN:
                    WmMouseDown(ref m, MouseButtons.Right, 1);
                    downButton = MouseButtons.Right;
                    break;
                case NativeMethods.WM_MOUSEMOVE:
                    if (listViewState[LISTVIEWSTATE_expectingMouseUp] && !listViewState[LISTVIEWSTATE_mouseUpFired] && MouseButtons == MouseButtons.None)
                    {
                        OnMouseUp(new MouseEventArgs(downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                        listViewState[LISTVIEWSTATE_mouseUpFired] = true;
                    }
                    CaptureInternal = false;
                    base.WndProc(ref m);
                    break;
                case NativeMethods.WM_MOUSEHOVER:
                    if (HoverSelection) {
                        base.WndProc(ref m);
                    }
                    else
                        OnMouseHover(EventArgs.Empty);
                    break;
                case NativeMethods.WM_NOTIFY:
                    if(WmNotify(ref m))
                    {
                        break; // we are done - skip default handling
                    }
                    else
                    {
                        goto default;  //default handling needed
                    }
                case NativeMethods.WM_SETFOCUS:
                    base.WndProc(ref m);

                    if (!this.RecreatingHandle && !this.ListViewHandleDestroyed) {
                        // This means that we get a WM_SETFOCUS on the hWnd that was destroyed.
                        // Don't do anything because the information on the previous hWnd is most likely
                        // out of [....] w/ the information in our ListView wrapper.
                        // See comment in vsw 451268.

                        // We should set focus to the first item,
                        // if none of the items are focused already.
                        if (FocusedItem == null && Items.Count > 0)
                        {
                            Items[0].Focused = true;
                        }
                    }
                    break;
                case NativeMethods.WM_MOUSELEAVE:
                    // if the mouse leaves and then re-enters the ListView
                    // ItemHovered events should be raised.
                    prevHoveredItem = null;
                    base.WndProc(ref m);
                    break;

                case NativeMethods.WM_PAINT:
                    base.WndProc(ref m);

                    // win32 ListView - look for comments about vsWhidbey 243708
                    BeginInvoke(new MethodInvoker(this.CleanPreviousBackgroundImageFiles));
                    break;
                case NativeMethods.WM_PRINT:
                    WmPrint(ref m);
                    break;
                case NativeMethods.WM_TIMER:
                    if (unchecked( (int) (long)m.WParam) != LVTOOLTIPTRACKING || !ComctlSupportsVisualStyles) {
                        base.WndProc(ref m);
                    }
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            };
        }
Exemplo n.º 5
0
        private void WmNmClick(ref Message m) {

            // If we're checked, hittest to see if we're
            // on the check mark

            if (CheckBoxes) {
                Point pos = Cursor.Position;
                pos = PointToClientInternal(pos);
                NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();

                lvhi.pt_x = pos.X;
                lvhi.pt_y = pos.Y;

                int displayIndex = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.LVM_HITTEST, 0, lvhi);
                if (displayIndex != -1 && (lvhi.flags & NativeMethods.LVHT_ONITEMSTATEICON) != 0) {
                    ListViewItem clickedItem = Items[displayIndex];
                    if (clickedItem.Selected) {
                        bool check = !clickedItem.Checked;
                        if (!VirtualMode) {
                            foreach(ListViewItem item in SelectedItems) {
                                if (item != clickedItem) {
                                    item.Checked = check;
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        private void WmNmDblClick(ref Message m) {

            // If we're checked, hittest to see if we're
            // on the item

            if (CheckBoxes) {
                Point pos = Cursor.Position;
                pos = PointToClientInternal(pos);
                NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();

                lvhi.pt_x = pos.X;
                lvhi.pt_y = pos.Y;

                int displayIndex = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.LVM_HITTEST, 0, lvhi);
                if (displayIndex != -1 && (lvhi.flags & NativeMethods.LVHT_ONITEM) != 0) {
                    ListViewItem clickedItem = Items[displayIndex];
                    clickedItem.Checked = !clickedItem.Checked;
                }
            }
        }
Exemplo n.º 7
0
        /// <include file='doc\ListView.uex' path='docs/doc[@for="ListView.HitTest1"]/*' />
        /// <devdoc>
        /// </devdoc>
        public ListViewHitTestInfo HitTest(int x, int y) {
            if (!this.ClientRectangle.Contains(x, y)) {
                return new ListViewHitTestInfo(null /*hitItem*/, null /*hitSubItem*/, ListViewHitTestLocations.None /*hitLocation*/);
            }

            NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();
            lvhi.pt_x = x;
            lvhi.pt_y = y;

            int iItem;

            if (this.View == View.Details) {
                iItem = unchecked( (int) (long)UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.LVM_SUBITEMHITTEST, 0, lvhi));
            } else {
                iItem = unchecked( (int) (long)UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.LVM_HITTEST, 0, lvhi));
            }

            ListViewItem item = (iItem == -1) ? null : Items[iItem];
            ListViewHitTestLocations location = ListViewHitTestLocations.None;

            if (item == null && (NativeMethods.LVHT_ABOVE & lvhi.flags) == NativeMethods.LVHT_ABOVE) {
                location = (ListViewHitTestLocations)((MASK_HITTESTFLAG & lvhi.flags) | (int)ListViewHitTestLocations.AboveClientArea);
            }
            else if (item != null && (NativeMethods.LVHT_ONITEMSTATEICON & lvhi.flags) == NativeMethods.LVHT_ONITEMSTATEICON) {
                location = (ListViewHitTestLocations)((MASK_HITTESTFLAG & lvhi.flags) | (int)ListViewHitTestLocations.StateImage);
            }
            else {
                location = (ListViewHitTestLocations)lvhi.flags;
            }

            if (this.View == View.Details && item != null) {
                if (lvhi.iSubItem < item.SubItems.Count) {
                    return new ListViewHitTestInfo(item, item.SubItems[lvhi.iSubItem], location);
                } else {
                    return new ListViewHitTestInfo(item, null, location);
                }
            } else {
                return (new ListViewHitTestInfo(item, null, location));
            }
        }
Exemplo n.º 8
0
        internal void GetSubItemAt(int x, int y, out int iItem, out int iSubItem) {
            NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();

            lvhi.pt_x = x;
            lvhi.pt_y = y;

            int index = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.LVM_SUBITEMHITTEST, 0, lvhi);

            if (index > -1) {
                iItem = lvhi.iItem;
                iSubItem = lvhi.iSubItem;
            } else {
                iItem = -1;
                iSubItem = -1;
            }
        }
Exemplo n.º 9
0
        /// <include file='doc\ListView.uex' path='docs/doc[@for="ListView.GetItemAt"]/*' />
        /// <devdoc>
        ///     Returns the current ListViewItem corresponding to the specific
        ///     x,y co-ordinate.
        /// </devdoc>
        public ListViewItem GetItemAt(int x, int y) {
            NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();

            lvhi.pt_x = x;
            lvhi.pt_y = y;

            int displayIndex = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.LVM_HITTEST, 0, lvhi);

            ListViewItem li = null;
            if (displayIndex >= 0 && ((lvhi.flags & NativeMethods.LVHT_ONITEM) != 0))
                li = Items[displayIndex];

            return li;
        }
Exemplo n.º 10
0
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
            case NativeMethods.WM_PAINT:
                _isInWmPaintMsg = true;
                base.WndProc(ref m);
                _isInWmPaintMsg = false;
                break;

            case NativeMethods.WM_REFLECT_NOTIFY:
                var nmhdr = (NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR));
                if (nmhdr.code == -12)
                {
                    // NM_CUSTOMDRAW
                    if (_isInWmPaintMsg)
                    {
                        base.WndProc(ref m);
                    }
                }
                else
                {
                    base.WndProc(ref m);
                }

                break;

            case NativeMethods.WM_LBUTTONUP:
            case NativeMethods.WM_LBUTTONDOWN:
            {
                if (IsListViewGroupClickHandled((uint)m.LParam, MouseButtons.Left))
                {
                    return;
                }

                base.WndProc(ref m);
                break;
            }

            case NativeMethods.WM_RBUTTONUP:
            case NativeMethods.WM_RBUTTONDOWN:
            {
                if (IsListViewGroupClickHandled((uint)m.LParam, MouseButtons.Right))
                {
                    return;
                }

                base.WndProc(ref m);
                break;
            }

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

            bool IsListViewGroupClickHandled(uint lparam, MouseButtons button)
            {
                var info = new NativeMethods.LVHITTESTINFO
                {
                    pt = NativeMethods.LParamToPOINT(lparam)
                };

                var handleRef = new HandleRef(this, Handle);

                if (NativeMethods.SendMessage(handleRef, NativeMethods.LVM_SUBITEMHITTEST, (IntPtr)(-1), ref info) == new IntPtr(-1))
                {
                    return(false);
                }

                if ((info.flags & NativeMethods.LVHITTESTFLAGS.LVHT_EX_GROUP_HEADER) == 0)
                {
                    return(false);
                }

                foreach (ListViewGroup group in Groups)
                {
                    var groupId = GetGroupId(group);
                    if (info.iItem == groupId)
                    {
                        GroupMouseClick?.Invoke(this, new ListViewGroupMouseEventArgs(button, group, 1, info.pt.X, info.pt.Y, 0));
                        return(true);
                    }
                }

                return(false);
            }
        }
Exemplo n.º 11
0
 public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, NativeMethods.LVHITTESTINFO lParam);