none
TreeViewコントロールのドラッグ&ドロップ中に挿入ポイントを出したい。 RRS feed

  • 質問

  • いつも質問ばかりで申し訳御座いません。

    TreeViewコントロールでドラッグ&ドロップ中にドロップ先が分かるように

    >--------<

    のような挿入ポイントを出したいのですが
    .NETのTreeViewにはInsertionMarkを表示する方法は御座いますでしょうか?

    2009年11月12日 15:54

回答

  • こんな
    #HotTrackingプロパティでもいいような気もする

    /// <summary>
    /// InsertMarkを表示できるTreeView
    /// </summary>
    public class InsertMarkTreeView : TreeView
    {
        [DllImport("user32.dll" , CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd , UInt32 Msg , IntPtr wParam , IntPtr lParam);
        [DllImport("user32.dll" , CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd , UInt32 Msg , IntPtr wParam , int colorRef);
    
        private const int TV_FIRST =0x1100;
        private const int TVM_SETINSERTMARK = TV_FIRST + 26;
        private const int TVM_SETINSERTMARKCOLOR = TV_FIRST + 37;
        private const int TVM_GETINSERTMARKCOLOR = TV_FIRST + 38;
    
        /// <summary>TreeViewにInsertMarkを設定する</summary>
        /// <param name="node">InsertMarkを設定するTreeNode  nullで解除</param>
        /// <param name="isAfter">True:nodeの後ろにInsertMarkを表示する</param>
        public void SetInsertMark(TreeNode node , bool isAfter)
        {
            //IntPtr result = SendMessage(this.Handle , TVM_SETINSERTMARK 
            //                             , new IntPtr(isAfter ? -1 : 0) 
            //                             , (node == null ? IntPtr.Zero : node.Handle)  );
            Message msg = new Message();
            msg.HWnd = this.Handle;
            msg.Msg = TVM_SETINSERTMARK;
            msg.WParam = new IntPtr(isAfter ? -1 : 0);
            msg.LParam = (node == null ? IntPtr.Zero : node.Handle);
            this.WndProc(ref msg);
            if (msg.Result == IntPtr.Zero)
            {
                throw new ApplicationException();
            }
        }
    
        /// <summary>InsertMarkの色</summary>
        public Color InsertMarkColor
        {
            get
            {
                int intColorRef = SendMessage(this.Handle , TVM_GETINSERTMARKCOLOR 
                                            , IntPtr.Zero , IntPtr.Zero).ToInt32();
                int r = intColorRef & 0xff;
                int g = (intColorRef & 0xff00) >> 8;
                int b = (intColorRef & 0xff0000) >> 16;
                return Color.FromArgb(r , g , b);
            }
            set
            {
                int colorRef = value.R | ((int)value.G << 8) | ((int)value.B << 16);
                SendMessage(this.Handle,TVM_SETINSERTMARKCOLOR , IntPtr.Zero , colorRef);
            }
        }
    
        /// <summary>
        /// InsertMarkをマウスに追随させるか
        /// </summary>
        public bool TraceInsertMark
        {
            get
            {
                return _TraceInsertMark;
            }
            set
            {
                _TraceInsertMark = value;
                if (value)
                {
                    //今のマウス位置でInsertMark表示
                    Point pos = Control.MousePosition;
                    pos = this.PointToClient(pos);
                    TreeViewHitTestInfo info = this.HitTest(pos);
                    SetInsertMark(info.Node , true);
                }
                else
                {
                    //追跡しないならInsertMarkを消す
                    SetInsertMark(null , true);
                }
            }
        }
        private bool _TraceInsertMark = false;
    
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (TraceInsertMark)
            {
                TreeViewHitTestInfo info = this.HitTest(e.Location);
                SetInsertMark(info.Node , true);
            }
            base.OnMouseMove(e);
        }
    
        protected override void OnBeforeExpand(TreeViewCancelEventArgs e)
        {
            //ExpandでInsertMarkの残像が残ってしまうのを防止
            if (TraceInsertMark)
            {
                SetInsertMark(null , true);
            }
            base.OnBeforeExpand(e);
        }
        protected override void OnAfterExpand(TreeViewEventArgs e)
        {
            if (TraceInsertMark)
            {
                SetInsertMark(e.Node , true);
            }
            base.OnAfterExpand(e);
        }
    }
    • 回答としてマーク zilch_1975 2009年11月18日 7:15
    2009年11月14日 3:27

すべての返信

  • こんな
    #HotTrackingプロパティでもいいような気もする

    /// <summary>
    /// InsertMarkを表示できるTreeView
    /// </summary>
    public class InsertMarkTreeView : TreeView
    {
        [DllImport("user32.dll" , CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd , UInt32 Msg , IntPtr wParam , IntPtr lParam);
        [DllImport("user32.dll" , CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd , UInt32 Msg , IntPtr wParam , int colorRef);
    
        private const int TV_FIRST =0x1100;
        private const int TVM_SETINSERTMARK = TV_FIRST + 26;
        private const int TVM_SETINSERTMARKCOLOR = TV_FIRST + 37;
        private const int TVM_GETINSERTMARKCOLOR = TV_FIRST + 38;
    
        /// <summary>TreeViewにInsertMarkを設定する</summary>
        /// <param name="node">InsertMarkを設定するTreeNode  nullで解除</param>
        /// <param name="isAfter">True:nodeの後ろにInsertMarkを表示する</param>
        public void SetInsertMark(TreeNode node , bool isAfter)
        {
            //IntPtr result = SendMessage(this.Handle , TVM_SETINSERTMARK 
            //                             , new IntPtr(isAfter ? -1 : 0) 
            //                             , (node == null ? IntPtr.Zero : node.Handle)  );
            Message msg = new Message();
            msg.HWnd = this.Handle;
            msg.Msg = TVM_SETINSERTMARK;
            msg.WParam = new IntPtr(isAfter ? -1 : 0);
            msg.LParam = (node == null ? IntPtr.Zero : node.Handle);
            this.WndProc(ref msg);
            if (msg.Result == IntPtr.Zero)
            {
                throw new ApplicationException();
            }
        }
    
        /// <summary>InsertMarkの色</summary>
        public Color InsertMarkColor
        {
            get
            {
                int intColorRef = SendMessage(this.Handle , TVM_GETINSERTMARKCOLOR 
                                            , IntPtr.Zero , IntPtr.Zero).ToInt32();
                int r = intColorRef & 0xff;
                int g = (intColorRef & 0xff00) >> 8;
                int b = (intColorRef & 0xff0000) >> 16;
                return Color.FromArgb(r , g , b);
            }
            set
            {
                int colorRef = value.R | ((int)value.G << 8) | ((int)value.B << 16);
                SendMessage(this.Handle,TVM_SETINSERTMARKCOLOR , IntPtr.Zero , colorRef);
            }
        }
    
        /// <summary>
        /// InsertMarkをマウスに追随させるか
        /// </summary>
        public bool TraceInsertMark
        {
            get
            {
                return _TraceInsertMark;
            }
            set
            {
                _TraceInsertMark = value;
                if (value)
                {
                    //今のマウス位置でInsertMark表示
                    Point pos = Control.MousePosition;
                    pos = this.PointToClient(pos);
                    TreeViewHitTestInfo info = this.HitTest(pos);
                    SetInsertMark(info.Node , true);
                }
                else
                {
                    //追跡しないならInsertMarkを消す
                    SetInsertMark(null , true);
                }
            }
        }
        private bool _TraceInsertMark = false;
    
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (TraceInsertMark)
            {
                TreeViewHitTestInfo info = this.HitTest(e.Location);
                SetInsertMark(info.Node , true);
            }
            base.OnMouseMove(e);
        }
    
        protected override void OnBeforeExpand(TreeViewCancelEventArgs e)
        {
            //ExpandでInsertMarkの残像が残ってしまうのを防止
            if (TraceInsertMark)
            {
                SetInsertMark(null , true);
            }
            base.OnBeforeExpand(e);
        }
        protected override void OnAfterExpand(TreeViewEventArgs e)
        {
            if (TraceInsertMark)
            {
                SetInsertMark(e.Node , true);
            }
            base.OnAfterExpand(e);
        }
    }
    • 回答としてマーク zilch_1975 2009年11月18日 7:15
    2009年11月14日 3:27
  • gekkaさん
     有難う御座いました。
     参考にさせて頂きます!
    2009年11月18日 7:15