--- /dev/null
+/**\r
+ * Copyright (c) Lynn J. Gasch\r
+ * 7/17/04\r
+ * Redmond, Washington\r
+ * \r
+ * typhoonUI displays the contents of an xml file in a tree control.\r
+ * It was developed to support chess programming, but can really be\r
+ * used for any xml file you wish.\r
+ * \r
+ * Xml nodes that do not have children should be written within\r
+ * a single tag, as < tag anAttrib="value" /> so that they can \r
+ * be displayed on a single line (node) of the tree.\r
+ * \r
+ * Tags starting with "FEN" can be used to lauch chess board\r
+ * viewers with the board value (they must use the single-line\r
+ * formatting as described above to trigger this functionality). \r
+ * \r
+ * This app is pretty special purpose and I'm sure there are plenty\r
+ * of ways to break it with various inputs. I coded it up in a few\r
+ * hours and it meets our needs. \r
+ */\r
+\r
+using System;\r
+using System.Drawing;\r
+using System.Collections;\r
+using System.ComponentModel;\r
+using System.Windows.Forms;\r
+using System.Data;\r
+using System.Xml;\r
+using System.IO;\r
+using System.Diagnostics;\r
+using System.Text;\r
+\r
+namespace typhoonUI\r
+{\r
+ // TODO: write tag for eval; Write evals dumps to file\r
+ // and retrieve the text into a separate text block \r
+ // on selection of the node\r
+ // TODO: command line file launch\r
+ // TODO: speed up loading\r
+\r
+ /// <summary>\r
+ /// Summary description for Form1.\r
+ /// </summary>\r
+ public class Form1 : System.Windows.Forms.Form\r
+ {\r
+ #region Private Fields\r
+\r
+ /// <summary>\r
+ /// inserted between tag names and their values for display\r
+ /// in the tree. For tags that have no children other than their\r
+ /// values, list them in the xml as \r
+ /// < tag attrib="something to display" /> and they will only\r
+ /// take up one tree node and be listed as \r
+ /// tag something to display.\r
+ /// </summary>\r
+ private const string VALUE_SEPARATOR = " ";\r
+\r
+ /// <summary>\r
+ /// Use this tag name to identify the board configuration node\r
+ /// in your xml. This will provide menu item and double-clicking\r
+ /// to launch the position in a viewer that you can specify.\r
+ /// </summary>\r
+ private const string TAG_BOARD = "FEN";\r
+\r
+ /// <summary>\r
+ /// name of a tag for which the first attrib should be added to its parent\r
+ /// node text. If it's the only child, the node itself will be skipped\r
+ /// </summary>\r
+ private const string TAG_SCORE = "score";\r
+\r
+ /// <summary>\r
+ /// Attributes named tip will be set as tool tip text for the node\r
+ /// </summary>\r
+ private const string ATTRIB_TIP = "tip";\r
+\r
+ /// <summary>\r
+ /// an attrib name to denote request for boldfacing the text.\r
+ /// In order for the text to be displayed, it must be the frst attrib.\r
+ /// </summary>\r
+ private const string ATTRIB_BOLD = "bold";\r
+\r
+ /// <summary>\r
+ /// Name of a (reusable) file that is written with the board\r
+ /// position and used as a command arg to the board viewer app.\r
+ /// </summary>\r
+ private const string POSITION_FILE_NAME = "boardConfigFile.txt";\r
+\r
+ /// <summary>\r
+ /// Windows designer generated code\r
+ /// </summary>\r
+ private System.Windows.Forms.MainMenu mainMenu1;\r
+ private System.Windows.Forms.MenuItem menuItem1;\r
+ private System.Windows.Forms.MenuItem menuItem2;\r
+ private System.Windows.Forms.TreeView _treeView1;\r
+\r
+ /// <summary>\r
+ /// appears when right-clicking on a "board" node. See\r
+ /// BOARD_TAG_NAME\r
+ /// </summary>\r
+ private System.Windows.Forms.ContextMenu _contextMenu;\r
+\r
+ /// <summary>\r
+ /// Path to the viewer app, to be collected from the user.\r
+ /// TODO: allow the user to enter it into the Path environment \r
+ /// variable and just attempt to run it; only request path\r
+ /// if fail to run.\r
+ /// </summary>\r
+ private string _boardViewerAppPath = null;\r
+\r
+ /// <summary>\r
+ /// the view app process, so we can kill it if another board\r
+ /// is to be viewed\r
+ /// </summary>\r
+ private Process _process = null;\r
+\r
+ /// <summary>\r
+ /// local dir for writing the board position file for input \r
+ /// into the viewer app.\r
+ /// </summary>\r
+ private string _applicationDir;\r
+\r
+ /// <summary>\r
+ /// Required designer variable.\r
+ /// </summary>\r
+ private System.ComponentModel.Container components = null;\r
+\r
+ /// <summary>\r
+ /// for displaying long or multi-line text\r
+ /// </summary>\r
+ private ToolTip _tip;\r
+\r
+ private string _tipText;\r
+\r
+ #endregion\r
+\r
+ #region Construction / Destruction\r
+\r
+ /// <summary>\r
+ /// The main thing\r
+ /// </summary>\r
+ public Form1(string startFile)\r
+ {\r
+ //\r
+ // Required for Windows Form Designer support\r
+ //\r
+ InitializeComponent();\r
+\r
+ // create the context menu that will be used for board nodes\r
+ _contextMenu = new ContextMenu();\r
+ MenuItem item = new MenuItem("View board");\r
+ item.Click += new EventHandler(OnViewBoardMenuClicked);\r
+ _contextMenu.MenuItems.Add(item);\r
+\r
+ _applicationDir = Path.GetDirectoryName(\r
+ Application.ExecutablePath);\r
+\r
+ _tip = new ToolTip();\r
+ _tipText = string.Empty;\r
+ _tip.SetToolTip(_treeView1, _tipText);\r
+\r
+ if ((startFile != null) && (startFile.Length > 0))\r
+ Display(startFile);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Clean up any resources being used.\r
+ /// </summary>\r
+ protected override void Dispose( bool disposing )\r
+ {\r
+ if( disposing )\r
+ {\r
+ KillProcess();\r
+ if (components != null) \r
+ {\r
+ components.Dispose();\r
+ }\r
+ }\r
+ base.Dispose( disposing );\r
+ }\r
+\r
+ \r
+ #endregion\r
+\r
+ #region Windows Form Designer generated code\r
+ /// <summary>\r
+ /// Required method for Designer support - do not modify\r
+ /// the contents of this method with the code editor.\r
+ /// </summary>\r
+ private void InitializeComponent()\r
+ {\r
+ this.mainMenu1 = new System.Windows.Forms.MainMenu();\r
+ this.menuItem1 = new System.Windows.Forms.MenuItem();\r
+ this.menuItem2 = new System.Windows.Forms.MenuItem();\r
+ this._treeView1 = new System.Windows.Forms.TreeView();\r
+ this.SuspendLayout();\r
+ // \r
+ // mainMenu1\r
+ // \r
+ this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {\r
+ this.menuItem1});\r
+ // \r
+ // menuItem1\r
+ // \r
+ this.menuItem1.Index = 0;\r
+ this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {\r
+ this.menuItem2});\r
+ this.menuItem1.Text = "File";\r
+ // \r
+ // menuItem2\r
+ // \r
+ this.menuItem2.Index = 0;\r
+ this.menuItem2.Text = "Open";\r
+ this.menuItem2.Click += new System.EventHandler(this.OnOpenMenuClick);\r
+ // \r
+ // _treeView1\r
+ // \r
+ this._treeView1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \r
+ | System.Windows.Forms.AnchorStyles.Left) \r
+ | System.Windows.Forms.AnchorStyles.Right);\r
+ this._treeView1.HideSelection = false;\r
+ this._treeView1.ImageIndex = -1;\r
+ this._treeView1.Name = "_treeView1";\r
+ this._treeView1.SelectedImageIndex = -1;\r
+ this._treeView1.Size = new System.Drawing.Size(680, 600);\r
+ this._treeView1.TabIndex = 0;\r
+ this._treeView1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnTreeViewMouseDown);\r
+ this._treeView1.DoubleClick += new System.EventHandler(this.OnTreeViewDoubleClick);\r
+ this._treeView1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnTreeViewMouseMove);\r
+ // \r
+ // Form1\r
+ // \r
+ this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);\r
+ this.ClientSize = new System.Drawing.Size(680, 598);\r
+ this.Controls.AddRange(new System.Windows.Forms.Control[] {\r
+ this._treeView1});\r
+ this.Menu = this.mainMenu1;\r
+ this.Name = "Form1";\r
+ this.Text = "Scott\'s Move Tree";\r
+ this.ResumeLayout(false);\r
+\r
+ }\r
+ #endregion\r
+\r
+ /// <summary>\r
+ /// The main entry point for the application.\r
+ /// </summary>\r
+ [STAThread]\r
+ static void Main(string[] args) \r
+ {\r
+ string filename = string.Empty;\r
+ if (args.Length > 0)\r
+ filename = args[0];\r
+\r
+ Application.Run(new Form1(filename));\r
+ }\r
+\r
+ /// <summary>\r
+ /// Use Xml support to load and parse the indicated xml doc.\r
+ /// Populate tree control with it.\r
+ /// </summary>\r
+ /// <param name="filename">path to the xml file to load</param>\r
+ private void Display(string filename)\r
+ {\r
+ _treeView1.BeginUpdate();\r
+ try\r
+ {\r
+ XmlDocument doc = new XmlDocument();\r
+ doc.Load(filename);\r
+ _treeView1.Nodes.Clear();\r
+ TreeNode root = new TreeNode(doc.DocumentElement.Name);\r
+ _treeView1.Nodes.Add(root);\r
+ // recursively add all\r
+ StringBuilder builder = new StringBuilder();\r
+ foreach(XmlNode node in doc.DocumentElement.ChildNodes)\r
+ {\r
+ AddNode(node, ref root, ref builder);\r
+ }\r
+ }\r
+ catch(Exception e)\r
+ {\r
+ MessageBox.Show(this, e.Message + "\r\n" +\r
+ e.StackTrace, "Error", \r
+ MessageBoxButtons.OK, MessageBoxIcon.Error);\r
+ }\r
+ _treeView1.EndUpdate();\r
+ }\r
+\r
+ /// <summary>\r
+ /// Recursively add nodes to the tree. \r
+ /// </summary>\r
+ /// <param name="element">the current info to add; corresponds\r
+ /// to the parent node so that we are adding its children.</param>\r
+ /// <param name="parent">parent node in the tree</param>\r
+ /// <param name="builder">on;y create one instance of string builder\r
+ /// and use it for text manipulation</param>\r
+ /// <remarks>Nodes that don't have any nested nodes (other than their\r
+ /// own "value") should be written in the form \r
+ /// < tagName attrib="Attrib value" />\r
+ /// In this case, the tag name and the first attrib value are\r
+ /// shown in one line (in one node) in the tree. NOTE: any\r
+ /// additional tags are ignored. (the attrib value is not required).\r
+ /// </remarks>\r
+ private void AddNode(XmlNode element, ref TreeNode parent,\r
+ ref StringBuilder builder)\r
+ {\r
+ builder.Length = 0;\r
+ string text = element.Name;\r
+\r
+ // special cases:\r
+ // - score: append parent text with score instead of adding \r
+ // it as a node. \r
+ // - any with attribs - append first attrib val to node text\r
+ // - bold - (must be first attrib) - boldface the node\r
+ // - tip - (any attrib) - set as the tag of the node for tooltip\r
+\r
+ if (text.Equals(TAG_SCORE))\r
+ {\r
+ builder.Append(parent.Text);\r
+ builder.Append(VALUE_SEPARATOR);\r
+ builder.Append(TAG_SCORE);\r
+ builder.Append(" ");\r
+ builder.Append(element.Attributes[0].Value);\r
+ parent.Text = builder.ToString();\r
+ // done\r
+ }\r
+ else\r
+ {\r
+ builder.Append(text);\r
+ XmlAttributeCollection coll = element.Attributes;\r
+ int numAttribs = coll.Count;\r
+ XmlAttribute attrib = null;\r
+ if (numAttribs > 0)\r
+ {\r
+ attrib = coll[0];\r
+ // append the tag name with the first attrib value\r
+ builder.Append(VALUE_SEPARATOR);\r
+ builder.Append(attrib.Value);\r
+ }\r
+ TreeNode node = new TreeNode(builder.ToString());\r
+\r
+ if ((attrib != null) && attrib.Name.Equals(ATTRIB_BOLD))\r
+ node.ForeColor = Color.Red;\r
+ if (numAttribs > 1)\r
+ { \r
+ attrib = coll[1];\r
+ if (attrib.Name.Equals(ATTRIB_TIP))\r
+ {\r
+ node.Tag = attrib.Value;\r
+ }\r
+ }\r
+\r
+ parent.Nodes.Add(node); \r
+\r
+ foreach (XmlElement child in element.ChildNodes)\r
+ {\r
+ AddNode(child, ref node, ref builder);\r
+ }\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets and saves the path to the viewer app from the user.\r
+ /// </summary>\r
+ private DialogResult SetViewerAppPath()\r
+ {\r
+ DialogResult result = DialogResult.OK;\r
+ if (_boardViewerAppPath == null)\r
+ {\r
+ result = MessageBox.Show(this, \r
+ "Please set path to Winboard or XBoard viewer app",\r
+ "Input requested", MessageBoxButtons.OKCancel, \r
+ MessageBoxIcon.Question);\r
+ if ( result == DialogResult.OK)\r
+ {\r
+ OpenFileDialog browse = new OpenFileDialog();\r
+ browse.Filter = "Executable files (*.exe)|*.exe";\r
+ browse.Multiselect = false;\r
+ result = browse.ShowDialog(this);\r
+ if (result == DialogResult.OK)\r
+ {\r
+ _boardViewerAppPath = browse.FileName;\r
+ }\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Closes the viewer app\r
+ /// </summary>\r
+ private void KillProcess()\r
+ {\r
+ if (_process != null)\r
+ {\r
+ if (!_process.HasExited)\r
+ {\r
+ if (!_process.CloseMainWindow())\r
+ _process.Kill();\r
+ }\r
+ _process = null;\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Writes board position to file and calls the viewer app with it.\r
+ /// </summary>\r
+ /// <param name="text">text of the board node, starting with the \r
+ /// "board" tag and separator</param>\r
+ private void ViewBoard(string text)\r
+ {\r
+ string boardCode = text.Substring(TAG_BOARD.Length\r
+ + VALUE_SEPARATOR.Length);\r
+ StreamWriter f = new StreamWriter(new FileStream(\r
+ Path.Combine(_applicationDir, POSITION_FILE_NAME),\r
+ FileMode.Create, FileAccess.Write));\r
+ f.WriteLine(boardCode);\r
+ f.Close();\r
+\r
+ if (SetViewerAppPath() == DialogResult.OK)\r
+ {\r
+\r
+ try\r
+ {\r
+ KillProcess();\r
+ ProcessStartInfo pInfo = \r
+ new ProcessStartInfo(_boardViewerAppPath);\r
+ pInfo.Arguments = \r
+ "/mode editposition /ncp /top /coords /size small /lpf " +\r
+ Path.Combine(_applicationDir, POSITION_FILE_NAME);\r
+\r
+ _process = new Process();\r
+ _process.StartInfo = pInfo;\r
+ _process.Start();\r
+ }\r
+ catch(Exception)\r
+ {\r
+ MessageBox.Show(this, "Unable to run viewer app", "Error", \r
+ MessageBoxButtons.OK, MessageBoxIcon.Error);\r
+ _boardViewerAppPath = null;\r
+ _process = null;\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ #region Event Handlers\r
+\r
+ /// <summary>\r
+ /// Handler for File | Open menu. Get the xml file to load.\r
+ /// </summary>\r
+ /// <param name="sender">ignored</param>\r
+ /// <param name="e">ignored</param>\r
+ private void OnOpenMenuClick(object sender, System.EventArgs e)\r
+ {\r
+ OpenFileDialog dialog = new OpenFileDialog();\r
+ dialog.Multiselect = false;\r
+ dialog.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";\r
+ if (dialog.ShowDialog(this) == DialogResult.OK)\r
+ {\r
+ Display(dialog.FileName);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Handles mouse down. if right-click on "board" node, \r
+ /// displays board context menu.\r
+ /// </summary>\r
+ /// <param name="sender">ignored</param>\r
+ /// <param name="e">select the tree node at the click\r
+ /// coords</param>\r
+ private void OnTreeViewMouseDown(object sender, MouseEventArgs e)\r
+ {\r
+ // this doesn't automatically happen\r
+ _treeView1.SelectedNode = _treeView1.GetNodeAt(e.X, e.Y);\r
+ if (e.Button.Equals(MouseButtons.Right))\r
+ {\r
+ string text = _treeView1.SelectedNode.Text;\r
+ if (text.StartsWith(TAG_BOARD))\r
+ {\r
+ _treeView1.ContextMenu = _contextMenu;\r
+ }\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// when view board menu item chosen, writes the selected board \r
+ /// position to a file and calls the viewer app.\r
+ /// </summary>\r
+ /// <param name="sender">ignored</param>\r
+ /// <param name="e">ignored</param>\r
+ private void OnViewBoardMenuClicked(object sender, EventArgs e)\r
+ {\r
+ string text = _treeView1.SelectedNode.Text;\r
+ if (text.StartsWith(TAG_BOARD))\r
+ {\r
+ ViewBoard(text);\r
+ }\r
+ _treeView1.ContextMenu = null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// If double-click a "board" node, calls the viewer \r
+ /// for the position\r
+ /// </summary>\r
+ /// <param name="sender"></param>\r
+ /// <param name="e"></param>\r
+ private void OnTreeViewDoubleClick(object sender, System.EventArgs e)\r
+ {\r
+ string text = _treeView1.SelectedNode.Text;\r
+ if (text.StartsWith(TAG_BOARD))\r
+ {\r
+ ViewBoard(text);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// set tooltip if over a node with a displayable tag \r
+ /// </summary>\r
+ /// <param name="sender">ignored</param>\r
+ /// <param name="e">holds mouse position</param>\r
+ private void OnTreeViewMouseMove(object sender, MouseEventArgs e)\r
+ {\r
+ TreeNode node = _treeView1.GetNodeAt(e.X, e.Y);\r
+ string tag = string.Empty;\r
+ if ((node != null) && (node.Tag != null))\r
+ {\r
+ tag = (string)node.Tag;\r
+ }\r
+ if (!tag.Equals(_tipText))\r
+ {\r
+ _tipText = tag;\r
+ _tip.SetToolTip(_treeView1, _tipText);\r
+ }\r
+ }\r
+\r
+\r
+ #endregion\r
+\r
+\r
+ }\r
+}\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<root>\r
+ <!-- \r
+ Microsoft ResX Schema \r
+ \r
+ Version 1.3\r
+ \r
+ The primary goals of this format is to allow a simple XML format \r
+ that is mostly human readable. The generation and parsing of the \r
+ various data types are done through the TypeConverter classes \r
+ associated with the data types.\r
+ \r
+ Example:\r
+ \r
+ ... ado.net/XML headers & schema ...\r
+ <resheader name="resmimetype">text/microsoft-resx</resheader>\r
+ <resheader name="version">1.3</resheader>\r
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r
+ <data name="Name1">this is my long string</data>\r
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>\r
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">\r
+ [base64 mime encoded serialized .NET Framework object]\r
+ </data>\r
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">\r
+ [base64 mime encoded string representing a byte array form of the .NET Framework object]\r
+ </data>\r
+ \r
+ There are any number of "resheader" rows that contain simple \r
+ name/value pairs.\r
+ \r
+ Each data row contains a name, and value. The row also contains a \r
+ type or mimetype. Type corresponds to a .NET class that support \r
+ text/value conversion through the TypeConverter architecture. \r
+ Classes that don't support this are serialized and stored with the \r
+ mimetype set.\r
+ \r
+ The mimetype is used for serialized objects, and tells the \r
+ ResXResourceReader how to depersist the object. This is currently not \r
+ extensible. For a given mimetype the value must be set accordingly:\r
+ \r
+ Note - application/x-microsoft.net.object.binary.base64 is the format \r
+ that the ResXResourceWriter will generate, however the reader can \r
+ read any of the formats listed below.\r
+ \r
+ mimetype: application/x-microsoft.net.object.binary.base64\r
+ value : The object must be serialized with \r
+ : System.Serialization.Formatters.Binary.BinaryFormatter\r
+ : and then encoded with base64 encoding.\r
+ \r
+ mimetype: application/x-microsoft.net.object.soap.base64\r
+ value : The object must be serialized with \r
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r
+ : and then encoded with base64 encoding.\r
+ mimetype: application/x-microsoft.net.object.bytearray.base64\r
+ value : The object must be serialized into a byte array \r
+ : using a System.ComponentModel.TypeConverter\r
+ : and then encoded with base64 encoding.\r
+ -->\r
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">\r
+ <xsd:element name="root" msdata:IsDataSet="true">\r
+ <xsd:complexType>\r
+ <xsd:choice maxOccurs="unbounded">\r
+ <xsd:element name="data">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />\r
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />\r
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ <xsd:element name="resheader">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" use="required" />\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:choice>\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+ </xsd:schema>\r
+ <resheader name="resmimetype">\r
+ <value>text/microsoft-resx</value>\r
+ </resheader>\r
+ <resheader name="version">\r
+ <value>1.3</value>\r
+ </resheader>\r
+ <resheader name="reader">\r
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+ <resheader name="writer">\r
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+ </resheader>\r
+ <data name="mainMenu1.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">\r
+ <value>17, 17</value>\r
+ </data>\r
+ <data name="$this.Name">\r
+ <value>Form1</value>\r
+ </data>\r
+ <data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">\r
+ <value>33</value>\r
+ </data>\r
+</root>
\ No newline at end of file