方法 : サブクラスをネイティブのコールバック関数を使用して、ツリー ビュー

[このドキュメントはプレビュー版であり、後のリリースで変更されることがあります。 空白のトピックは、プレースホルダーとして挿入されています。]

次の使用例は方法をサブクラス化する、TreeView 制御示しています、.NET Compact Framework では使用できません、 NodeMouseClick イベントを作成します。

サブクラス TreeView コントロールとクリックしたノードに関する情報を表示するフォームします。 表示のノードのテキストおよび x と y 座標の位置、TreeView コントロールがクリックされた、ノード上で別の場所でクリックすると、変更します。

このサンプル プログラムについては 管理ウィンドウ プロシージャでコントロールをサブクラス化 で詳しく説明します。

NodeMouseClick イベントを作成するツリー ビュー コントロールをサブクラス化

  1. Microsoft Visual Studio 2005 でスマート デバイスの Pocket PC プロジェクトを作成します。

  2. プロジェクトに、Win32 ヘルパー クラスを追加します。 このコードは「方法 : 使用のプラットフォーム用のヘルパー クラスを呼び出す」にあります。

  3. WinProcHooker クラスをプロジェクトに追加します。 このコードは「方法 : Windows のプロシージャをフックのクラスを使用します。」にあります。

  4. TreeViewBonus クラスをプロジェクトに追加します。

                                // Extends the standard TreeView control to add an implementation
                                // of the NodeMouseClick event.
                                public
                                class TreeViewBonus : TreeView
    {
        // The original parent of this control.
        Control prevParent = null;
    
        // Creates a new instance of the derived TreeView controlpublic TreeViewBonus()
        {
        }
    
        // Called when the control's parent is changed. Here we hook into that// parent's WndProc and spy on the WM_NOTIFY message. When the parent// changes, we unhook the old parent's WndProc and hook into the new one.protectedoverridevoid OnParentChanged(EventArgs e)
        {
            // unhook the old parentif (this.prevParent != null)
            {
                WndProcHooker.UnhookWndProc(prevParent, Win32.WM_NOTIFY);
            }
            // update the previous parent
            prevParent = this.Parent;
    
            // hook up the new parentif (this.Parent != null)
            {
                WndProcHooker.HookWndProc(this.Parent,
                new WndProcHooker.WndProcCallback(this.WM_Notify_Handler),
                Win32.WM_NOTIFY);
            }
    
            base.OnParentChanged(e);
        }
    
        // Occurs when the user clicks a TreeNode with the mouse.publicevent TreeNodeMouseClickEventHandler NodeMouseClick;
    
        // Occurs when the mouse pointer is over the control and a mouse button is clicked.protectedvoid OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
        {
            if (NodeMouseClick != null)
                NodeMouseClick(this, e);
       }
    
        // The method that gets called when a WM_NOTIFY message is received by the// TreeView's parent.// hwnd - The handle of the window that received the message// msg - The message received// wParam - The wParam arguments for the message// lParam - The lParam arguments for the message// handled - Set to true to indicate that this message was handled// Returns an appropriate return code for the message handledint WM_Notify_Handler(
            IntPtr hwnd, uint msg, uint wParam, int lParam,
            refbool handled)
        {
            Win32.NMHDR nmHdr = new Win32.NMHDR();
            System.Runtime.InteropServices.Marshal.PtrToStructure((IntPtr)lParam, nmHdr);
            switch (nmHdr.code)
            {
                case Win32.NM_RCLICK:
                case Win32.NM_CLICK:
                    // get the cursor coordinates on the client
                    Point msgPos = Win32.LParamToPoint((int)Win32.GetMessagePos());
                    msgPos = this.PointToClient(msgPos);
    
                    // check to see if the click was on an item
                    Win32.TVHITTESTINFO hti = new Win32.TVHITTESTINFO();
                    hti.pt.X = msgPos.X;
                    hti.pt.Y = msgPos.Y;
                    int hitem = Win32.SendMessage(this.Handle, Win32.TVM_HITTEST, 0, ref hti);
                    uint htMask = (
                        Win32.TVHT_ONITEMICON |
                        Win32.TVHT_ONITEMLABEL |
                        Win32.TVHT_ONITEMINDENT |
                        Win32.TVHT_ONITEMBUTTON |
                        Win32.TVHT_ONITEMRIGHT |
                        Win32.TVHT_ONITEMSTATEICON);
                    if ((hti.flags & htMask) != 0)
                    {
                        bool leftButton = (nmHdr.code == Win32.NM_CLICK);
                        RaiseNodeMouseClickEvent(hti.hItem,
                            leftButton ? MouseButtons.Left : MouseButtons.Right,
                            msgPos);
                        return 0;
                    }
                    break;
                default:
                    break;
            }
            return 0;
        }
    
        // Raises the TreeNodeMouseClick event for the TreeNode with the specified handle.// hNode - The handle of the node for which the event is raised// button - The [mouse] buttons that were pressed to raise the event// coords - The [client] cursor coordinates at the time of the eventvoid RaiseNodeMouseClickEvent(IntPtr hNode, MouseButtons button, Point coords)
        {
            TreeNode tn = FindTreeNodeFromHandle(this.Nodes, hNode);
    
            TreeNodeMouseClickEventArgs e = new TreeNodeMouseClickEventArgs(
                tn,
                button,
                1, coords.X, coords.Y);
    
            OnNodeMouseClick(e);
        }
    
        // Finds a TreeNode in the provided TreeNodeCollection that has the handle specified.// Warning: recursion!// tnc - The TreeNodeCollection to search// handle - The handle of the TreeNode to find in the collection// Returns tThe TreeNode if found; null otherwise
        TreeNode FindTreeNodeFromHandle(TreeNodeCollection tnc, IntPtr handle)
        {
            foreach (TreeNode tn in tnc)
            {
            if (tn.Handle == handle) return tn;
                // we couldn't have clicked on a child of this node if this node// is not expanded!if (tn.IsExpanded)
                {
                    TreeNode tn2 = FindTreeNodeFromHandle(tn.Nodes, handle);
                    if (tn2 != null) return tn2;
                }
            }
            returnnull;
        }
    }
    
  5. TreeNodeMouseClickEventArgs クラスをプロジェクトに追加します。

                                // Provides data for the System.Windows.Forms.TreeView.NodeMouseClick event
                                public
                                class TreeNodeMouseClickEventArgs : MouseEventArgs
    {
        // Initializes a new instance of the TreeNodeMouseClickEventArgs class.// node - The node that was clicked// button - One of the System.Windows.Forms.MouseButtons members// clicks - The number of clicks that occurred// x - The x-coordinate where the click occurred// y - The y-coordinate where the click occurredpublic TreeNodeMouseClickEventArgs(TreeNode node, MouseButtons button, int clicks, int x, int y)
            :
            base(button, clicks, x, y, 0)
        {
            nodeValue = node;
        }
    
        //// Gets the node that was clicked.//public TreeNode Node
        {
            get { return nodeValue; }
            set { nodeValue = value; }
        }
        TreeNode nodeValue;
    
        publicoverridestring ToString()
        {
            returnstring.Format(
                "TreeNodeMouseClickEventArgs\r\n\tNode: {0}\r\n\tButton: {1}\r\n\tX: {2}\r\n\tY: {3}",
                nodeValue.Text, Button.ToString(), X, Y);
        }
    }
    
  6. 種類 treeViewBTreeViewBonus をという名前のフォーム変数を宣言します。

                                private TreeViewBonus treeViewB;
    
  7. Form1 への呼び出しを手本、 InitializeComponent クラスのコンストラクターに次のコードを追加します。 このコードもツリー ノードの範囲を追加し、その階層を整列します。

        InitializeComponent();
        this.treeViewB = new TreeViewBonus();
        this.treeViewB.NodeMouseClick += new TreeNodeMouseClickEventHandler(this.tv_NodeMouseClicked);
        this.treeViewB.Location = new System.Drawing.Point(18, 16);
        this.treeViewB.Size = new System.Drawing.Size(205, 144);
        this.treeViewB.Name = "treeViewB";
    
    
        // Set up the tree nodes.
        System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Node0");
        System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Node2");
        System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("Node3");
        System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("Node6");
        System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("Node7");
        System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("Node8");
        System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode("Node4");
        System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("Node1");
        System.Windows.Forms.TreeNode treeNode9 = new System.Windows.Forms.TreeNode("Node5");
        System.Windows.Forms.TreeNode treeNode10 = new System.Windows.Forms.TreeNode("Node9");
        System.Windows.Forms.TreeNode treeNode11 = new System.Windows.Forms.TreeNode("Node10");
        System.Windows.Forms.TreeNode treeNode12 = new System.Windows.Forms.TreeNode("Node11");
    
        treeNode2.Text = "Node2";
        treeNode4.Text = "Node6";
        treeNode5.Text = "Node7";
        treeNode6.Text = "Node8";
        treeNode3.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
                treeNode4,
                treeNode5,
                treeNode6});
        treeNode3.Text = "Node3";
        treeNode7.Text = "Node4";
        treeNode1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
                treeNode2,
                treeNode3,
                treeNode7});
        treeNode1.Text = "Node0";
        treeNode12.Text = "Node11";
        treeNode11.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
                treeNode12});
        treeNode11.Text = "Node10";
        treeNode10.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
                treeNode11});
        treeNode10.Text = "Node9";
        treeNode9.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
                treeNode10});
        treeNode9.Text = "Node5";
        treeNode8.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
                treeNode9});
        treeNode8.Text = "Node1";
        this.treeViewB.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
                treeNode1,
                treeNode8});
    
        this.Controls.Add(treeViewB);
    
    
  8. NodeMouseClick クラスに、デリゲート、および派生 Form1 イベントのイベント処理メソッドを追加します。

                                // Delegate represents the method that will handle
                                // the NodeMouseClick event of a TreeView.
                                // Parameters:
                                // sender - The source of the event.
                                // e - A TreeNodeMouseClickEventArgs that contains the event data.
                                public
                                delegate
                                void TreeNodeMouseClickEventHandler(object sender, TreeNodeMouseClickEventArgs e);
    
    privatevoid tv_NodeMouseClicked(object sender, TreeNodeMouseClickEventArgs e)
    {
        // Show the current node and the coordinates// in TreeView control where it was clicked.// This is just some of the information you// can obtain from TreeNodeMouseClickEventArgs.// Use a StringBuilder for efficient// use of device resources.
        StringBuilder sb = new StringBuilder();
        sb.Append(e.Node.Text + " ");
        sb.Append("X: " + e.X.ToString() + ", ");
        sb.Append("Y: " + e.Y.ToString());
    
        label1.Text = sb.ToString();
    
    }
    
  9. アプリケーションをコンパイルして実行します。

参照

処理手順

方法 : Windows のプロシージャをフックのクラスを使用します。

方法 : 使用のプラットフォーム用のヘルパー クラスを呼び出す

方法 : サブクラスをネイティブのコールバック関数を使用して、ツリー ビュー

方法 : グラデーションの塗りつぶしを表示します。

概念

.NET コンパクトなフレームワーク方法を説明したトピックの検索

その他の技術情報

.NET Compact Framework の相互運用性