HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Creating an Object Member List

04-29-2007, 02:01 AM#1
Mapz_Maker
I believe that i am supposed to use System.Reflection.Emit to get the items and parameter info for this, but how do i create the actual window and how do i get it to appear in the right place and how do i get it to go to the closest match
04-29-2007, 03:32 AM#2
PitzerMike
Yes, you use System.Reflection (without Emit) to get the Members of a type.
Example:

typeof(whatever).GetMembers();

About creating a window and the closest match: I have no idea what you want.
04-29-2007, 12:23 PM#3
Mapz_Maker
you know in things like visual studio when you type a word then press "." it produces a list at the "." and lists all the members of the word before. The list then steadily goes to the alphabetically closest match as you type. (known as IntelliSense) How would i create the window at the location where they presses the "." key and how would i get it to have it so that it is a scrollable list?
04-29-2007, 03:23 PM#4
BlacKDicK
Mapz_Maker, please don´t take this as an offense, accept it as a suggestion instead: try to be more clear when you explains things. For and example, you could´ve said: How do I implement a InteliSense-like window onto the Jass editor I´m currently developing? How do I setup and set the coordinates of the small listbox with "hints" that pops when I press the dot "." after a recognized word?


My answer: I don´t know. I suck at GUI development., but you can take a look on the ICShapCode SharpDevelop: they have this feature on the editor and you can grab the code (it´s open src) and take a look.

As another suggestion, you should take a look on the Domain-Specific Language Tools pack that comes with the Microsoft Visual Studio 2005 SDK and start learning about software factories. As an example of it´s implementation, take a look on SharpLudus.
04-29-2007, 11:35 PM#5
Mapz_Maker
No offense taken. Thanks for pointing me to that source code, but it requires Visual Studio 2005 Standard edition, and i just have the express and Visual Studio 2002 Professional. The code is huge, and i could not reasonably find what i wanted since i could not run it (i would have used spy++ to find the class name, then searched for it). Anybody (including BlackDick) have some other ideas?
04-30-2007, 07:59 AM#6
PitzerMike
http://www.codeproject.com/csharp/diy-intellisense.asp

Searching codeproject.com is usually a good idea.
04-30-2007, 10:30 PM#7
Mapz_Maker
Might try to remember that next time (*looks at link*)
05-02-2007, 12:51 AM#8
Mapz_Maker
Development Environment Nearly complete...
05-03-2007, 12:37 AM#9
Mapz_Maker
Aaaarg, i cannot get this to function properly: i want to load all of the assemblies defaultly loaded by csc.exe (when you compile) so that i can provide the full functionality currently alotted users. For some unknown reason it is erasing all of the previous intellisense data when appying a new one. I found the reason for one part of the clearing; except when i do that it loses even more data. When i leave it to clear the data it properly loads the last assembly it was told to load. Here is the code that should contain the problem. I know it is a lot of code... Try and look through it; i attempted to organize it. (the data is stored on a TreeView {is hidden})
Summary


I need a way to keep all of the collected data; it is being lost somewhere when i try and load more than one assembly (dll).


Code for calling the Reading of the Assemblies::Is run on init


Code:
...
//to prevent lag on load, there are app.doevents and sleep between each read
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\Accessibility.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\Microsoft.Vsa.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Configuration.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Configuration.Install.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Data.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Data.OracleClient.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Data.SqlXml.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Deployment.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Design.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.DirectoryServices.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Drawing.Design.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Drawing.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.EnterpriseServices.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Management.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Messaging.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Runtime.Remoting.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Runtime.Serialization.Formatters.Soap.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Security.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.ServiceProcess.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Transactions.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Web.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Web.Mobile.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Web.RegularExpressions.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Web.Services.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Windows.Forms.Dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.Xml.dll");
            System.Threading.Thread.Sleep(10);
            Application.DoEvents();
            readAssembly("C:\\WINDOWS\\Microsoft.Net\\Framework\\v2.0.50727\\System.dll");
...


Code for the actual manipulation of the assemblies

