I knew I had not done anything on the File Manager for some time but that the last post was almost a year ago even surprised me. That is probably also the last time I did any programming on it. I even had to read back to see what I was up to at that moment. I decided to continue on Aros using Zune which is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. I am going to switch back to OS4.1 using ReAction. At the time I was still programming using ReAction the wrong way. Since I am doing it the correct way with my Redhouse Editor project I decided to ditch all the current code and use the Redhouse Editor code for which I program ReAction the correct way. So what I have at the moment is a window that is being opened and already has a small menu system in place.
The above Window is what I have at the moment. Simple but proper ReAction code so a good start if you ask me. What I plant to do next is to play around a bit with the layout. Getting myself a bit familiar with the Layout Class to make it look like a bit more like a File Manager. When you talk about a File Manager look you instantly think about the two column look like you can see below from Directory Opus.
For this I will have to use the List Browser Class. I remember how difficult it was last time I tried to have a go at it. I better be prepared this time and get the job done.
Since Aros uses Zune which is a MUI clone I had to get myself familiar with MUI. I know a bit about ReAction which is being used by OS4.x which does come in handy when using MUI. Since I knew nothing about MUI I probably will use up most of the coming time on getting myself familiar with it.
As you might know I prefer opening my own libraries instead of having it done by the compiler. I know it is extra work but it will teach you more about libraries. You can use libraries without even having to open and close them or even worry about the error handling (check if you manage to open them or not and what to do). I learned a lot from doing it myself and that kind of knowledge can be useful for other coding parts as well. When it comes to MUI we have to open the MUI library. Below are the code fragments we need to get this done. First the includes, setting up the pointer and finally opening the library.
struct MUIMasterBase *MUIMasterBase;
MUIMasterBase = (struct MUIMasterBase *)OpenLibrary(“muimaster.library”, 39);
But when I compile it I get the error “Conflicting types for MUI MasterBase”. I am not sure but to me it seems to be the <proto/muimaster.h> include that is the culprit. I posted about this on the Aros-Exec forums in the hope of getting this resolved soon. I am taking a short break from it so maybe the solution might come to me.
I left my Redhouse file manager project on hold for some time already. Started out on OS4.x I thought it was a good time to continue with it on Aros for now. I am getting myself familiar with Aros so what better way better than to involve Aros in to it. One thing I really miss, and “highlighted” already several times is a editor that supports C syntax highlights. Being used to CodeBench and Cubic IDE it is a big must for me. I really hope someone will create this. For now I am using the NoWinED editor. When the code is not that large yet it is fine but once it grows you just loose that great ability of oversight.
Programming on Aros is somewhat different compared to OS4.x. The approach to libraries and the GUI toolkit of choice are different. When it comes to libraries we will switch back to the old classic way of opening them. I actually like this since it is true to the classic way of doing things and since I invested a lot of time in Amiga OS libraries the classic way and new OS4.x way it is not really a problem to switch back to this way of opening libraries.
Instead of ReAction which is used on OS4.x we are using Zune on Aros. Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. I have no experience with MUI so for me this will be a bit of a hurdle. I always got the idea that there are more and better MUI classes one can use giving you a more easier way of getting your code done. So far I already have small example of a window that is being displayed with some control code that will close it again. That will be the basis from which I will continue. First I will start with a split window look which is the basis for each Amiga file manager if you ask me.
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.
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.
For about a week now I am stuck with finding a certain bug in my code. Every time I run it OS4 crashes. What I have done far:
– Opening all the libraries and classes
– Setting up my window parameters
– Opening the window
If I run the code it displays the window but instantly brings up the Grim Reaper saying it crashed. Being the smart ass as I am I believe my code is clean as a whistle. 🙂 The problem is how to you find this bug? My first thought was that it goes wrong at the “looping” part. This is the part that keeps the window displayed until someone closes it. But after checking and comparing my code I really code not spot a wrong line of code. To narrow it down I started printing text on the screen after each line of code so I know what part works. The benefit of this is that I soon discovered that it does not even get to the looping part.
A good practice sometimes is that if you really can’t find the problem to take some example code that does work and strip it of all it’s extra’s till it does only what you failed to achieve with your approach. Once you have that you just continue from there. Since I am running the Pre-release version of OS4 I also have to consider that sometimes the code is just fine but it is the Pre-release version that is causing it. Time to squash that bug.
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;
WindowBase = IIntuition->OpenClass(“window.class”, 50, &WindowClass);
if (WindowBase != NULL)
printf (“We opened the Window Class Library!!\n”);
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.