Diary of an Amiga fanatic

Tag Archives: OS4Coding.net

Finally I managed to fix the crashing issue when another issue surfaced.

After solving this one I ran into another one that seems to be even worse. My window displays but when I click to close it nothing happens.

After spending a lot of time on it and not getting really any further I decided to move back to my previous “older” code. I was following Trixie’s article over at OS4Coding.net regarding the proper way of programming with ReAction. One of part of the proper way of using ReAction was:

Instead of using OpenLibrary() to open ReAction Classes we should use OpenClass() to open the ReAction Classes. Besides returning the class library base (which we store in WindowBase) it will also return something called the class pointer.

Instead of using the OpenClass() function I am now (again) using OpenLibrary() and GetInterface() to open ReAction Classes. You might remember that in a previous article I was talking about how can you check if the class pointer is also being opened when you use the OpenClass() function.

My question about this is that when we check if we opened the Window class do we also need to check if we got the pointer and if so how? Or can we assume that if we succeed in opening the Window class we also have successfully got the class pointer?

Maybe it did not really open (class pointer) which is the reason my code for closing the window is not working. Besides this part there is another part for which I switched back to my “older” code. Don’t use RA_OpenWindow()  to open a window but instead use  WM_OPEN which would look something like this:

window = (struct Window *)IIntuition->IDoMethod(objects[OID_WINDOW], WM_OPEN, NULL);

I moved back to using RA_OpenWindow() which would look something like this:

window = RA_OpenWindow (winobj);

Just ignore all the parts of the code it is just for reference. The third and last part I moved away from is WM_HANDLEINPUT. This is part of the code that will loop (keeping our window open till we do something like clicking something) and would look like something like this:

