Пример #1
0
        protected override void WndProc(ref Message m) {
            switch (m.Msg) {
                case NativeMethods.WM_WINDOWPOSCHANGING:
                case NativeMethods.WM_NCCALCSIZE:
                case NativeMethods.WM_WINDOWPOSCHANGED:
                case NativeMethods.WM_SIZE:
                    // While we are changing size of treeView to avoid the scrollbar; dont respond to the window-sizing messages.
                    if (treeViewState[TREEVIEWSTATE_stopResizeWindowMsgs])
                    {
                        //Debug.WriteLineIf(treeViewState[TREEVIEWSTATE_stopResizeWindowMsgs], "Sending message directly to DefWndProc() : " + m.ToString());
                        DefWndProc(ref m);
                    }
                    else
                    {
                        base.WndProc(ref m);
                    }
                    break;                        
               case NativeMethods.WM_HSCROLL:
                    base.WndProc(ref m);
                    if (DrawMode == TreeViewDrawMode.OwnerDrawAll)
                    {
                        //VsW : 432718
                        Invalidate();
                    }
                    break;

        case NativeMethods.WM_PRINT:
            WmPrint(ref m);
            break;
                case NativeMethods.TVM_SETITEMA:
                case NativeMethods.TVM_SETITEMW:
                    base.WndProc(ref m);
                    if (this.CheckBoxes) {
                        NativeMethods.TV_ITEM item = (NativeMethods.TV_ITEM) m.GetLParam(typeof(NativeMethods.TV_ITEM));
                        // Check for invalid node handle
                        if (item.hItem != IntPtr.Zero) {
                            NativeMethods.TV_ITEM item1 = new NativeMethods.TV_ITEM();
                            item1.mask = NativeMethods.TVIF_HANDLE | NativeMethods.TVIF_STATE;
                            item1.hItem = item.hItem;
                            item1.stateMask = NativeMethods.TVIS_STATEIMAGEMASK;
                            UnsafeNativeMethods.SendMessage(new HandleRef(null, this.Handle), NativeMethods.TVM_GETITEM, 0, ref item1);

                            TreeNode node = NodeFromHandle(item.hItem);
                            node.CheckedStateInternal = ((item1.state >> 12) > 1);
                        }
                    }
                    break;
                case NativeMethods.WM_NOTIFY:
                    NativeMethods.NMHDR nmhdr = (NativeMethods.NMHDR) m.GetLParam(typeof(NativeMethods.NMHDR));
                    switch (nmhdr.code) {
                        case NativeMethods.TTN_GETDISPINFOA:
                        case NativeMethods.TTN_GETDISPINFOW:
                            // MSDN:
                            // Setting the max width has the added benefit of enabling multiline
                            // tool tips!
                            //
                            UnsafeNativeMethods.SendMessage(new HandleRef(nmhdr, nmhdr.hwndFrom), NativeMethods.TTM_SETMAXTIPWIDTH, 0, SystemInformation.MaxWindowTrackSize.Width);
                            WmNeedText(ref m);
                            m.Result = (IntPtr)1;
                            return;
						case NativeMethods.TTN_SHOW:
                            if (WmShowToolTip(ref m))
                            {
                                m.Result = (IntPtr)1;
                                return;  
                            }
                            else
                            {
                                base.WndProc(ref m);
                                break;
                            }
                            
                        default:
                             base.WndProc(ref m);
                             break;
                    }
                    break;
                case NativeMethods.WM_REFLECT + NativeMethods.WM_NOTIFY:
                        WmNotify(ref m);
                        break;
                case NativeMethods.WM_LBUTTONDBLCLK:
                    WmMouseDown(ref m, MouseButtons.Left, 2);
                    //just maintain state and fire double click.. in final mouseUp...
                    treeViewState[TREEVIEWSTATE_doubleclickFired] = true;
                    //fire Up in the Wndproc !!
                    treeViewState[TREEVIEWSTATE_mouseUpFired] = false;
                    //problem getting the UP... outside the control...
                    //
                    CaptureInternal = true;
                    break;
                case NativeMethods.WM_LBUTTONDOWN:
                    try
                    {
                        treeViewState[TREEVIEWSTATE_ignoreSelects] = true;
                        FocusInternal();
                    }
                    finally
                    {
                       treeViewState[ TREEVIEWSTATE_ignoreSelects] = false;
                    }
                    //Always Reset the MouseupFired....
                    treeViewState[TREEVIEWSTATE_mouseUpFired] = false;
                    NativeMethods.TV_HITTESTINFO tvhip = new NativeMethods.TV_HITTESTINFO();
                    tvhip.pt_x = NativeMethods.Util.SignedLOWORD(m.LParam);
                    tvhip.pt_y = NativeMethods.Util.SignedHIWORD(m.LParam);
                    hNodeMouseDown = UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TVM_HITTEST, 0, tvhip);

                    // This gets around the TreeView behavior of temporarily moving the selection
                    // highlight to a node when the user clicks on its checkbox.
                    if ((tvhip.flags & NativeMethods.TVHT_ONITEMSTATEICON) != 0) {
                        //We donot pass the Message to the Control .. so fire MouseDowm ...
                        OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                        if (!ValidationCancelled && CheckBoxes)
                        {
                            TreeNode node = NodeFromHandle(hNodeMouseDown);
                            bool eventReturn = TreeViewBeforeCheck(node, TreeViewAction.ByMouse);
                            if (!eventReturn && node != null) {
                                node.CheckedInternal = !node.CheckedInternal;
                                TreeViewAfterCheck(node, TreeViewAction.ByMouse);
                            }
                        }
                        m.Result = IntPtr.Zero;
                    }
                    else {
                        WmMouseDown(ref m, MouseButtons.Left, 1);
                    }
                    downButton = MouseButtons.Left;
                    break;
                case NativeMethods.WM_LBUTTONUP:
                case NativeMethods.WM_RBUTTONUP:
                    NativeMethods.TV_HITTESTINFO tvhi = new NativeMethods.TV_HITTESTINFO();
                    tvhi.pt_x = NativeMethods.Util.SignedLOWORD(m.LParam);
                    tvhi.pt_y = NativeMethods.Util.SignedHIWORD(m.LParam);
                    IntPtr hnode = UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TVM_HITTEST, 0, tvhi);
                    //Important for CheckBoxes ... click needs to be fired ...
                    //
                    if(hnode != IntPtr.Zero) {
                        if (!ValidationCancelled && !treeViewState[TREEVIEWSTATE_doubleclickFired] & !treeViewState[TREEVIEWSTATE_mouseUpFired]) {
                            //OnClick(EventArgs.Empty);

                            //If the hit-tested node here is the same as the node we hit-tested
                            //on mouse down then we will fire our OnNodeMoseClick event.
                            if (hnode == hNodeMouseDown) {
                                OnNodeMouseClick(new TreeNodeMouseClickEventArgs(NodeFromHandle(hnode), downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam)));
                            }
                            
                            OnClick(new MouseEventArgs(downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                            OnMouseClick(new MouseEventArgs(downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                        }

                        if (treeViewState[TREEVIEWSTATE_doubleclickFired]) {
                            treeViewState[TREEVIEWSTATE_doubleclickFired] = false;
                            if (!ValidationCancelled) {
                                 //OnDoubleClick(EventArgs.Empty);
                                 OnNodeMouseDoubleClick(new TreeNodeMouseClickEventArgs(NodeFromHandle(hnode), downButton, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam)));
                                 OnDoubleClick(new MouseEventArgs(downButton, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                                 OnMouseDoubleClick(new MouseEventArgs(downButton, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                            }
                        }
                    }
                    if (!treeViewState[TREEVIEWSTATE_mouseUpFired])
                        OnMouseUp(new MouseEventArgs(downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                    treeViewState[TREEVIEWSTATE_doubleclickFired] = false;
                    treeViewState[TREEVIEWSTATE_mouseUpFired] = false;
                    CaptureInternal = false;

                    //always clear our hit-tested node we cached on mouse down
                    hNodeMouseDown = IntPtr.Zero;
                    break;
                case NativeMethods.WM_MBUTTONDBLCLK:
                    //fire Up in the Wndproc !!
                    treeViewState[TREEVIEWSTATE_mouseUpFired] = false;
                    WmMouseDown(ref m, MouseButtons.Middle, 2);
                    break;
                case NativeMethods.WM_MBUTTONDOWN:
                    //Always Reset the MouseupFired....
                    treeViewState[TREEVIEWSTATE_mouseUpFired] = false;
                    WmMouseDown(ref m, MouseButtons.Middle, 1);
                    downButton = MouseButtons.Middle;
                    break;
                case NativeMethods.WM_MOUSELEAVE:
                    // if the mouse leaves and then reenters the TreeView
                    // NodeHovered events should be raised.
                    prevHoveredNode = null;
                    base.WndProc(ref m);
                    break;
                case NativeMethods.WM_RBUTTONDBLCLK:
                    WmMouseDown(ref m, MouseButtons.Right, 2);
                    //just maintain state and fire double click.. in final mouseUp...
                    treeViewState[TREEVIEWSTATE_doubleclickFired] = true;
                    //fire Up in the Wndproc !!
                    treeViewState[TREEVIEWSTATE_mouseUpFired] = false;
                    //problem getting the UP... outside the control...
                    //
                    CaptureInternal = true;
                    break;
                case NativeMethods.WM_RBUTTONDOWN:
                    //Always Reset the MouseupFired....
                    treeViewState[TREEVIEWSTATE_mouseUpFired] = false;
                    //Cache the hit-tested node for verification when mouse up is fired
                    NativeMethods.TV_HITTESTINFO tvhit = new NativeMethods.TV_HITTESTINFO();
                    tvhit.pt_x = NativeMethods.Util.SignedLOWORD(m.LParam);
                    tvhit.pt_y = NativeMethods.Util.SignedHIWORD(m.LParam);
                    hNodeMouseDown = UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TVM_HITTEST, 0, tvhit);
                    
                    WmMouseDown(ref m, MouseButtons.Right, 1);
                    downButton = MouseButtons.Right;
                    break;
                    //# VS7 15052
                case NativeMethods.WM_SYSCOLORCHANGE:
                    SendMessage(NativeMethods.TVM_SETINDENT, Indent, 0);
                    base.WndProc(ref m);
                    break;
                case NativeMethods.WM_SETFOCUS:
                     // If we get focus through the LBUttonDown .. we might have done the validation...
                     // so skip it..
                     if (treeViewState[TREEVIEWSTATE_lastControlValidated])
                     {
                        treeViewState[TREEVIEWSTATE_lastControlValidated] = false;
                        WmImeSetFocus();
                        DefWndProc(ref m);
                        OnGotFocus(EventArgs.Empty);
                     }
                     else 
                     {
                        base.WndProc(ref m);
                     }
                     break;
                case NativeMethods.WM_CONTEXTMENU:
                    if (treeViewState[TREEVIEWSTATE_showTreeViewContextMenu]) {
                        treeViewState[TREEVIEWSTATE_showTreeViewContextMenu] = false;
                        base.WndProc(ref m);
                    }
                    else {
                        // this is the Shift + F10 Case....
                        TreeNode treeNode = SelectedNode;
                        if (treeNode != null && (treeNode.ContextMenu != null || treeNode.ContextMenuStrip !=null)) {
                            Point client;
                            client = new Point(treeNode.Bounds.X , treeNode.Bounds.Y + treeNode.Bounds.Height / 2);
                            // VisualStudio7 # 156, only show the context menu when clicked in the client area
                            if (ClientRectangle.Contains( client )) {
                                if (treeNode.ContextMenu != null) {
                                    treeNode.ContextMenu.Show(this, client);
                                }
                                else if (treeNode.ContextMenuStrip !=null) {
                                    bool keyboardActivated =  (unchecked((int)(long)m.LParam) == -1);
                                    treeNode.ContextMenuStrip.ShowInternal(this, client, keyboardActivated);
                                }
                            }
                        }
                        else {
                            // in this case we dont have a selected node.  The base
                            // will ensure we're constrained to the client area.
                            base.WndProc (ref m);
                        }
                    }
                    break;


                default:
                    base.WndProc(ref m);
                    break;
            }
        }
Пример #2
0
        internal void UpdateImage ()
        {
            NativeMethods.TV_ITEM item = new NativeMethods.TV_ITEM();

            item.mask = NativeMethods.TVIF_HANDLE | NativeMethods.TVIF_IMAGE;
            item.hItem = Handle;
            item.iImage = Math.Max(0, ((ImageIndexer.ActualIndex >= TreeView.ImageList.Images.Count) ? TreeView.ImageList.Images.Count - 1 : ImageIndexer.ActualIndex));
            UnsafeNativeMethods.SendMessage(new HandleRef(TreeView, TreeView.Handle), NativeMethods.TVM_SETITEM, 0, ref item);
        }
Пример #3
0
        private void ResetExpandedState(TreeView tv) {
            Debug.Assert(tv.IsHandleCreated, "nonexistent handle");

            NativeMethods.TV_ITEM item = new NativeMethods.TV_ITEM();
            item.mask = NativeMethods.TVIF_HANDLE | NativeMethods.TVIF_STATE;
            item.hItem = handle;
            item.stateMask = NativeMethods.TVIS_EXPANDEDONCE;
            item.state = 0;
            UnsafeNativeMethods.SendMessage(new HandleRef(tv, tv.Handle), NativeMethods.TVM_SETITEM, 0, ref item);
        }
Пример #4
0
        /// <include file='doc\TreeNode.uex' path='docs/doc[@for="TreeNode.UpdateNode"]/*' />
        /// <devdoc>
        ///     Tell the TreeView to refresh this node
        /// </devdoc>
        private void UpdateNode(int mask) {
            if (handle == IntPtr.Zero) return;
            TreeView tv = TreeView;
            Debug.Assert(tv != null, "TreeNode has handle but no TreeView");

            NativeMethods.TV_ITEM item = new NativeMethods.TV_ITEM();
            item.mask = NativeMethods.TVIF_HANDLE | mask;
            item.hItem = handle;
            if ((mask & NativeMethods.TVIF_TEXT) != 0)
                item.pszText = Marshal.StringToHGlobalAuto(text);
            if ((mask & NativeMethods.TVIF_IMAGE) != 0)
                item.iImage = (ImageIndexer.ActualIndex == -1) ? tv.ImageIndexer.ActualIndex : ImageIndexer.ActualIndex;
            if ((mask & NativeMethods.TVIF_SELECTEDIMAGE) != 0)
                item.iSelectedImage = (SelectedImageIndexer.ActualIndex == -1) ? tv.SelectedImageIndexer.ActualIndex : SelectedImageIndexer.ActualIndex;
            if ((mask & NativeMethods.TVIF_STATE) != 0) {
                item.stateMask = NativeMethods.TVIS_STATEIMAGEMASK;
                if (StateImageIndexer.ActualIndex != -1) {
                    item.state = ((StateImageIndexer.ActualIndex + 1) << SHIFTVAL);
                }
                // VSWhidbey 143401: ActualIndex == -1 means "don't use custom image list"
                // so just leave item.state set to zero, that tells the unmanaged control
                // to use no state image for this node.
            }
            if ((mask & NativeMethods.TVIF_PARAM) != 0) {
                item.lParam = handle; 
            }

            UnsafeNativeMethods.SendMessage(new HandleRef(tv, tv.Handle), NativeMethods.TVM_SETITEM, 0, ref item);
            if ((mask & NativeMethods.TVIF_TEXT) != 0) {
                Marshal.FreeHGlobal(item.pszText);
                if (tv.Scrollable)
                    tv.ForceScrollbarUpdate(false);
            }
        }
Пример #5
0
        internal void UpdateImage ()
        {
            TreeView tv = this.TreeView;
            if (tv.IsDisposed) {
                return;
            }

            NativeMethods.TV_ITEM item = new NativeMethods.TV_ITEM();

            item.mask = NativeMethods.TVIF_HANDLE | NativeMethods.TVIF_IMAGE;
            item.hItem = Handle;
            item.iImage = Math.Max(0, ((ImageIndexer.ActualIndex >= tv.ImageList.Images.Count) ? tv.ImageList.Images.Count - 1 : ImageIndexer.ActualIndex));
            UnsafeNativeMethods.SendMessage(new HandleRef(tv, tv.Handle), NativeMethods.TVM_SETITEM, 0, ref item);
        }