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