Articles : Using Mono and GTK# on Win32

A quick introduction to using GTk# with Mono for Windows written and contributed by Brian Rose

Quick Navigation:

  • Overview
  • Installation
  • Hello World
  • Conclusion

    Overview

    One of the longest held goals of computing was a system to develop software and have it run on a variety of different architectures. Platform independence allows the developer to concentrate on developing a solution to the problem instead of worrying about the specifics of the platform at hand. If you wanted to develop software to ask the user a question and then get an answer back, you would have to develop a Windows program, a Mac program, and a host of other programs for all the platforms you wanted to support (like PDAs or customized embedded devices). Console applications are rather easy to port, but graphical applications have been quite resistant. Graphical environments developed by different companies all have different APIs (Application Programming Interfaces) due to the fact that they run on different hardware and operating systems. What was needed was a way to abstract all of this from the application programmer's point of view.

    The first language to achieve success on a reasonable scale was Java. Java was developed by Sun Microsystems to allow programmers to release one executeable and have it run on any machine. This was accomplished by having the Java compiler produce an intermediate "byte code" that contained the instructions for a virtual machine. This byte code would be instructions and data like "create a 200x100 window and put a button at (10,10)". The Java virtual machine would then read this command in the byte code and make the appropriate system calls for whatever hardware/OS platform that the virtual machine was running on. So as long as the developer targets the virtual machine, the same program can run on any platform that the virtual machine runs on.

    Microsoft, not wanting to be left out, developed .Net and the C# language. With similiar goals and structure, moving between Java to .Net is relatively straightforward. If you are familiar with Java, then you got a pretty good idea of how .Net is going to work.

    Unlike their past endeavors, Microsoft submitted the specifications for the .Net runtime to various standards bodies. The benefit for us is that if you develop code to that specification, it will run on a .Net machine. This has allowed open source developers to create a .Net suite of tools, called Mono, to allow programmers to create software without having to pay for Microsoft tools. It has also allowed open source developers to create .Net runtimes on other operating systems, like Linux.

    Installation

    Well, enough about .Net history and how it can change the world, let's install something. You can download everything you need from the Mono website I downloaded the 1.0.2 version of the Windows installer, which comes with GTK#, which is a library of common things like buttons, menus and other widgets. The installer is self-documenting and I simply stuck with the default installation. After running the installer you should be ready to roll.

    Hello World

    Everyone starts learning a new language with the traditional "Hello World" application. Like Java, we have two options. The simplest is the console based application and the slightly more complex is the graphical program.

    Console

    Below is a listing for a simple console program, which I saved as Hello.cs.

       public class HelloWorld  
       {
          static void Main()  
          {
             System.Console.WriteLine("Hello World");
          }
       }
    
    When Mono installs, it will create a "Mono Command Prompt" shortcut on your desktop and/or Start menu. All it does is run the console and prepend the Mono binary folder path to the PATH environment variable. If you like, you can do this yourself by copying the path out of the setmonopath.bat file, and pasting it into your environment. For the windows console, right click "My Computer", select Properties, select the Advanced tab and the Environment button should be near the bottom of the window. If you use another shell, simply copy the same path into the relevant place for your shell. Type mcs to see if you can invoke the compiler. To compile the above program, you need to invoke the compiler and pass the source code as the argument. The compiler will read the file and produce an EXE file with the source base name. So my Hello.cs is compiled into Hello.exe. If you want to change the name, you can use the -out flag like this...
       mcs -out:HelloWorld.exe Hello.cs
       

    GTK#

    Console applications are no big deal. But making a graphical program is a bit more involved. To really do anything useful, you need a widget set. Widgets are those little things that make a graphical program graphical. Windows, menus, buttons, and all those other things that when put together, make a familiar program interface. When you installed Mono, you installed one such widget set - GTK# (for the history of GTK, visit the website). All you need to do now is to include that into your program. This is done in the source with the Using directive, and in the makefile, with various link options passed to the compiler. Here is the source for my first little GUI app.

       // helloworld.cs - Gtk# Tutorial example
    
       using Gtk;
       using GtkSharp;
       using System;
       using System.Drawing;
    
       public class helloworld {
    
    
       /* This is a callback function. The data arguments are ignored
        * in this example. More on callbacks below. */
    
       static void hello (object obj, EventArgs args)
       {
    
       	// Console.WriteLine("Hello World");
       	Application.Quit ();
       }
    
       static void delete_event (object obj, DeleteEventArgs args)
       {
       	// If you return FALSE in the "delete_event" signal handler,
       	// GTK will emit the "destroy" signal. Returning TRUE means
       	// you don't want the window to be destroyed.
       	// This is useful for popping up 'are you sure you want to quit?'
       	// type dialogs. 
           Console.WriteLine ("delete event occurred\n");
           Application.Quit ();
       }
    
       public static void Main(string[] args)
       {
       	/* This is called in all GTK applications. Arguments are parsed
       	 * from the command line and are returned to the application. */
       	Application.Init ();
    
    	/* create a new window */
    	Window window = new Window ("helloworld");
    	/* When the window is given the "delete_event" signal (this is 
    	 * given by the window manager, usually by the "close" option, or
    	 * on the titlebar), we ask it to call the delete_event () 
    	 * function as defined above. The data passed to the callback
    	 * function is NULL and is ignored in the callback function. */
    
    	window.DeleteEvent += new DeleteEventHandler (delete_event);
        
    	/* Sets the border width of the window. */
    	window.BorderWidth = 10;
    	window.Resize(250, 250);
    	
    	/*  gtk_container_set_border_width (GTK_CONTAINER (window), 10);*/
        
    	/* Creates a new button with the label "Hello World". */ 
    	Button btn = new Button ("Press to quit");
        
    	/* When the button receives the "clicked" signal, it will call the
    	 * function hello() passing it NULL as its argument.  The hello()
    	 * function is defined above. */
    	btn.Clicked += new EventHandler (hello);
    
           
    	/* This packs the button into the window (a gtk container). */
    	window.Add (btn);
    
    	/* The final step is to display this newly created widget. */
    	window.ShowAll ();
        
    
    	/* All GTK applications must have a gtk_main(). Control ends here
    	* and waits for an event to occur (like a key press or
    	* mouse event). 
    	* In C#, we use Application.Run(), as used in Windows.Forms*/
    
       	Application.Run ();
        
       } // public static void Main
    
       } // public class helloworld
    
    In order to link this to the appropriate libraries, you invoke the compiler with the following flags. After that, simply invoke the program and you should be greeted with a simple app that presents a button. When you click on the button, the program will disappear. You can find the libraries by looking for the gtk-sharp.dll file. Then put that path into the -lib option and you should be ready to roll.
    mcs -out:gui.exe -r:System.Drawing -r:gtk-sharp -lib:"C:\Program Files\Mono-1.0.2\lib\mono\gtk-sharp gui.cs
    
    To get more information about how to use the GTK# library, visit the GTK website where they have some good tutorials on how to use the language.

    Conclusion

    So them's the basics. As you can see it is fairly easy to do .Net development on a shoestring budget. For my next article, I'll look into some good Integrated Development Environments for Mono.

    Thanks

    Many thanks to Brian Rose for the contribution of this article.

    Copyright

    Copyright © 2004 Brian Rose. All Rights Reserved.
    For reproduction rights, please contact brian@brianrose.net