[Gtk-sharp-list] MonkeyGuide?: Hello World in GNOME.NET - Second Draft
Charles Iliya Krempeaux
charles@reptile.ca
15 Feb 2003 16:50:15 -0800
--=-/hX1OneEFp8WhdEzrLn3
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Hello,
First, this is being cross posted to both the Gtk# Mailing List and the
Mono Docs Mailing List. So make sure to do a "Reply to All" when
replying to this. (So that everyone can keep up with the conversation.)
This is my second draft of the GNOME.NET HelloWorld tutorial, for the
MonkeyGuide.
The first draft has already been posted in the MonekyGuide, and can be
found at:
http://go-mono.com/tutorial/html/en/gnome/bindings/gnome/hello_world.html
This second draft changes the use of the term "GNOME#" to "GNOME.NET".
Contains some mirror corrections and various modifications. Adds an
explanation of the "HelloWorld, third try" example code. Adds a
"HelloWorld, fourth try" and "HelloWorld, fifth try" section. And has
some other additions.
It is longer than the first draft. But it includes stuff to help
developers write more complex programs. (I've added this because I have
often heard the complaint that, "most example only show you the very
basics; but don't show you what to do to write real programs".)
(Some one else, with the ability, will again need to add this to the
MonkeyGuide.)
------- BEGIN -------
GNOME.NET
HelloWorld, first try
helloworld1.cs:
class HelloWorld
{
static void Main(string[] args)
{
Gnome.Program program =
new Gnome.Program("Hello World", "1.0", Gnome.Modules.UI,
args);
Gnome.App app = new Gnome.App("Hello World", "Hello World");
app.Show();
program.Run();
}
}
compile:
mcs helloworld1.cs -r gnome-sharp.dll
run:
mono helloworld1.exe
It's a bit longer than console Hello World and needs some explanation.
In Main() at first you see:
Gnome.Program program =
new Gnome.Program("Hello World", "1.0", Gnome.Modules.UI,
args);
This initializes GNOME and is needed in every GNOME application. Here
we are creating a variable of type Gnome.Program, called program. This
variable, program, is used to control the GNOME program, as we'll see
later.
Next we see:
Gnome.App app = new Gnome.App("Hello World", "Hello World");
This creates our GNOME application window. (That's what you see on the
screen.)
We then see:
app.Show();
This makes the GNOME Application Window (that you created with the
previous line on code) visible on the screen. With GNOME, things don't
automatically display themselves unless you explicitly tell them too.
And finally we see:
program.Run();
This make your GNOME program run. It makes all the magic happen, that
you don't need to worry about at this moment. Needless to say though,
you need to do this to make your GNOME Application work.
HelloWorld, second try
While the above program compiles and runs, it's doesn't quit, properly.
You have to exit by pressing CTRL+C. (Ideally, we want the program to
close when you press the "X" on the title bar. Which is what this next
example does.)
helloworld2.cs:
class HelloWorld
{
static Gnome.Program program;
static void Main(string[] args)
{
program =
new Gnome.Program("Hello World", "1.0", Gnome.Modules.UI,
args);
Gnome.App app = new Gnome.App("Hello World", "Hello World");
app.DeleteEvent += new
GtkSharp.DeleteEventHandler(delete_event);
app.Show();
program.Run();
}
static void delete_event(object obj, GtkSharp.DeleteEventArgs
args)
{
program.Quit();
}
}
compile:
mcs helloworld2.cs -r gnome-sharp.dll -r gtk-sharp.dll
run:
mono helloworld2.exe
The first change to notice is that the variable program has been moved
out of Main() and made a (static) class variable. We see this in the
line:
static Gnome.Program program;
This was done so we could access it from the delete_event function,
which we will talk about later.
The next difference we is in the Main() method, and is:
app.DeleteEvent += new
GtkSharp.DeleteEventHandler(delete_event);
This makes it so that when the "X" button on the title bar is pressed,
the function delete_event is called. Technically, when the "X" button
is pressed, the program receives a DeleteEvent, which is what you see in
the code above.
The final difference that you see is:
static void delete_event(object obj, GtkSharp.DeleteEventArgs
args)
{
program.Quit();
}
This is the function that is called when the application receives a
DeleteEvent. I.e., when the user clicks the "X" button on the title
bar. As you can hopefully see, when this function is called, the
program will quit.
HelloWorld, third try
While the above code functioned properly, and did what we wanted, it was
kind of sloppy. The sloppyness came from having to make the program
variable a (static) class variable. A much more elegant way of doing
the same thing involves using subclassing (also called inheritance) to
accomplish the same thing. Which can be seen in the example below.
helloworld3.cs:
class HelloWorld
: Gnome.Program
{
HelloWorld(string[] args)
: base("Hello World", "1.0", Gnome.Modules.UI, args)
{
// Nothing here.
}
static void Main(string[] args)
{
HelloWorld program = new HelloWorld(args);
program.run();
}
void run()
{
Gnome.App app = new Gnome.App("Hello World", "Hello World");
app.DeleteEvent += new
GtkSharp.DeleteEventHandler(delete_event);
app.Show();
this.Run();
}
void delete_event(object obj, GtkSharp.DeleteEventArgs args)
{
this.Quit();
}
}
compile:
mcs helloworld3.cs -r gnome-sharp.dll -r gtk-sharp.dll
run:
mono helloworld3.exe
If you just glance at this code, then it may seem much more complex than
the previous example. Two big things that you will probably notice
right away are: we now have a constructor (which we didn't have before),
and we have a new method named run(). (There are some other
modifications too.)
However, in terms of Object Oriented Programming, this code example is
much better. Doing things this way makes our software much easier to
maintain and modify. This is something you will appreciate as the size
of your software system grows.
In the code, we first we see:
class HelloWorld
: Gnome.Program
{
This makes our class a subclass of the Gnome.Program class. (So instead
of creating and using a variable of type Gnome.Program, we will instead
do everything with our own class. As we will see later.)
We next see:
HelloWorld(string[] args)
: base("Hello World", "1.0", Gnome.Modules.UI, args)
{
// Nothing here.
}
This, newly added code, is a constructor for our class. The purpose of
it is to call the constructor of Gnome.Program with the correct
arguments.
And then, in the Main() procedure, we first see:
HelloWorld program = new HelloWorld(args);
This creates an instance our class.
These three portions of code basically take the place of:
Gnome.Program program =
new Gnome.Program("Hello World", "1.0", Gnome.Modules.UI,
args);
which we saw in helloworld1.cs.
Next, in Main(), we see:
program.run();
This is essentially equivalent of:
program.Run();
from helloworld1.cs and helloworld2.cs. Although, as we will soon see,
our new run() does much more.
Next we see the definition of run():
void run()
{
Gnome.App app = new Gnome.App("Hello World", "Hello World");
app.DeleteEvent += new
GtkSharp.DeleteEventHandler(delete_event);
app.Show();
this.Run();
}
In addition to calling the Run() method from Gnome.Program (which we see
on the last line of this method). Our run() method also handles all the
other activities relating to our GNOME application window, that we were
previously doing in our Main() procedure, in helloworld1.cs and
helloworld2.cs.
The last thing we see is the definition of the delete_event() method.
However, since this has not changed from our previous example, we will
not discuss it again.
HelloWorld, fourth try
Although the previous example was pretty good. There was still one
problem. The special Main() procedure (which is the beginning of life
for our program) was intertwined within our GNOME program class. (I.e.,
it was a part of the class named HelloWorld.) It is good programming
practise to have Main() separate from everything else, as you can see in
the code sample below.
helloworld4.cs:
class HelloWorld
: Gnome.Program
{
HelloWorld(string[] args)
: base("Hello World", "1.0", Gnome.Modules.UI, args)
{
// Nothing here.
}
void run()
{
Gnome.App app = new Gnome.App("Hello World", "Hello World");
app.DeleteEvent += new
GtkSharp.DeleteEventHandler(delete_event);
app.Show();
this.Run();
}
void delete_event(object obj, GtkSharp.DeleteEventArgs args)
{
this.Quit();
}
}
class MainClass
{
static void Main(string[] args)
{
HelloWorld program = new HelloWorld(args);
program.run();
}
}
compile:
mcs helloworld4.cs -r gnome-sharp.dll -r gtk-sharp.dll
run:
mono helloworld4.exe
The only difference in this code, from that of helloworld3.cs, is that a
new class, named MainClass, has been created; and the special Main()
procedure has been moved to it.
HelloWorld, fifth try
As your software gets larger, it will become necessary for you to use
multiple files for you project. This fifth and final incarnation of our
GNOME.NET HelloWorld program separates out our two classes into two
files to illustrate this. And shows you how to compile a program with
multiple source files. (Other than that, no other modifications have
been made to our program.)
HelloWorld.cs:
class HelloWorld
: Gnome.Program
{
HelloWorld(string[] args)
: base("Hello World", "1.0", Gnome.Modules.UI, args)
{
// Nothing here.
}
void run()
{
Gnome.App app = new Gnome.App("Hello World", "Hello World");
app.DeleteEvent += new
GtkSharp.DeleteEventHandler(delete_event);
app.Show();
this.Run();
}
void delete_event(object obj, GtkSharp.DeleteEventArgs args)
{
this.Quit();
}
}
Main.cs:
class MainClass
{
static void Main(string[] args)
{
HelloWorld program = new HelloWorld(args);
program.run();
}
}
compile:
mcs Main.cs HelloWorld.cs -r gnome-sharp.dll -r gtk-sharp.dll -o
HelloWorld.exe
run:
mono HelloWorld.exe
Your own programs should follow this example.
-------- END --------
I have a Druid tutorial I'm writing right now. I'll be posting that
soon.
See ya
--
Charles Iliya Krempeaux, BSc
charles@reptile.ca
________________________________________________________________________
Reptile Consulting & Services 604-REPTILE http://www.reptile.ca/
--=-/hX1OneEFp8WhdEzrLn3
Content-Type: text/html; charset=utf-8
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
<META NAME="GENERATOR" CONTENT="GtkHTML/1.1.8">
</HEAD>
<BODY>
Hello,<BR>
<BR>
First, this is being cross posted to both the Gtk# Mailing List and the Mono Docs Mailing List. So make sure to do a "Reply to All" when replying to this. (So that everyone can keep up with the conversation.)<BR>
<BR>
This is my second draft of the GNOME.NET HelloWorld tutorial, for the MonkeyGuide.<BR>
<BR>
The first draft has already been posted in the MonekyGuide, and can be found at:<BR>
<BR>
<A HREF="http://go-mono.com/tutorial/html/en/gnome/bindings/gnome/hello_world.html"><TT>http://go-mono.com/tutorial/html/en/gnome/bindings/gnome/hello_world.html</TT></A><BR>
<BR>
This second draft changes the use of the term "GNOME#" to "GNOME.NET". Contains some mirror corrections and various modifications. Adds an explanation of the "HelloWorld, third try" example code. Adds a "HelloWorld, fourth try" and "HelloWorld, fifth try" section. And has some other additions.<BR>
<BR>
It is longer than the first draft. But it includes stuff to help developers write more complex programs. (I've added this because I have often heard the complaint that, "most example only show you the very basics; but don't show you what to do to write <I>real</I> programs".)<BR>
<BR>
(Some one else, with the ability, will again need to add this to the MonkeyGuide.)<BR>
<BR>
<FONT SIZE="3"><TT>------- BEGIN -------</TT></FONT><BR>
<BR>
<H1>GNOME.NET</H1>
<H2>HelloWorld, first try</H2>
<BR>
<TT>helloworld1.cs</TT>:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> class HelloWorld<BR>
{<BR>
static void Main(string[] args)<BR>
{<BR>
Gnome.Program program =<BR>
new Gnome.Program("Hello World", "1.0", Gnome.Modules.UI, args);<BR>
<BR>
Gnome.App app = new Gnome.App("Hello World", "Hello World");<BR>
app.Show();<BR>
<BR>
program.Run();<BR>
}<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
compile:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mcs helloworld1.cs -r gnome-sharp.dll</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
run:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mono helloworld1.exe</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
It's a bit longer than console Hello World and needs some explanation.<BR>
<BR>
In <FONT SIZE="3"><TT>Main()</TT></FONT> at first you see:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d4d4d4">
<FONT SIZE="3"><TT> Gnome.Program program =<BR>
new Gnome.Program("Hello World", "1.0", Gnome.Modules.UI, args);</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This initializes GNOME and is needed in every GNOME application. Here we are creating a variable of type <FONT SIZE="3"><TT>Gnome.Program</TT></FONT>, called <FONT SIZE="3"><TT>program</TT></FONT>. This variable, <FONT SIZE="3"><TT>program</TT></FONT>, is used to control the GNOME program, as we'll see later.<BR>
<BR>
Next we see:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d4d4d4">
<FONT SIZE="3"><TT> Gnome.App app = new Gnome.App("Hello World", "Hello World");</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This creates our GNOME application window. (That's what you see on the screen.)<BR>
<BR>
We then see:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d4d4d4">
<FONT SIZE="3"><TT> app.Show();</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This makes the GNOME Application Window (that you created with the previous line on code) visible on the screen. With GNOME, things don't automatically display themselves unless you explicitly tell them too.<BR>
<BR>
And finally we see:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d4d4d4">
<FONT SIZE="3"><TT> program.Run();</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This make your GNOME program <FONT SIZE="3"><I>run</I></FONT>. It makes all the magic happen, that you don't need to worry about at this moment. Needless to say though, you need to do this to make your GNOME Application work.<BR>
<BR>
<BR>
<H2>HelloWorld, second try</H2>
While the above program compiles and runs, it's doesn't quit, properly. You have to exit by pressing CTRL+C. (Ideally, we want the program to close when you press the "X" on the title bar. Which is what this next example does.)<BR>
<BR>
<TT>helloworld2.cs</TT>:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> class HelloWorld<BR>
{<BR>
static Gnome.Program program;<BR>
<BR>
static void Main(string[] args)<BR>
{<BR>
program =<BR>
new Gnome.Program("Hello World", "1.0", Gnome.Modules.UI, args);<BR>
<BR>
Gnome.App app = new Gnome.App("Hello World", "Hello World");<BR>
app.DeleteEvent += new GtkSharp.DeleteEventHandler(delete_event);<BR>
app.Show();<BR>
<BR>
program.Run();<BR>
}<BR>
<BR>
static void delete_event(object obj, GtkSharp.DeleteEventArgs args)<BR>
{<BR>
program.Quit();<BR>
}<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
compile:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mcs helloworld2.cs -r gnome-sharp.dll -r gtk-sharp.dll</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
run:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mono helloworld2.exe</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
The first change to notice is that the variable <FONT SIZE="3"><TT>program</TT></FONT> has been moved out of <TT>Main()</TT> and made a (static) class variable. We see this in the line:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d4d4d4">
<FONT SIZE="3"><TT> static Gnome.Program program;</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This was done so we could access it from the <FONT SIZE="3"><TT>delete_event</TT></FONT> function, which we will talk about later.<BR>
<BR>
The next difference we is in the <FONT SIZE="3"><TT>Main()</TT></FONT> method, and is:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d4d4d4">
<FONT SIZE="3"><TT> app.DeleteEvent += new GtkSharp.DeleteEventHandler(delete_event);</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This makes it so that when the "X" button on the title bar is pressed, the function <FONT SIZE="3"><TT>delete_event</TT></FONT> is called. Technically, when the "X" button is pressed, the program receives a <FONT SIZE="3"><TT>DeleteEvent</TT></FONT>, which is what you see in the code above.<BR>
<BR>
The final difference that you see is:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d4d4d4">
<FONT SIZE="3"><TT> static void delete_event(object obj, GtkSharp.DeleteEventArgs args)<BR>
{<BR>
program.Quit();<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This is the function that is called when the application receives a <FONT SIZE="3"><TT>DeleteEvent</TT></FONT>. I.e., when the user clicks the "X" button on the title bar. As you can hopefully see, when this function is called, the program will quit.<BR>
<BR>
<BR>
<H2>HelloWorld, third try</H2>
While the above code functioned properly, and did what we wanted, it was kind of sloppy. The sloppyness came from having to make the <FONT SIZE="3"><TT>program</TT></FONT> variable a (static) class variable. A much more elegant way of doing the same thing involves using subclassing (also called inheritance) to accomplish the same thing. Which can be seen in the example below.<BR>
<BR>
<TT>helloworld3.cs</TT>:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> class HelloWorld<BR>
: Gnome.Program<BR>
{<BR>
HelloWorld(string[] args)<BR>
: base("Hello World", "1.0", Gnome.Modules.UI, args)<BR>
{ <BR>
// Nothing here.<BR>
}<BR>
<BR>
static void Main(string[] args)<BR>
{<BR>
HelloWorld program = new HelloWorld(args);<BR>
<BR>
program.run();<BR>
}<BR>
<BR>
void run()<BR>
{<BR>
Gnome.App app = new Gnome.App("Hello World", "Hello World");<BR>
app.DeleteEvent += new GtkSharp.DeleteEventHandler(delete_event);<BR>
app.Show();<BR>
<BR>
this.Run();<BR>
}<BR>
<BR>
void delete_event(object obj, GtkSharp.DeleteEventArgs args)<BR>
{<BR>
this.Quit();<BR>
}<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
compile:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mcs helloworld3.cs -r gnome-sharp.dll -r gtk-sharp.dll</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
run:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mono helloworld3.exe</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
If you just glance at this code, then it may seem much more complex than the previous example. Two big things that you will probably notice right away are: we now have a constructor (which we didn't have before), and we have a new method named <TT>run()</TT>. (There are some other modifications too.)<BR>
<BR>
However, in terms of Object Oriented Programming, this code example is much better. Doing things this way makes our software much easier to maintain and modify. This is something you will appreciate as the size of your software system grows.<BR>
<BR>
In the code, we first we see:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> class HelloWorld<BR>
: Gnome.Program<BR>
{</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This makes our class a subclass of the <TT>Gnome.Program</TT> class. (So instead of creating and using a variable of type <TT>Gnome.Program</TT>, we will instead do everything with our own class. As we will see later.)<BR>
<BR>
We next see:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> HelloWorld(string[] args)<BR>
: base("Hello World", "1.0", Gnome.Modules.UI, args)<BR>
{ <BR>
// Nothing here.<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This, newly added code, is a constructor for our class. The purpose of it is to call the constructor of <TT>Gnome.Program</TT> with the correct arguments.<BR>
<BR>
And then, in the <TT>Main()</TT> procedure, we first see:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> HelloWorld program = new HelloWorld(args);</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This creates an instance our class.<BR>
<BR>
These three portions of code basically take the place of:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> Gnome.Program program =<BR>
new Gnome.Program("Hello World", "1.0", Gnome.Modules.UI, args);</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
which we saw in <TT>helloworld1.cs</TT>.<BR>
<BR>
Next, in <TT>Main()</TT>, we see:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> program.run();</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
This is essentially equivalent of:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> program.Run();</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
from <TT>helloworld1.cs</TT> and <TT>helloworld2.cs</TT>. Although, as we will soon see, our new <TT>run()</TT> does much more.<BR>
<BR>
Next we see the definition of <TT>run()</TT>:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> void run()<BR>
{<BR>
Gnome.App app = new Gnome.App("Hello World", "Hello World");<BR>
app.DeleteEvent += new GtkSharp.DeleteEventHandler(delete_event);<BR>
app.Show();<BR>
<BR>
this.Run();<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
In addition to calling the <TT>Run()</TT> method from <TT>Gnome.Program</TT> (which we see on the last line of this method). Our <TT>run()</TT> method also handles all the other activities relating to our GNOME application window, that we were previously doing in our <TT>Main()</TT> procedure, in <TT>helloworld1.cs</TT> and <TT>helloworld2.cs</TT>.<BR>
<BR>
The last thing we see is the definition of the <FONT SIZE="3"><TT>delete_event()</TT> method. However, since this has not changed from our previous example, we will not discuss it again.</FONT><BR>
<BR>
<BR>
<H2>HelloWorld, fourth try</H2>
Although the previous example was pretty good. There was still one problem. The special <TT>Main()</TT> procedure (which is the beginning of life for our program) was intertwined within our GNOME program class. (I.e., it was a part of the class named <TT>HelloWorld</TT>.) It is good programming practise to have <TT>Main()</TT> separate from everything else, as you can see in the code sample below.<BR>
<BR>
<TT>helloworld4.cs</TT>:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> class HelloWorld<BR>
: Gnome.Program<BR>
{<BR>
HelloWorld(string[] args)<BR>
: base("Hello World", "1.0", Gnome.Modules.UI, args)<BR>
{ <BR>
// Nothing here.<BR>
}<BR>
<BR>
void run()<BR>
{<BR>
Gnome.App app = new Gnome.App("Hello World", "Hello World");<BR>
app.DeleteEvent += new GtkSharp.DeleteEventHandler(delete_event);<BR>
app.Show();<BR>
<BR>
this.Run();<BR>
}<BR>
<BR>
void delete_event(object obj, GtkSharp.DeleteEventArgs args)<BR>
{<BR>
this.Quit();<BR>
}<BR>
}<BR>
<BR>
<BR>
class MainClass<BR>
{<BR>
static void Main(string[] args)<BR>
{<BR>
HelloWorld program = new HelloWorld(args);<BR>
<BR>
program.run();<BR>
}<BR>
<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
compile:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mcs helloworld4.cs -r gnome-sharp.dll -r gtk-sharp.dll</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
run:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mono helloworld4.exe</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
The only difference in this code, from that of <TT>helloworld3.cs</TT>, is that a new class, named <TT>MainClass</TT>, has been created; and the special <TT>Main()</TT> procedure has been moved to it.<BR>
<FONT SIZE="3"><TT><BR>
</TT></FONT><BR>
<H2>HelloWorld, fifth try</H2>
As your software gets larger, it will become necessary for you to use multiple files for you project. This fifth and final incarnation of our GNOME.NET HelloWorld program separates out our two classes into two files to illustrate this. And shows you how to compile a program with multiple source files. (Other than that, no other modifications have been made to our program.)<BR>
<BR>
<TT>HelloWorld.cs</TT>:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> class HelloWorld<BR>
: Gnome.Program<BR>
{<BR>
HelloWorld(string[] args)<BR>
: base("Hello World", "1.0", Gnome.Modules.UI, args)<BR>
{ <BR>
// Nothing here.<BR>
}<BR>
<BR>
void run()<BR>
{<BR>
Gnome.App app = new Gnome.App("Hello World", "Hello World");<BR>
app.DeleteEvent += new GtkSharp.DeleteEventHandler(delete_event);<BR>
app.Show();<BR>
<BR>
this.Run();<BR>
}<BR>
<BR>
void delete_event(object obj, GtkSharp.DeleteEventArgs args)<BR>
{<BR>
this.Quit();<BR>
}<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
<BR>
<TT>Main.cs</TT>:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#d5d5d5">
<FONT SIZE="3"><TT> class MainClass<BR>
{<BR>
static void Main(string[] args)<BR>
{<BR>
HelloWorld program = new HelloWorld(args);<BR>
<BR>
program.run();<BR>
}<BR>
<BR>
}</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
<BR>
compile:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mcs Main.cs HelloWorld.cs -r gnome-sharp.dll -r gtk-sharp.dll -o HelloWorld.exe</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<BR>
run:<BR>
<BR>
<TABLE BGCOLOR="#bfbfbf" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<TABLE BGCOLOR="#f2f2f2" CELLSPACING="1" CELLPADDING="3" WIDTH="100%">
<TR>
<TD BGCOLOR="#808080">
<FONT COLOR="#ffffff" SIZE="3"><TT>mono HelloWorld.exe</TT></FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<BR>
<FONT SIZE="3"><BR>
Your own programs should follow this example.<BR>
<TT><BR>
-------- END --------</TT></FONT><BR>
<BR>
I have a Druid tutorial I'm writing right now. I'll be posting that soon.<BR>
<BR>
<BR>
See ya<BR>
<BR>
<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>--
Charles Iliya Krempeaux, BSc
charles@reptile.ca
________________________________________________________________________
Reptile Consulting & Services 604-REPTILE http://www.reptile.ca/</PRE>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
--=-/hX1OneEFp8WhdEzrLn3--