Tuesday, February 21, 2017

Brief Comparison of Four Graphic Compilers

Brief Comparison of Four Graphic Compilers

In the last couple of months I've used four different compilers to create similar applications to interface with Windows to display and interact with forms and their widgets.

I first tried GtkAda.  I discovered that it was difficult to use and also seemed to be need work.  For instance, when I tried a text box it could be displayed but the user (that is, me) couldn't enter anything into it.

I next tried to use the Linux version of visual C# (Mono) using the Window operating system.  This requires the use of CygWin.  I attempted to use instructions from approximately seven years ago that I had saved and then newer ones that I found online.  With none of them could I completely finish the installation to enable me to use Mono to interface to Windows.  I was able to install the Mono that runs under Windows but runs as a DOS-like application in a Linux-like way.  But I couldn't get to the point where I could get Mono that runs as its own Windows application where I could determine if it could create Windows applications.  A number of years ago I did use Mono running under Linux where I could create visual applications.  But as much as I tried to follow the various online instructions of how to do an install for Windows, I wasn't able to succeed.

After giving up on that I went back to the Microsoft Visual Express compilers that I used years ago - Microsoft Visual C++ 2010 Express and Microsoft Visual C# 2010 Express.  My trial usage ran out years ago but I found I could still use them if I first launched the compiler and selected the application rather than trying to launch a particular previously created application.  (Note: Obtaining an updated compiler now costs thousands of dollars which is out-of-range for my recreational use.)

Since I had previously used C# for my exploratory projects, after discovering that I could still use the compilers by launching them, I tried creating Visual C++ application similar to the GtkAda application to see the difference.  That is, an application that displays a few buttons including those inside of a container and a text box and can interact with mouse clicks on these widgets.

The old Microsoft Visual C++ 2010 Express was much, much easier to use than GtkAda and, in addition, the text box could actually be used.  Although I couldn't find a way to know when the user was finished entering into the text box.  Online searches showed that others had the same problem and had devised ways such as using a timer to anticipate that the user was finished with their entry.

I added a Done button instead.   Then, read the entered text via the Done button event handler.  This resulted in finding out that the format of the text was not a C/C++ string but something else entirely that required a conversion to obtain a C/C++ string.

In looking into this I found comments such as "Microsoft's advise would seem to be if you want to do Windows Desktop UI code (with the .Net framework), use C# (or VB.NET)." rather than Visual C++ and, in response to a question, "Looks to me like you're using C++/CLI which is NOT C++. It is a completely different language created by Microsoft to supersede Managed Extensions for C++. (.NET)."

Therefore, I repeated the application in Visual C#.  The general code to create the widgets and the event handlers was much the same.  (Except for using dot notation in C# versus the '->' notation of the Visual C++.)  In each case, the code to initialize the widgets that were placed into the displayed form was created automatically.  Just in it own .cs file in C# versus being in the same file as the event handlers as in Visual C++.

In neither case was a Key Up or Down event handler added automatically when double clicking on the displayed widget.  Versus a handler for when the contents were changed which was.

But I was able to add a Key Down event handler to the C# application and manually add it to the initialization of the text box.  And without problem have it check if the key was the Enter (i.e., Return) key to indicate that the user was finished entering text.  Therefore, although I didn't remove the Done button from the form, it was no longer needed.

Also, the TextChanged event handler that was added by double clicking the text box wasn't needed for this application so it could have been eliminated.  Although it would be needed if trying to restrict the input of certain characters in some way – such as only to digits.

And when getting the entered text (upon detecting the use of the Enter key), a normal C string could be directly used.  Therefore, C# was much more C-like than Visual C++.

In conclusion, Visual C# was easier to use than Visual C++ and the entire application took less than a day.  So much different from GtkAda.  If memory serves at all, Mono under Linux was similar.

To complete this report, the code and the form (as first displayed before buttons or labels were hidden due to mouse clicks on other buttons or the entry of any text) are shown below.  Only the code inside an event handler had to be written along with the line to initialize the use of the KeyDown event handler for the text box.  The rest was generated by the compiler.

Note, button4_Click is the event handler for the Done button.  "Done" is the text displayed on the button via the button's properties.  The name of the button can be changed but I noticed, when I did so for Visual C++, the previously generated code wasn't always automatically updated.  So rather than needing to update the names my hand I didn't bother with the C# application since proper naming wasn't my concern in creating the application.  Thus I don't know if Visual C# would have tracked the property changes better.  And, of course, the compiler is many years out of date and a newer one would need to be used for an actual application.

Note:  In the display of the form, the container panel cannot be seen against the background of the form itself.  However, button3 is a child of the container.  If button1 is clicked button3 is hidden.  As can be seen from the code, the handler for button1 hides the panel as well as label1.  And hiding the panel of which button3 is a child, hides the button as well.


Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Form1.Designer.cs with Initialize
namespace WindowsFormsApplication1
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.panel1 = new System.Windows.Forms.Panel();
            this.button3 = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.button4 = new System.Windows.Forms.Button();
            this.panel1.SuspendLayout();
            this.SuspendLayout();
            //
            // button1
            //
            this.button1.Location = new System.Drawing.Point(447, 128);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            //
            // button2
            //
            this.button2.Location = new System.Drawing.Point(484, 259);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 23);
            this.button2.TabIndex = 1;
            this.button2.Text = "button2";
            this.button2.UseVisualStyleBackColor = true;
            //
            // label1
            //
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(434, 223);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(46, 17);
            this.label1.TabIndex = 2;
            this.label1.Text = "label1";
            this.label1.Click += new System.EventHandler(this.label1_Click);
            //
            // panel1
            //
            this.panel1.Controls.Add(this.button3);
            this.panel1.Location = new System.Drawing.Point(114, 111);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(261, 190);
            this.panel1.TabIndex = 3;
            //
            // button3
            //
            this.button3.Location = new System.Drawing.Point(143, 81);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(75, 23);
            this.button3.TabIndex = 0;
            this.button3.Text = "button3";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);
            //
            // textBox1
            //
            this.textBox1.Location = new System.Drawing.Point(423, 377);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 22);
            this.textBox1.TabIndex = 4;
            this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
            this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyDown);
            //
            // button4
            //
            this.button4.Location = new System.Drawing.Point(538, 376);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(52, 23);
            this.button4.TabIndex = 5;
            this.button4.Text = "Done";
            this.button4.UseVisualStyleBackColor = true;
            this.button4.Click += new System.EventHandler(this.button4_Click);
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(631, 462);
            this.Controls.Add(this.button4);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.panel1);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.panel1.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Panel panel1;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Button button4;
    }
}

Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (this.label1.Visible == true)
            {
                this.label1.Visible = false;
                this.panel1.Visible = false;
            }
            else
            {
                this.label1.Visible = true;
                this.panel1.Visible = true;
            }

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (this.button2.Visible == true)
            {
                this.button2.Visible = false;
            }
            else
            {
                this.button2.Visible = true;
            }
        }

        private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
      if (this.label1.Visible == true)
{
   this.label1.Visible = false;
}
else
{
   this.label1.Visible = true;
}
if (e.KeyCode == Keys.Return)
{
   this.button1.Visible = false;
                 string standardString = textBox1.Text;
             }
}

        private void button4_Click(object sender, EventArgs e)
        {
             if (this.label1.Visible == true)
{
   this.label1.Visible = false;
}
else
{
   this.label1.Visible = true;
}
             string standardString = textBox1.Text;
        }    
    }
}


No comments: