Friday 30 December 2011

Goodbye 2011... Hello 2012

As the end of this year is rapidly approaching, I thought I would take the opportunity to assess a few things and work out what changes I plan to make for next year.

Changes I have come up with so far are:

Shave more often.

My wife hates me having a beard or stubble, and I don't blame her, so I will attempt to shave every day. Not saying I will manage it, but I plan to try.

Finish what I start.

I am fantastic at coming up with new projects and starting them off, but I am one of the worst at getting my own finished. I have about five or six half finished programs sitting on my hard drive, as well as some poetry I started, but got bored with and some stories. Hell, if I get good at this 'finishing stuff' thing, I might even get around to that novel I promised myself to write years ago (but don't hold your breath on that one).

Learn something new.

2012 is the year I get off my backside and learn something. Something totally unrelated to computers and programming. I may even take a course, if I can find the right one and I can afford it.

Quit smoking.

This time, I am going to do it. I spend far too much money, only to set fire to it and inhale. I'm also getting to that age where I really should be thinking about my health a bit more. Which brings me on to...

Lose weight.

Somehow, over the last few years, I have managed to pile on a few too many pounds. Well, enough is enough, it has to go.

I think that's enough to get started, I don't want to over-do it. I do plan to get some more tutorials written too, so hopefully you will find something a little more interesting that my plans for the future.

As I will also be tackling some of my programming projects, most I will be restarting from scratch, I hope to be able to keep everyone apprised of the progress of these too.

Anyhow, I will be seeing the new year in with my family, so, as I won't be writing anything else here again until next year...

 

Happy New Year

Wednesday 28 December 2011

What have developers got against Mac users?

Just a quick rant about the software industry. In particular, the Mac software industry.

I switched to  Mac back in 2006 and have never looked back. I like the system, the security, the ease of use and maintenance, the build quality, etc. I could probably go on for hours (but I won't).

However, there is one thing that being a Mac user has caused me concern.

Whenever a new version of the OS is released, it appears that developers are almost chomping at the bit to release their software for the new OS. I can understand this if they were taking advantage of the new features of the operating system, some 'whizz-bang' thing that has only just been introduced, but most of the time, they are not. Most of the time, it just appears that the developers are compiling for OSX 10.whatever just for the sake of it.

I find it somewhat frustrating when I find some piece of software that I would like, only to find that it is only available for the latest version of Apple's operating system. Yet, if you look at the Windows requirements, 9 out of 10 times, it will run on Windows XP, an operating system that is over 10 years old!

When I worked in the Windows software industry, one of the prime directives was to make sure you did not alienate those users with older operating systems, and therefore a sizeable chunk of your market. This philosophy does not seem to cross the OS border into Mac. Why not?

It was really brought home to me recently when I saw that Doom 3 had been reduced to a little over £6. I was amazed and overjoyed. I originally played the Demo of Doom 3 on my G5 Mac, running OS X 10.4, so the assumption that it would run ok on my Intel Mac, with 10.5.8, seemed logical. But then I checked the requirements. For some bizarre reason, Aspyr (I'm not picking on them, just using them as an example) have decided that they would recompile Doom 3 to an Intel only application, and in doing so, have increased the required operating system to OS X 10.6.

Now, I understand that this may be to get the game on the App Store, but is it really necessary to cut out a large slice of users? Maybe I should be looking at why Apple decided to make the App Store require 10.6?

Either way, I think it is definitely a problem with the Mac software industry somewhere. Not everyone wants to upgrade to the latest OS. My Windows machine is still running Windows XP, and I don't see me upgrading it for a few years yet. I'm not going to abandon my Mac, in fact I think I'll probably have to go the way most Mac users do and upgrade my OS, just to allow me to run certain software.

I for one, will not be compiling my software for the latest OS. I aim my software at the lowest possible requirement to allow as many people the benefit of using it as possible. I know of a number of others that also go this route, and I salute them.

So, come on developers, you're in the business of making money, so why alienate your customers?

Wednesday 21 December 2011

Comment About Comments

After posting my last tutorial, someone made a criticism, or rather an observation, about the coding style I have been using. I will be the first to admit, they are quite right in what they said, too.

I failed to use any comments in my code. I should have commented. No matter how small the piece of code you are writing, it is always advisable to put comments in your code. This can save you a lot of time in the future, especially if you haven't worked with that piece of code for some time. Even one line of code can cause a programmer to stop and think, if it's not too clear on it's function.

So, my apologies to all. From now on, I shall ensure that I place adequate comments in the code, as well as the explanations of the code function in the blogs.

Extending The Date Class

After the positive response I received about my last post (Flipping Pages), I have decided to carry on with some simple tutorials, in the hope that they will be useful to people.
This time, I will be looking at another question that has been posed in the Real Studio forums on more than one occasion. The question is how to determine the last day of any given month.
At it's simplest, I could just write a single method to accomplish this, and it would be perfectly valid. However, RealBasic is an object orientated language and I want to explore a true object orientated approach method for solving the problem.

As I already have a Date class which handles most of the time and date functions, it seems only right that I use this as my base. But, this time, I shall not be creating a subclass of the Date class, this time I shall be extending the class. Extending a class allows me to add methods to an existing class and then use them as if they are defined in the class definition. The advantage of this over a subclass, is that I can still continue to use the Date class with existing classes and methods, with no modifications.
Hopefully, this will become clearer as I progress.

To extend a class, I need only create a new method, in a module. However, the first parameter of that method must be of the class type that I am extending and use the keyword Extends.

First step then, is to create a new module in our project. In the screen shot, I have renamed this module to DateExtensions.

So, to create a method that adds to the Date class and returns the last day of the current month, I declare my new method in DateExtensions thus:


Function LastDayOfMonth(Extends d As Date) As Integer


Another useful thing would be a method that could tell me if the current year of the Date object is a leap year. I mention this now, because I will be using the method in the LastDayOfMonth method. So, the next step is to add another method that extends the Date class. This one will be called IsLeapYear and returns a boolean value.
The declaration of this method is:

Function IsLeapYear(Extends d As Date) As Boolean


Now it is time to add the actual code. I will start with the IsLeapYear method, as that will be used by LastDayOfMonth.

Before I do add the code, I ought to mention something about extending a class. When a method is added to an existing class, by using the Extends keyword, the program can refer to the instance of the class with the first parameter in the parameter list. Hopefully, this will demonstrate.

As you can see, this method only requires one line of code. What the method is returning may look a little daunting at first, but it is actually rather simple. All it does is calculate whether or not the year stored in the object (referred to by the variable d) is divisible by 400 or, the year is divisible by 4, but not divisible by 100.
Therefore, if the year stored in the object is a leap year, then IsLeapYear will return True, otherwise it will return False.

Now I can determine if the year is a leap year, I can now insert the code into LastDayOfMonth:

There are several different ways to determine the last day of the month. The one I have presented here is the one I normally use. I believe it is probably the fastest, although I may be wrong so, please don't flame me. It is also very easy to understand.

I use a simple Select Case condition on the month of the Date object.
If the month is 2 (February), then I know that I need to check if I am in a leap year, so I use the new IsLeapYear method to test this. If I am in a leap year, then return 29, otherwise, February only has 28 days.
The next Case statement tests if the month is one of the following: January, March, May, July, August, October or December. These months all have 31 days, so that is what is returned.
Finally, if neither of the above two Case statements are True, then the month must have 30 days.

That is it. The Date class has now been extended to include two new methods. The methods are used like any other method of the Date class. For Example, the following code creates a For...Next loop for everyday of the current month:

I hope you enjoyed this one, and maybe found it useful.

Monday 19 December 2011

Flipping Pages

I saw in the RealStudio forums that someone wanted to know how to get confirmation to change the page on a PagePanel BEFORE it changed. As there is no way to intercept the Change event before it fires, I thought I would have a crack at solving the issue.

The first step is to create a subclass of the PagePanel. Although we want to change some of the functionality, we still want the majority of the functionality to remain intact, so it makes sense to create a subclass. No need to re-invent the wheel.

Next, we need to add three new event definitions for the class.

CanChange
Change
Open

The Change and Open events are to reintroduce the existing events, because we will need to use them for this subclass.
The other event CanChange is the key to this modification. Ensure that the CanChange event returns a boolean value.

We also need two new private variables. These are an integer variable, called OldPageValue and a boolean variable called DoNotConfirm.

That's it for the setup. Easy right?
Well, now for the hard bit. Well, not really, this class only requires two routines, both of which are located in the event handlers.
First of all, we need to initialise everything. As normal, we do this in the Open event handler and is accomplished with just three lines of code:

The first line simply sets the value of OldPageID to the initial page displayed. Normally, this would be page zero. The next line sets DoNotConfirm to False. This means that we do not want to bypass the Change event.

Now for a slightly trickier piece of code, but still fairly simple:

We put this code in the original Change event of the PagePanel. I shall explain what is happening here line by line:


if not DoNotConfirm Then
If the DoNotConfirm variable is set to False then proceed with this. If the variable is set to True, then we need to ignore this entire routine.

if RaiseEvent CanChange then 
  OldPageID=Value
  RaiseEvent Change
Now, we call the new event handler. If the return value is True, then we want to change the page. As the page has actually already changed, we just store the new value of the PagePanel and then call the new Change event.

else
  DoNotConfirm=True
  Value=OldPageID
  DoNotConfirm=False
If the CanChange event returned False, then we need to return to the previous page. However, we do not want this Change event processing again, so we set the DoNotConfirm variable to True before setting the Value of the PagePanel back to the OldPageID. We also need to reset the DoNotConfirm variable back to False once the Value has been set.

That is it. We now have a new control that we can drag onto our window which will give us a PagePanel that can test to see if the change of page is permitted, either by some internal processing, or user confirmation.