Code:
        /// <summary>
        /// Takes an assembly filename, opens it and retrieves all types.
        /// </summary>
        /// <param name="filename">Filename to open</param>
        private void readAssembly(string filename)
        {
            namespaces = new Hashtable();
            assembly = Assembly.LoadFrom(filename);

            Type[] assemblyTypes = assembly.GetTypes();
            this.treeViewItems.Nodes.Clear();

            // Cycle through types
            foreach (Type type in assemblyTypes)
            {
                if (type.Namespace != null)
                {
                    if (namespaces.ContainsKey(type.Namespace))
                    {
                        // Already got namespace, add the class to it
                        TreeNode treeNode = (TreeNode)namespaces[type.Namespace];
                        treeNode = treeNode.Nodes.Add(type.Name);
                        this.addMembers(treeNode, type);

                        if (type.IsClass)
                        {
                            treeNode.Tag = MemberTypes.Custom;
                        }
                    }
                    else
                    {
                        // New namespace
                        TreeNode membersNode = null;

                        if (type.Namespace.IndexOf(".") != -1)
                        {
                            // Search for already existing parts of the namespace
                            nameSpaceNode = null;
                            foundNode = false;

                            this.currentPath = "";
                            searchTree(this.treeViewItems.Nodes, type.Namespace, false);

                            // No existing namespace found
                            if (nameSpaceNode == null)
                            {
                                // Add the namespace
                                string[] parts = type.Namespace.Split('.');

                                TreeNode treeNode = treeViewItems.Nodes.Add(parts[0]);
                                string sNamespace = parts[0];

                                if (!namespaces.ContainsKey(sNamespace))
                                {
                                    namespaces.Add(sNamespace, treeNode);
                                }

                                for (int i = 1; i < parts.Length; i++)
                                {
                                    treeNode = treeNode.Nodes.Add(parts[i]);
                                    sNamespace += "." + parts[i];
                                    if (!namespaces.ContainsKey(sNamespace))
                                    {
                                        namespaces.Add(sNamespace, treeNode);
                                    }
                                }

                                membersNode = treeNode.Nodes.Add(type.Name);
                            }
                            else
                            {
                                // Existing namespace, add this namespace to it,
                                // and add the class
                                string[] parts = type.Namespace.Split('.');
                                TreeNode newNamespaceNode = null;

                                if (!namespaces.ContainsKey(type.Namespace))
                                {
                                    newNamespaceNode = nameSpaceNode.Nodes.Add(parts[parts.Length - 1]);
                                    namespaces.Add(type.Namespace, newNamespaceNode);
                                }
                                else
                                {
                                    newNamespaceNode = (TreeNode)namespaces[type.Namespace];
                                }

                                if (newNamespaceNode != null)
                                {
                                    membersNode = newNamespaceNode.Nodes.Add(type.Name);
                                    if (type.IsClass)
                                    {
                                        membersNode.Tag = MemberTypes.Custom;
                                    }
                                }
                            }

                        }
                        else
                        {
                            // Single root namespace, add to root
                            membersNode = treeViewItems.Nodes.Add(type.Namespace);
                        }

                        // Add all members
                        if (membersNode != null)
                        {
                            this.addMembers(membersNode, type);
                        }
                    }
                }

            }
        }

        /// <summary>
        /// Adds all members to the node's children, grabbing the parameters
        /// for methods.
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="type"></param>
        private void addMembers(TreeNode treeNode, System.Type type)
        {
            // Get all members except methods
            WriteLine(type.Name);
            MemberInfo[] memberInfo = type.GetMembers();
            for (int j = 0; j < memberInfo.Length; j++)
            {
                if (memberInfo[j].ReflectedType.IsPublic && memberInfo[j].MemberType != MemberTypes.Method)
                {
                    TreeNode node = treeNode.Nodes.Add(memberInfo[j].Name);
                    node.Tag = memberInfo[j].MemberType;
                }
            }

            // Get all methods
            MethodInfo[] methodInfo = type.GetMethods();
            for (int j = 0; j < methodInfo.Length; j++)
            {
                TreeNode node = treeNode.Nodes.Add(methodInfo[j].Name);
                string parms = "";

                ParameterInfo[] parameterInfo = methodInfo[j].GetParameters();
                for (int f = 0; f < parameterInfo.Length; f++)
                {
                    parms += parameterInfo[f].ParameterType.ToString() + " " + parameterInfo[f].Name + ", ";
                }

                // Knock off remaining ", "
                if (parms.Length > 2)
                {
                    parms = parms.Substring(0, parms.Length - 2);
                }

                node.Tag = parms;
            }
        }

       /// <summary>
        /// Searches the tree view for a namespace, saving the node. The method
        /// stops and returns as soon as the namespace search can't find any
        /// more items in its path, unless continueUntilFind is true.
        /// </summary>
        /// <param name="treeNodes"></param>
        /// <param name="path"></param>
        /// <param name="continueUntilFind"></param>
        private void searchTree(TreeNodeCollection treeNodes, string path, bool continueUntilFind)
        {
            if (this.foundNode)
            {
                return;
            }

            string p = "";
            int n = 0;
            n = path.IndexOf(".");

            if (n != -1)
            {
                p = path.Substring(0, n);

                if (currentPath != "")
                {
                    currentPath += "." + p;
                }
                else
                {
                    currentPath = p;
                }

                // Knock off the first part
                path = path.Remove(0, n + 1);
            }
            else
            {
                currentPath += "." + path;
            }

            for (int i = 0; i < treeNodes.Count; i++)
            {
                if (treeNodes[i].FullPath == currentPath)
                {
                    if (continueUntilFind)
                    {
                        nameSpaceNode = treeNodes[i];
                    }

                    nameSpaceNode = treeNodes[i];

                    // got a dot, continue, or return
                    this.searchTree(treeNodes[i].Nodes, path, continueUntilFind);

                }
                else if (!continueUntilFind)
                {
                    foundNode = true;
                    return;
                }
            }
        }

        /// <summary>
        /// Searches the tree until the given path is found, storing
        /// the found node in a member var.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="treeNodes"></param>
        private void findNode(string path, TreeNodeCollection treeNodes)
        {
            for (int i = 0; i < treeNodes.Count; i++)
            {
                if (treeNodes[i].FullPath == path)
                {
                    this.findNodeResult = treeNodes[i];
                    break;
                }
                else if (treeNodes[i].Nodes.Count > 0)
                {
                    this.findNode(path, treeNodes[i].Nodes);
                }
            }
        }