while ( (result = IIntuition->IDoMethod(winObj, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG )
{

}

I moved back to using the RA_HandleInput() macro which would look something like this:

while ( (result = RA_HandleInput(winObj, &code)))
{

}

As a result my code works now and clicking on the close button actually closes my window. I could not keep spending time on this issue so I had to move back in order for my code to work and move on. At a later stage I might do some further testing so that eventually I can move back. If you go through the ReAction examples for OS4 you do get rather confused since every example seems to differ from the other. But since I now got it to work I am moving on to the next part which is the layout. At first I want to start with having buttons on top of the window. See example screenshot below which is from the utility Filer from Bjorn Hagstrom.

Filer 53.27 from Bjorn Hagstrom

I will discuss the layout and buttons in the next article. Till next time!


I did manage to locate the bug that made my code crash. If you remember my previous posting you know how much that bug haunted me. The declaration “Object *winObj” was the one that caused it. By changing it to  “Object *winObj = NULL” I solved it. If you follow The Bucket Programming Corner you might remember me talking about setting pointers to NULL. I see a lot of ReAction examples which do not set this to NULL. Since it solved it for me and I can’t find any other info on this I will just leave the statement as it is.

Home free right? Not exactly. After solving this one I ran into another one that seems to be even worse. My window displays but when I click to close it nothing happens. After running some tests it seems the code never reaches the part that checks if the window needs to be closed. After staring at it till my eyes hurt and compare it to several examples I still have not found the bug and I decided I need some outside help. So I posted my problem over at OS4Coding for some outside help. Let’s hope I find it soon so I can continue.


I already ran into my first problem. Well not so much a problem but more of a query. It has to do with checking if something was successfully opened. We do it when we open a library and also the interface of it. You might still remember it from The Bucket Programming Corner but for reference I will place the source code below.

(Note: the code is not complete since we use a if statement to make a check but we need to use the else statement to complement it. Of course in the example code of the article it is complete.)

struct Library *IntuitionBase = NULL;

struct IntuitionIFace *IIntuition = NULL;

/* Opening the Intuition Library */
IntuitionBase = IExec->OpenLibrary(“intuition.library”, 50L);

/* Did we manage to open the Intuition Library? */
if (IntuitionBase != NULL)
{

printf (“We opened the Intuition Library!!\n”);

/* Open the Intuition Interface */
IIntuition = (struct IntuitionIFace *) IExec->GetInterface (IntuitionBase, “main”, 1, NULL);

/* Did we get the Intuition Interface? */
if (IIntuition != NULL)
{

printf (“We did get the Intuition Interface!!\n”);

The most important thing you need to do is to make sure you set both *IntuitionBase and *IIntuition to zero (NULL). If we set it to NULL and we open the library and get the interface the value of both *IntuitionBase and *IIntuition should be NOT (hence the !=NULL) zero. If they are it would mean that we failed to open the library or did not get the interface. If we do not set both *IntuitionBase and IIntuition to NULL we cannot do a proper check. Even worse we could and almost surely would crash the system.

All of the above bring me to the issue I ran into. If you read Trixie’s article over at OS4Coding.net you know that instead of using OpenLibrary() to open ReAction Classes we should use OpenClass() to open the ReAction Classes. Besides returning the class library base (which we store in WindowBase) it will also return something called the class pointer. Have a look at the below code.

struct ClassLibrary *WindowBase = NULL;

Class *WindowClass;

WindowBase = IIntuition->OpenClass(“window.class”, 50, &WindowClass);

if (WindowBase != NULL)
{

printf (“We opened the Window Class Library!!\n”);

}
else

printf (“We failed opening the Window Class Library!!\n”);

As you can see we open the Window class and with it the class pointer. My question about this is that when we check if we opened the Window class do we also need to check if we got the pointer and if so how? Or can we assume that if we succeed in opening the Window class we also have successfully got the class pointer? I assume the last is the case. If we successfully opened the Window class we will also have successfully got the class pointer. Let’s say the system is not capable of storing the class pointer in &WindowClass for whatever reason it will mark it as failing to open the Window class and the WindowBase value would be NULL. I am not 100% sure about this but for now I will assume this is the case. I am still trying to figure this out by speaking to some OS4 programmers and once I got the final answer I will let you all know.


The idea for this article came from a posting from Hans de Ruiter over at OS4Coding.net in which he wanted to know how you could identify your machine. He talked about the function GetMachineInfo() from the expansion library that could do this. With that info I set out to create some code that would do exactly that; identifying our machine. Unfortunately the GetMachineInfo() function is not that detailed when it comes to identifying your machine. It can identify the below machines:

MACHINETYPE_UNKNOWN – Unknown hardware
MACHINETYPE_BLIZZARDPPC – BlizzardPPC in an A1200
MACHINETYPE_CYBERSTORMPPC – CyberStorm PPC in an A3000/A4000
MACHINETYPE_AMIGAONE – any AmigaOne model (including XE, SE, MicroA1 or XC).

The problem lies in the AmigaOne identifier since it will only report back “AmigaOne” and not if it is a XE, SE, MicroA1 or XC. I will do some more digging into this to see if there is  way to determine what exact model of AmigaOne it is. For now this example will demonstrate some new programming code and get you to extend your knowledge. Let’s have a look at the code.  

01 #include <stdio.h>
02 #include <expansion/expansion.h>
03
04 #include <proto/exec.h>
05 #include <proto/expansion.h>
06
07 struct Library *ExpansionBase = NULL;
08
09 struct ExpansionIFace *IExpansion = NULL;
10
11 int main (void)
12
13 {
14
15  /* Opening the Expansion Library */
16  ExpansionBase = IExec->OpenLibrary(“expansion.library“, 50L);
17
18   /* Did we manage to open the Expansion Library? */
19   if (ExpansionBase != NULL)
20  {
21
22     printf (“We opened the Expansion Library!!\n”);
23
24     /* Open the Expansion Interface */
25     IExpansion = (struct ExpansionIFace *) IExec->GetInterface (ExpansionBase, “main“, 1, NULL);
26
27      /* Did we get the Expansion Interface? */
28      if (IExpansion != NULL)
29     {
30
31       printf (“We did get the Expansion Interface!!\n”);
32
33        STRPTR machine;
34
35        IExpansion->GetMachineInfoTags(GMIT_MachineString, &machine, TAG_END);
36
37        printf(“Blimey! Your model = ‘%s’\n”, machine);
38
39        /* If the Expansion Library Interface is open, close it */
40        IExec->DropInterface((struct Interface *)IExpansion);
41         }
42
43     /* We could not open the Expension Library Interface */
44     else
45     {
46
47    printf (“Unable to open the Expansion Library Interface!\n”);
48    }
49
50   /* If the Expansion Library is open, close it */
51   IExec->CloseLibrary(ExpansionBase);
52   }
53
54   /* We could not open the Expansion Library */
55   else
56  {
57
58   printf (“Unable to open the Expansion Library!\n”);
59  }
60
61 return 0;
62 }

If we compile our program and run it from the shell we will get the below output.

Running the ID machine program

As you can see I still add the code of printing if you managed to open a library or get the interface. You can leave that out if you wish.

The only strange piece of code on the block is:

02       #include <expansion/expansion.h>

05       #include <proto/expansion.h>

33        STRPTR machine;
34
35        IExpansion->GetMachineInfoTags(GMIT_MachineString, &machine, TAG_END);
36
37        printf(“Blimey! Your model = ‘%s’\n”, machine);

Line 02 and 05 will add some includes so that we can use the Expansion base library functions in our program. Line 33 till 37 is the code that will actually perform our little magic trick.

The AutoDocs from the SDK describe GMIT_MachineString as:

GMIT_MachineString (STRPTR *) — Machine model as a human-readable string.

GMIT_MachineString is part of the GetMachineInfoTags function. We use IExpansion-> to call upon GetMachineInfoTags. The value returned by GMIT_MachineString is stored in “machine”. We have set-up “machine” on line 33 which sets up “machine” as a string pointer. In line 35 the & sign will store the value as a string pointer. And at line 37 we are printing the value of “machine” which is in this case AmigaOne.

This example also shows one of the difficult parts of programming on the Amiga OS; trying to understand the AutoDocs which describes all the functions. At least for me this is the case. It does describe all the functions but not really how to use them. Well in some cases they do provide some examples but mostly it just mentions all the functions which make almost no sense. It certainly would scare some new programmers away since they might become frustrated in not understanding it. I will try to address the AutoDocs in some future articles to make it easier to understand and at some point make it possible to actually read and understand them yourself. Till next time and happy coding!


It was time to use my A1SE and OS4.0 on a more regular basis so that is exactly what I did. Trying out some utilities and demos I had a really great time. With the weather getting colder nothing beats using your Amiga’s. Currently I am trying some stuff out that might be used for my next article for the The Bucket Programming Corner section.

Suddenly I get a “Please insert volume CONSOLE: in any drive” error at random times. Not really sure what is causing this. At first I thought it could be AmiSystemRestore since I installed this recently but even when this is not running it still shows this error. The problem is that once this comes up the system will freeze up and I will have to restart the machine. I will do some more investigation in to this.

Console error

Earlier this week I tried out the new NetSurf 2.8 version. I like the download window so that I can see the download status of a file. I normally fire up OWB when browsing but since I installed NetSurf 2.8 I fire this puppy up when browsing the net. I am really starting to like it more each day I use it. Probably I only touched the surface of it and there is a lot more to discover.

NetSurf 2.8 download window

For the last couple of weeks I am thinking about what my next project should me. I need something that would not take ages (I have very limited time so even the most simple projects would take ages) but can be done in a fair amount of time. I keep coming back to my already attempted file manager project. I kind of had it binned due to the ReAction issues I came across. After reading Trixie’s articles about ReAction over at OS4Coding.net I am going to give it another try. Since his articles show how it is suppose to be done, and showing what I did was wrong, I feel a new burst of energy to give it another try. Here’s to happy coding!