I will teach you how to write a GUI app that will run on Linux and Windows with the same code using GTK. Since both OS's have a different executable format, you will have to Assemble and Link the code on each OS. No big deal here, we can use one makefile for this.

The only real prerequisite is to install GTK on windows, Linux should already have it installed if you are using a GNOME desktop (I think KDE uses it now), if not you will need to install it on Linux also.

Down here in our land, you do not need the GTK Developer package, you only need to download the GTK Runtimes. The GTK Developer package is a good thing to have though, since it includes all the headers and stuff.

Now, you could totally create the whole GUI through code with GTK, but lets not!! We will use GLADE to create the xml file GTK uses to create the GUI. Guess what, they have both a Linux an Windows version! What are you waiting for, install it for Windows! For Linux, you can install it from your Package Manager or compile the sources.

We will create a very simple program to view text files (anything really if it is UTF-8 encoded). To keep it simple, there is no error checking whatsoever.

First thing we need to do is initialize GTK with gtk_init. This will initialize everything GTK will need, and parse command line options which we don't use here.

push 0
push 0
call gtk_init
add esp, 4 * 2

We now need to create a new GtkBuilder object which is responsible for loading the glade file and all widgets.

call gtk_builder_new
mov [oBuilder], eax

Now we can have GTKBuilder load our glade file and create the GUI. Here I keep the glade file in the app directory. You will need to ship your glade file with your app. You could also load the glade file from a resource or a string in your data section.

Next we connect any signals we have set up in the glade file. These are not the same as Linux system signals. You can think of GTK signals as Windows Messages. Click a button, and the procedure you set up is called.

push dword [oBuilder]
call gtk_builder_connect_signals
add esp, 4 * 1

You need to export these procedures in order for glade to find and call them.

We are done the the Builder Object, so we unreference it

push dword [oBuilder]
call g_object_unref
add esp, 4 * 1

Our window just doesn't appear on the screen, so we need to tell GTK to show it

push dword [oMain]
call gtk_widget_show
add esp, 4 * 1

Just like in Windows, we need a message loop to listen for and process any happenings.

call gtk_main

GTK will exit its loop when it gets the destroy signal, at which time we can exit our app

call exit

If you wanted to, you could call ExitProcess here instead, but that would not work on Linux.

When the About button is clicked or Alt+A is used, GTK will call our About proc since that is what we set up in the glad file to be called for the clicked signal.

We "run" the dialog with gtk_dialog_run and wait for the user to finish. The function will return a code telling us what happened (just like a windows message box), if the OK button was not selected (the return was not GTK_RESPONSE_ACCEPT) then we just skip the file open code. You can set up your own return ID in the glade file.

So somebody either double clicked on a file in the file browser or selected a file and choose ok, now we need the path and file name, we do this with gtk_file_chooser_get_filename this function will return a pointer to a buffer GTK allocates with the path and file name. We then pass this pointer on to DisplayFileContents and free the pointer with g_free

We set up space on the stack for 2 DWORD variables with sub esp, 8. g_file_get_contents will allocate a buffer to hold the file contents and the filesize so we need to vars for this. Now that we have the contents of the file, we display it in the textview buffer with gtk_text_buffer_set_text
Once done with the file contents, we free it with g_free. This g_free looks different then the earlier on because get_contents gives us a pointer to a pointer.

Make will detect which OS it is on and run the appropriate commands.
You can lookup the meanings of the command line options to learn more about them. For the Windows app, I link it as a console app in case I wanted to print out strings or ints to the console with g_print The GUI program will still run fine.

We don't need lib files to link with when using GoLink. It will take a list of dlls and use them, this is what the imports.inc file is for.

As I said earlier, you need to export some things for gtk_builder_connect_signals
For Linux/GCC:
1. We mark them as global in the globals.inc and
2. We use the -export-dynamic command line option

global main, File_Open, About

For Windows/GoLink:
we mark them as exportable in exports.inc/export File_Open, About

The GTK runtimes consist of 25 files for a total of 13MB. These need to be in your app directory. Actually, you only need to ship the dlls that your app needs. This is trial and error of removing them. I am sure you can put them in your /system32 directory, haven't tried.