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:
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:
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:
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:
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:
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:
This is essentially equivalent of:
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:
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:
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
[EMAIL PROTECTED]
________________________________________________________________________
Reptile Consulting & Services 604-REPTILE http://www.reptile.ca/
|