At some point down the line this got fixed, so a console application today can have UI elements - for example, it can call MessageBox(). Despite the weirdness - I am sure HCI purists/Apple would never approve of it - it can actually come quite handy. I, for one, quite often find myself in need of a graphic in the middle of a simple application (sometimes to just visualize something as part of a debug code path) - which I don't want to convert to fully-fledged GUI.
Unfortunately, there is precious little information on how to do do mixed mode console/GUI programming on the Internet, so I figured I'd fill the void :-).
First add references to System.Windows.Forms and System.Drawing (only if you are going to be drawing of course) to your app, as well as the corresponding "using"s.
Then you can create a dialog box that derives from Form:
using System.Windows.Forms;
class MyForm : Form
{
}
...and display it as follows:
MyForm f = new MyForm();
f.ShowDialog();
ShowDialog function is blocking - your console thread will not get control until user closes the window. Of course, standard console functions all work, you can print to the screen like so:
class MyForm : Form
{
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Console.WriteLine("Paint called!");
}
}
As an example, here is a very simple application that allows a user to plot simple functions from Math library:
//-----------------------------------------------------------------------
//
// Copyright (C) Sergey Solyanik.
//
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
//
//-----------------------------------------------------------------------
using System;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
namespace Graph
{
class Graph : Form
{
public delegate double Function(double x);
public Function F;
public double X1;
public double X2;
public double Y1;
public double Y2;
private double stretchX;
private double stretchY;
private int ToScreenX(double x)
{
return ClientRectangle.Left + (int)((x - X1) * stretchX);
}
private int ToScreenY(double y)
{
return ClientRectangle.Bottom + (int)((y - Y1) * stretchY);
}
private double ToPlaneX(int x)
{
return X1 + ((double)(x - ClientRectangle.Left)) / stretchX;
}
private double ToPlaneY(int y)
{
return Y1 + ((double)(y - ClientRectangle.Bottom)) / stretchY;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
stretchX = (double)(ClientRectangle.Right - ClientRectangle.Left) /
(X2 - X1);
stretchY = (double)(ClientRectangle.Top - ClientRectangle.Bottom) /
(Y2 - Y1);
if (Math.Sign(X1) != Math.Sign(X2))
{
e.Graphics.DrawLine(
Pens.Black,
ToScreenX(0),
ClientRectangle.Bottom,
ToScreenX(0),
ClientRectangle.Top);
}
if (Math.Sign(Y1) != Math.Sign(Y2))
{
e.Graphics.DrawLine(
Pens.Black,
ClientRectangle.Left,
ToScreenY(0),
ClientRectangle.Right,
ToScreenY(0));
}
for (int x = ClientRectangle.Left; x < ClientRectangle.Right - 1; ++x)
{
e.Graphics.DrawLine(
Pens.Blue,
x,
ToScreenY(F(ToPlaneX(x))),
x + 1,
ToScreenY(F(ToPlaneX(x + 1))));
}
}
}
class Program
{
private static Graph.Function SelectFunction()
{
Console.WriteLine("Available functions:");
Type t = typeof(Math);
MethodInfo[] m = t.GetMethods();
for (int i = 0; i < m.Length; ++i)
{
if (m[i].IsPublic && m[i].IsStatic && m[i].ReturnType == typeof(double))
{
ParameterInfo[] p = m[i].GetParameters();
if (p.Length == 1 && p[0].ParameterType == typeof(double))
Console.WriteLine(" " + m[i].Name);
}
}
while (true)
{
Console.Write("Select a function to plot: ");
string response = Console.ReadLine();
for (int i = 0; i < m.Length; ++i)
{
if (m[i].IsPublic && m[i].IsStatic && m[i].ReturnType == typeof(double))
{
ParameterInfo[] p = m[i].GetParameters();
if (p.Length == 1 && p[0].ParameterType == typeof(double))
{
if (m[i].Name.Equals(response))
{
return (Graph.Function)
Delegate.CreateDelegate(typeof(Graph.Function), m[i]);
}
}
}
}
}
}
private static double GetNumber(string prompt)
{
for (; ; )
{
Console.Write(prompt);
string response = Console.ReadLine();
double result;
if (double.TryParse(response, out result))
return result;
}
}
static void Main(string[] args)
{
Console.CancelKeyPress += delegate
{
Console.WriteLine("Cancelled!");
Environment.Exit(1);
};
Console.WriteLine("Press Ctrl-C to quit.");
Console.WriteLine();
Graph g = new Graph();
g.F = SelectFunction();
g.X1 = GetNumber("Abscissa lower boundary: ");
g.X2 = GetNumber("Abscissa upper boundary: ");
g.Y1 = GetNumber("Ordinate lower boundary: ");
g.Y2 = GetNumber("Ordinate upper boundary: ");
g.ShowDialog();
}
}
}
1 comment:
It's good about Graphic in Cosole Process. It's best console related idea.
Post a Comment