Code Block for responding to pressing the period key

Code:
...
            if (e.KeyData == Keys.OemPeriod)
            {
                // The amazing dot key
#if ShowKeyPressLoc
                MessageBox.Show("if ( e.KeyData == Keys.OemPeriod )");
#endif

                if (!this.listBoxAutoComplete.Visible)
                {
                    WriteLine("Not Visible...");
                    // Display the member listview if there are
                    // items in it
                    if (populateListBox())
                    {
                        WriteLine("Box Populated...");
                        //this.listBoxAutoComplete.SelectedIndex = 0;

                        // Find the position of the caret
                        Point point = EditBox.GetPositionFromCharIndex(EditBox.SelectionStart);
                        point.Y += (int)Math.Ceiling(EditBox.Font.GetHeight()) + 27;
                        point.X += 2;
                        this.listBoxAutoComplete.Location = point;
                        this.listBoxAutoComplete.BringToFront();
                        this.listBoxAutoComplete.Show();
                        WriteLine("Is Visible...");
                    }
                }
                else
                {
                    if (populateListBox())
                    {
                        typed = "";
                    }
                    else
                    {
                        this.listBoxAutoComplete.Hide();
                        typed = "";
                    }
                }
...


Code for populating the Intellisense Box

Code:
       /// <summary>
        /// Called when a "." is pressed - the previous word is found,
        /// and if matched in the treeview, the members listbox is
        /// populated with items from the tree, which are first sorted.
        /// </summary>
        /// <returns>Whether an items are found for the word</returns>
        private bool populateListBox()
        {
            bool result = false;
            string word = this.getLastWord();

            //System.Diagnostics.Debug.WriteLine(" - Path: " +word);
            WriteLine(treeViewItems.Nodes.Count.ToString());
            if (word != "")
            {
                findNodeResult = null;
                findNode(word, this.treeViewItems.Nodes);

                if (this.findNodeResult != null)
                {
                    this.listBoxAutoComplete.Items.Clear();

                    if (this.findNodeResult.Nodes.Count > 0)
                    {
                        result = true;

                        // Sort alphabetically (this could be replaced with
                        // a sortable treeview)
                        MemberItem[] items = new MemberItem[this.findNodeResult.Nodes.Count];
                        for (int n = 0; n < this.findNodeResult.Nodes.Count; n++)
                        {
                            MemberItem memberItem = new MemberItem();
                            memberItem.DisplayText = this.findNodeResult.Nodes[n].Text;
                            memberItem.Tag = this.findNodeResult.Nodes[n].Tag;

                            if (this.findNodeResult.Nodes[n].Tag != null)
                            {
                                System.Diagnostics.Debug.WriteLine(this.findNodeResult.Nodes[n].Tag.GetType().ToString());
                            }

                            items[n] = memberItem;
                        }
                        Array.Sort(items);

                        for (int n = 0; n < items.Length; n++)
                        {
                            int imageindex = 0;

                            if (items[n].Tag != null)
                            {
                                // Default to method (contains text for parameters)
                                imageindex = 2;
                                if (items[n].Tag is MemberTypes)
                                {
                                    MemberTypes memberType = (MemberTypes)items[n].Tag;

                                    switch (memberType)
                                    {
                                        case MemberTypes.Custom:
                                            imageindex = 1;
                                            break;
                                        case MemberTypes.Property:
                                            imageindex = 3;
                                            break;
                                        case MemberTypes.Event:
                                            imageindex = 4;
                                            break;
                                    }
                                }
                            }

                            this.listBoxAutoComplete.Items.Add(new GListBoxItem(items[n].DisplayText, imageindex));
                        }
                    }
                }
            }

            return result;
        }

05-03-2007, 10:06 AM#10
BlacKDicK
/// <summary>
/// Takes an assembly filename, opens it and retrieves all types.
/// </summary>
/// <param name="filename">Filename to open</param>
private void readAssembly(string filename)
{
namespaces = new Hashtable();
assembly = Assembly.LoadFrom(filename);

Type[] assemblyTypes = assembly.GetTypes();
this.treeViewItems.Nodes.Clear();
....
05-05-2007, 03:12 AM#11
Mapz_Maker
come on... it is not that easy. i tried that. it made it have even less data (why?) than before. That is why i am asking here...
Quote:
Originally Posted by Mapz_Maker
I found the reason for one part of the clearing; except when i do that it loses even more data.
05-06-2007, 05:57 PM#12
PitzerMike
Just from the code it's hard to tell, what is going wrong.
Use the debugger to find out, where it's happening.