Main

November 11, 2007

Set Windows XP style on logon

A while ago I displayed a little script that automatically changed the Windows display appearance from 'Windows Classic style' to 'Windows XP style'. It sometimes had problems switching to the correct window to accept key strokes, so I've made some slight adjustments.

//=================================================================== // FILE: XpStyle.js
// DESCRIPTION: automatically set to use Windows XP style
//===================================================================

// create shell object
objShell = new ActiveXObject("WScript.Shell");

// wait for other startup programs to load
WScript.Sleep(1200);

// start appearance applet and activate this window
objShell.Run('rundll32.exe Shell32.dll,Control_RunDLL desk.cpl desk,@Appearance');

// wait for appearance window
WScript.Sleep(200);

//switch to correct window
success = false;

do {
success = objShell.AppActivate("Display Properties");
} while (success == false)

WScript.Sleep(100);

// send the keystrokes to set the style
objShell.Sendkeys("{Down}");
objShell.Sendkeys("{TAB}");
objShell.Sendkeys("{Down}");
objShell.Sendkeys("{ENTER}");

September 17, 2007

Dynamic publishing in MovableType at NearlyFreeSpeech.NET

My web host, NearlyFreeSpeech.NET, has a rather unusual setup. The web root as seen by a Perl CGI script is very different from that seen by PHP. This leads to a problem in a MovableType-powered blog, which has its administrative web site written in Perl, and its customer-facing site written in PHP (when published dynamically - as a static site it's all HTML). However, it's nothing that a few edits to the source won't fix.

Note that in the code excerpts below I've included the preceding lines to indicate where the code should be placed, in case the line numbers are out. Also, the alterations are based on MovableType v4.01, but other releases of MT4 should be very similar.

  1. File cgi/lib/MT/App/CMS.pm. Here we alter the folder names written into mtview.php, the main dynamic viewing page -

    Line 16687:
    $cgi_path =~ s!/*$!!;
    #Fix Perl -> PHP folder
    $cgi_path =~ s|/home/|/nfsn/content/mySite/|;


    Line 16690:
    my $config = MT->instance->{cfg_file};
    #Fix Perl -> PHP folder
    $config =~ s|/home/|/nfsn/content/mySite/|;


    Note that if you edit these folder names directly in blog/mtview.php then your changes will be overwritten when your site is republished or if you change your publishing settings.

  2. File cgi/php/mt.php. Now another easy part. In here we just need to insert a line in a couple of places to change the folder retrieved from the config file from Perl to PHP form.

    Line 215: (This change might only be needed for SQLite databases) $cfg['dbdriver'] = strtolower($driver);

    //Fix Perl -> PHP folder for database
    $cfg['database'] = str_replace("/home/","/nfsn/content/mySite/",$cfg['database']);

    Line 338:
    function configure_paths($blog_site_path) {
    //Fix Perl -> PHP folder for templating
    $blog_site_path = str_replace("/home/","/nfsn/content/mySite/",$blog_site_path);


You might noticed a pattern from my last few blog entries. If you put them together you might get the impression that I've been trying to run a dynamically-published MovableType blog in SQLite3 at NearlyFreeSpeech.NET. Whilst this is true, I found that the end result was unbearably slow, so I've had to remain in the statically-published world.

Update 19 Sep 2007: I have found that enabling the dynamic publishing option Enable Conditional Retrieval speeds up the page display tremendously. The only documentation I've seen on that feature is too sparse for me to understand what it does or why it works so well. In contrast, Enable Dynamic Cache is self-explanatory, but I don't see why it makes no improvement to my site's speed at all. Still, this is good news, and makes dynamic publishing a viable option for me.

September 16, 2007

Dynamic publishing with SQLite 3 in MovableType

MovableType 4 has just been released, but it still hasn't been updated to let you publish dynamically with an SQLite 3 database (SQLite 2 is supported). This is an interesting omission, because dynamic publishing is the best option for low-volume sites, and SQLite 3 is an excellent choice for low volume sites.

PHP 5.1 with SQLite 3 support has been out since 2005, so the developer community, including me, has had plenty of time to get used to the change. Which brings me to the solution.

  1. Reactivate the administration option to publish dynamically

    In file /lib/MT/App/CMS.pm, comment out lines 13277-13280, like so (a '#' at the start of the line tells Perl to ignore the rest of that line):
    #if ( $app->config->ObjectDriver =~ qr/(db[id]::)?sqlite/i ) {
    # $param{hide_build_option} = 1
    # unless $app->config->UseSQLite2;
    #}

  2. Change the PHP calls from the old SQLite functions to the new PHP Data Objects (PDO) functions

    • File /php/lib/mtdb_sqlite.php

      Line 158:
      //$this->result = @sqlite_query($query,$this->dbh);
      $this->result = @$this->dbh->query($query);

      Line 188:
      //if ( $row = sqlite_fetch_array($this->result, SQLITE_ASSOC) )

      if ($row = $this->result->fetch(PDO::FETCH_ASSOC) )

    • File /php/extlib/ezsql/ezsql_sqlite.php

      Line 50:
      //$this->dbh = @sqlite_open($dbpath.$dbname);
      //if ( ! $this->dbh )
      //{
      // $this->print_error("Error","<ol><b>Error establishing a database!</b><li>Are you sure you have the correct path?<li>Are you sure that you have typed the correct database instance name?<li>Are you sure that the database is installed?</ol>");
      //}

      try {
      $this->dbh = new PDO("sqlite:$dbpath$dbname");
      } catch (PDOException $e) {
      $this->print_error($e->getMessage());
      }

      Line 168:

      //$handle = @sqlite_query($query,$this->dbh);
      $handle = $this->dbh->query($query);


      Line 239:

      //while ($row = sqlite_fetch_array($handle, SQLITE_ASSOC)) {
      while ($row = $handle->fetch(PDO::FETCH_ASSOC) ) {


Although there are many further SQLite 2 specific lines of code in MovableType, the above changes were all that were required to get my dynamic blog to work with my SQLite 3 database.

February 10, 2007

Australian Weather Chart now live

Charting your way to successI have put my Weather Chart page live, amongst the assorted other online knick-knacks in the fun section of this site. It displays the last 72 hours of temperature and rainfall data for the weather station of your choice in Australia.

The data is made freely available by the Australian Bureau of Meteorology, but as their XML feeds are not expected until after the middle of 2007 I had to screen-scrape HTML for the particular aspects I required. I cache this data for 15 minutes, so the charts won't refresh faster than that.

Currently only the capital city weather is easily selectable. For other locations you have to wander through the BOM site and find the URL for the station you want. For example, to find all the stations in Western Australia, you could go via:

  • WA in the top-right navigation bar, then
  • Western Australian Weather and Warnings
  • Western Australian Observations
  • Latest Weather Observations for Western Australia
From here you can click the station of your choice, and that URL is what you should enter into Weather Chart.

Weather Chart was designed with manual entry of URLs because I'm not sure how permanent the URLs are, and because there is no good long list of them for the program to grab. When the XML feeds come into effect I'll look at making this more user-friendly.

Update 16 Feb: Moved programming description to earlier post.

February 9, 2007

Set Windows theme on logon

In Windows it is possible to set the theme from the command line, instead of using the Themes tab of the Display Properties control panel applet. This makes it amenable to scripting, which can be useful when your theme settings are not saved after you log out, for whatever reason.

If a shortcut to the following WSH script was placed in your startup folder, then the given theme would automatically be loaded when Windows started. Note that you must have previously saved your desired theme, and that you must edit the script to point to this saved theme.

//===================================================================
// FILE: theme.js
// DESCRIPTION: automatically set the Windows theme
//===================================================================

// create shell object
objShell = new ActiveXObject("WScript.Shell");

// start themes applet, load desired theme, and activate this window
objShell.Run('rundll32.exe Shell32.dll,Control_RunDLL desk.cpl desk,@Themes /Action:OpenTheme /File:"C:\\temp\\Happy.theme"',1);

// wait for themes window
WScript.Sleep(1600);

// send the 'enter' key to accept this theme
objShell.Sendkeys("{ENTER}");

As themes encompass Window appearance, this method will also set 'Windows and buttons' in the Appearance tab to 'Windows XP style' or 'Windows Classic style'. There may be an easier method to do just this change without loading a whole theme, but I could not find any official documentation for the Shell32.dll options.

Update 12 Feb 2007: The obvious way of just changing the 'Windows and buttons' from Windows Classic to Windows XP style is by emulating keypresses. XpStyle.js does that, and also changes from Default (blue) to Olive Green. If this is the only outcome you are after, then this method is preferable to changing the theme because that requires the use of a saved theme, and because themes store much more than just the Windows and buttons style.

February 4, 2007

PHP Graphing

In the past I've used the GD library in PHP to manually create graphs. For example, the bar charts that regularly appear in this blog are formed on the fly by a specially created program. However, it's often quicker and easier to use graphing libraries that other people have made available, especially if your graphing requirements are relatively standard.

The most full-featured for graphing library for PHP appears to be JpGraph, which is free for non-commercial use. Oddly, its excellent html-formatted manual is not provided officially online, but only as part of the JpGraph download. This would probably put off a number of people who like to see proper documentation before they go to the trouble of downloading and installing a package. If you do a Google search for "jpgraph manual 2005" you may find a copy hosted elsewhere.

Another potential disincentive to using JpGraph is its size. It's a 5MB download, which uncompresses to 9MB. However, much of that won't be necessary to install onto your live site, as it includes documentation, images and library code. To work out what you do need, just upload your script that references JpGraph, but don't upload JpGraph itself. Then, when you run it, an error message stating the files which are missing will be displayed. Just install those files, and try again. For my project, that whittled it down to a very reasonable amount of just over 300 kB.

As for JpGraph itself, it is an excellent product. It's easy to use, highly configurable, and has the best documentation that I've seen in a long time.

Update 16 Feb: I have used JpGraph to produce my new Australian Weather Chart tool. Although I could have built the charts from scratch, to create something as complex as the Weather Chart, I'd be tweaking it for weeks, and even then I'd just have to start from scratch again for the next one. Another point to note is the extreme customisability of JpGraph. It let me overlay the rainfall bar chart on top of the temperature line chart with no fuss, and happily provided two y-axes for these measurements. In addition, the plethora of formatting options ensured that any ugliness in the graph was entirely my fault. Finally, the extremely simple method of using caching ensured that no programmer would have an excuse not to use it.

October 11, 2006

Turbo Delphi Explorer

Every year it was the same old story. Borland would make some minor improvements to Delphi, increase the version number, announce a free "Personal" version, then make it virtually impossible to actually obtain. They'd stick it on a few magazine cover disks, and hope that nobody found it. Unfortunately, nobody did.

My guess is that Microsoft's successful launch of its competing free Visual Studio Express family finally nudged Borland out of their apathy. A few weeks ago they made Turbo Delphi Explorer (and Delphi for .Net, C++ and C#) available for download. Thus the major stumbling block in actually getting Delphi has been removed.

A second crucial point is that the free editions finally include various essential components built in. Previously, if you wanted to do even the simplest internet-related task you needed to install a separate component. Turbo Delphi comes with the brilliant Indy Sockets, as well as numerous other components, already installed. This means that the keen hobbyist can get immediately to work, instead of jumping across to a platform that is easier to start actual coding in.

For even more inspiration, the inimitable Huw Collingbourne has a great new tutorial series on Turbo Delphi.

September 14, 2006

Delphi 2005 vs. Visual C# Express 2005

A few weeks ago I decided to try out the Flickr API by developing a wallpaper application that would automatically retrieve images from Flickr. As well as experiencing the Flickr API, I would also experiment by developing the same basic software simultanously in two languages and IDEs, namely Microsoft Visual C# Express 2005 and Delphi 2005 Personal.

I usually don't reinvent the wheel, and in this case components have been developed which ease the programming interaction with Flickr. These are FlickrNet for .Net (ie. C#) and dFlickr for Delphi. It was at this point that my Delphi project stalled, as I had great difficulty installing dFlickr. As I tinkered aimlessly trying to get Delphi to talk to Flickr, I steamed ahead on the C# project. The combination of straightforward installation of FlickrNet, sufficient documentation, and very helpful code completion enabled me to communicate with Flickr in negligible time, and get the guts of the program done without trouble.

There are other Flickr wallpaper applications written in C#, but I wanted to provide a better user experience. Flickrwallpaper is a nice command-line example, which is useful to programmers because it includes all the source code, but would put off most casual users by its difficulty of use due to its lack of graphical user interface.

After about a week, my C# wallpaper application was just about done, and I moved back to trying to get dFlickr to work. Doing this, and learning how to use it, took an additional two days. Then I did a quick straight conversion of the C# code to Delphi, which took three more days.

I did a previous comparison of Delphi 6 versus Visual C# Express 2005 (Beta 1), and much of that is still valid with these products. Whilst Delphi hasn't progressed much, the problems with the C# Express beta have been eliminated.

Visual C# Express is good because:

  • The visual designer provides great positioning aids. You can use the mouse to align items with ease, whereas with Delphi I have to resort to doing pixel positioning calculations in my head.
  • It is very productive. I was never stuck wondering how to do something. This is due to a combination of great help, great code completion, and plenty of online tutorials and forums about C# and .Net.

Visual C# Express is bad because:

  • It has no inputbox function. I had to write an entire form and associated code to do what I expected to be provided in a single line of code.
  • The programmer and end user need to have the .Net framework installed.
  • Any extra components need to have their .dll files distributed too, so you can't just provide a single file download without zipping everything up.
  • Help (not Intellisense, though) is very slow to load, slower than loading the whole rest of the IDE.

Delphi 2005 is good because:

  • The end result is an all-in-one executable, making life easy for your users.

Delphi 2005 is bad because:

  • Errors, such as accessing an object before it's created, often cause an 'Access violation' message, but do not provide much help debugging.
  • Code completion doesn't work if there are many errors in the document.
  • Code completion isn't very descriptive, and you can't click elements within it, such as on type names to get more information
  • Help is hard to navigate
  • Not much is built in (eg. no XML processing, no internet access), so you must rely on components written by third parties
  • The IDE is much clunkier (and even worse than Delphi 6)
  • Because this is Pascal, you have to declare everything (functions and variables) in advance.
  • It can be hard to install components.
  • Again a Pascal note, begin and end are more verbose than curly brackets.

In the neither bad nor good category, it was interesting that with Visual C# the IDE is fast to start, but slow to load the actual project. In comparison, the Delphi is IDE slow to start, but the project fast to load. I prefer the former, which seems faster though probably isn't much different.

Delphi 2005 can actually produce two types of code. The first is based on Win32, which is what all former Delphi versions could create. Second is the new-fangled .Net Framework, or what Visual C# Express is using. I have been testing the former only, as the other seems to offer the worst of both worlds, the poor IDE of Delphi combined with the poor distributability of .Net.

In summary, the programming experience in Visual C# Express is vastly superior to that of Delphi. However, for most end users, the code that Delphi produces is much better. Firstly, it does not require a large software package, the .Net Framework, to be installed. Secondly, all the components are combined into one executable file, rather than being separate dll files. Certainly these problems can be mitigated by the use of nifty installers, but they're not ever going to be as clean.

The end result of all this work is the Delphi production of Fleace. I'll probably still use the C# code to try out experiments, but my users deserve the easy-to-install Delphi version.

PS. Just a note that if you have both these IDEs installed, you may have problems with the Delphi help refusing to appear. The fixes for this are on the Borland and gnegg sites.

September 7, 2006

Installing dFlickr

Update 5-Oct-2006: This article is for Delphi 2005 Personal. The new free Turbo Delphi Express comes with Indy already installed, so you can skip the Installing Indy section below.



I recently worked on a couple of projects involving the great Flickr API. My first project was postponed and became my second due to delays in getting the Delphi Flickr component dFlickr installed and working. This was due to a combination of my inexperience, outdated documentation, and bad luck.

Flickr is a picture sharing site. Their API lets programmers upload and download images within their programs. In simple terms, the program sends a request in a URL's querystring, and Flickr returns the results in XML. I am using Delphi 2005 Personal, which doesn't include any facilities for accessing the internet or processing XML, so I am reliant on external components for this. dFlickr fits the bill perfectly.

Installing Indy

To prepare Delphi for Indy, you need to install a special file. Without this, Indy will not compile.

Now to Indy itself. The first step is to install Indy(.Sockets) 10. I used the latest development snapshot. The instructions on the Indy web site for installation through the Delphi IDE didn't work for me. Luckily, they also provide some batch files that do work. Before that, though, you need to compile Lib/Computil.dpr. You can do this in the IDE, just open it and choose Project | Compile. This will create the Computil.exe file. Note that if you close the IDE without saving then the Computil.exe mysteriously disappears, so save it.

Now you can run the correct batch file. Those in the know will be aware that Delphi 2005 is really just Delphi 9, so you need to run Lib/Fulld9.bat. That should complete with a few unimportant warnings.

Finally, go into the IDE and go to Component | Install Packages. Here you should add Lib/Core/dclIndyCore and then Lib/Protocols/dclIndyProtocols. They should then appear as new items in your Tool Palette. Oh, and absolutely finally, you need to set the paths as mentioned in the otherwise outdated Indy documentation.

Installing and using dFlickr

That's the hard stuff out of the way. Nothing else needs to be installed, just referenced when needed. That is, just use 'Add to project' to use dFlickr.pas. If necessary, it'll ask to be pointed to the other components included in the dFlickr download, which you can similary 'Add to project'.

An important note is that the version of Indy currently available seems out of sync with dFlickr, resulting in all dFlickr calls failing with an Assert error. The latest dFlickr, 0.9.3b uses POST, whereas previous versions used GET. Indy objects to the way that dFlickr does its POST, so you must either use an old dFlickr, or change the line about 1055 back from POST to GET (just uncomment the GET line and add a comment to the POST line). The author of dFlickr has been very responsive to my queries, so watch for a better solution in 0.9.4.

Finally, the sample code on the dFlickr page is outdated, and no longer works. Here's my sample. If shows the number of photos which are tagged as 'puppy' or 'beach', and gives the URL of the small thumbnail image of the first of those photos.


var
  Flickr: TFlickr; 
  PhotoList: TFlickrPhotoList;
begin
  Flickr := TFlickr.Create('YOUR_FLICKR_API_KEY','');
  try
    PhotoList := Flickr.PhotosSearch('','beach,microsoft');
    ShowMessage(inttostr(PhotoList.Total) + ' photos found');
    ShowMessage(PhotoList.GetPhoto(0).Sizes.GetSize(0).Source);
      except
    on E: Exception do ShowMessage('Error: ' + E.Message);
  end;
end;

June 21, 2006

Fractal zoom canvas demo

So far my Firefox canvas demos have only used a small subset of the available canvas commands. To learn about some of the other features I have added the zoom capability to my previous fractal offerings.

View the fractal zoom at your leisure.

The zooming was accomplished by displaying sliced images from an offscreen (hidden by CSS) buffer. This is an extension of the concise description from the Mozilla canvas tutorial. I have also tidied up the previous fractal code somewhat, removing hard-coded constants. It still needs a general reorganisation to remove global variables, but that shall wait for another time.

Because Javascript is not the fastest of languages you may see some delay in the drawing of the fractal. After an extended delay Firefox may pop up a message box asking if you wish to continue. If you say 'yes' then the fractal should get drawn eventually. It is this speed issue that has caused me to draw the fractal in lower than maximal resolution. If you want to zoom in to a high-resolution fractal then have a look at a desktop fractal zoomer such as my old Windows software JM's Mandelbrot Explorer.

June 16, 2006

Flame canvas demo

Following on from my successful canvas demos of fractals I thought I'd attempt the old staple of the demo scene, the flame effect.

Luckily it's very common and very simple. There are dozens of examples in Programmers Heaven - Graphics & Sound - Fire & Flame, coded in Java, C, C++, ASM, Pascal and even QBasic. All of those are old hat, as the cool stuff is now being done online, using the canvas tag supported by all modern web browsers. Coding and deployment is much simpler, though the results are usually a tad slower.

That's enough waffling. Here's the fire. Just view the source to see the code.

This time I did the animation using setInterval() rather than setTimeout(), as it's slightly less code. I expected from their definitions that they'd be virtually identical, but setInterval() seemed to run faster but be more CPU intensive, as if the delay value was reduced. As such I increased the delay to compensate.

In addition, I used the canvas scale(x,y) command instead of doing the scaling manually. Again it slightly simplfied the code in this example, but I imagine for more complex programs the benefit would be greater.

June 9, 2006

Let's bookmark bookmarklets

When I click on the URL of an mp3 file in Firefox I want that file to be streamed via Winamp. Instead, Firefox downloads the file in its entirety before passing the file on to Winamp. To get around this I have been copying the URL into the clipboard, opening Winamp, then telling Winamp to play that URL directly. Whilst this works, it is a little inconvenient. A much nicer solution is to use a bookmarklet, such as HubLog's client-side M3U generator. Just bookmark the generator, then when you want to play the mp3s on a webpage just click the bookmark. What magic!

As with all good things on the internet, the code is there for all to see:

javascript:
a=document.getElementsByTagName('a');
s=new Array();
for(i=0;i<a.length;i++){
    if((a[i].href)&&(a[i].href.match(/\.mp3$/))){
        s.push(encodeURIComponent(a[i].href));
    }
}
var newline=encodeURIComponent('\n');
var m3u=s.join(newline);
if(m3u){
    location.href='data:audio/x-mpegurl,'+encodeURIComponent('#EXTM3U\n')+m3u;
} else {
    alert('no links found');}

It works by grabbing all of the links to mp3 files, then uses the lovely (though underused) inline data facility to create an m3u playlist in situ to pass to Winamp. All hail bookmarklets!

April 17, 2006

Distributing Managed DirectX 2 applications

Before you rush off to update your Managed DirectX applications to the shiny new Managed DirectX 2 (henceforth MDX 2.0) you should be aware of the crucial fact that you cannot (in any reasonable sense) distribute your application in a usable state.

MDX 2.0 is nominally still a beta, and this is unlikely to change soon. As such, Microsoft have not released any MDX 2.0 redistributables, meaning that the only to get MDX 2.0 onto a PC is to install the 350MB DirectX SDK. Oddly, despite the fact that elimination of DLL Hell means that the app will work with the MDX 2.0 dlls included in the application folder, and not needing installation, the SDK EULA doesn't let you do this.

Development of MDX has morphed into a more holistic game development library called XNA, which promises a more mainstream role for MDX for PC and XBox 360 games.

Whilst XNA is the future, continuing support for MDX 1.1 is promised, so the practical approach is to keep your applications targetted at MDX 1.1 until a non-beta release of its successor (be it called MDX 2.0 or XNA) appears.

March 7, 2006

Weather APIs

I built my Weather Guesser using the Services_Weather PEAR PHP module. Although the module can retrieve weather data from CapeScience's GlobalWeather, EJSE, Weather.com and NOAA, only the last of these was suitable for my simple needs. I'll explain why, and describe the other weather APIs that I have found.

  • NOAA - the USA's National Oceanic and Atmospheric Administration's National Weather Service provides METAR, or METeorological Aerodrome Reports. The reports are freely available, and cover airports throughout the world. The actual data returned is in a cryptic code, like YPPH 071430Z 10003KT CAVOK 22/14 Q1012, but Services_Weather helpfully translates it into something more user-friendly.
  • weather.com - has onerous terms of use, effectively saying that you can use their weather API as long as it is to produce weather pages that look and function identically to the Weather.com site. It even has a term stating that a person's location has to be stored as a permanent user preference unless the user alters it, which makes my application ineligible.
  • AccuWeather - I noticed this because it is being used by the Mozilla Firefox weather extension ForecastFox. However, I couldn't find any details of a free API.
  • GlobalWeather - this service has disappeared, but an answer in their FAQ promises it will return.
  • Yahoo Weather - data is provided by Weather.com, but seems to have much more liberal terms of use than them. The API is really easy to use, requiring just a simple GET, eg. http://xml.weather.yahoo.com/forecastrss?p=USCA1116, and returning some comprehensive XML. Unfortunately, it doesn't provide an API method of determing the ID for a particular location. For the US zip codes can be used, but for the rest of the world you have to determine the code via a manual search on the Yahoo Weather home page. I suppose this could be screen-scraped, but that really defeats the purpose of an API.
  • EJSE - US only, so not investigated.
  • WeatherBug - US only, so not investigated.

February 21, 2006

Animation of embedded images

Following on from my previous post on Embedding data within HTML I thought it might be interesting to see if you could use client-side JavaScript to modify the embedded data in a useful manner. It turns out that modifying the palette of a GIF image is not very difficult, so here is a proof of concept that demonstrates how this colour change can be effected.

You can see the code by viewing the source of this page. The main interesting component (copied below) is that the colours are set by modifying a few particular bytes. Specifically, the hex value of red is set at bytes 43 & 44, green at 46 & 47 and blue at 49 & 50 of my data element. Knowing that, the reading and writing of particular colours is elementary.

function setColour(data, red, green, blue) {
	dataOffset = 43;
	return(
              data.substr(0, dataOffset) + 
              inHex(red) + '%' + 
              inHex(green) + '%' + 
              inHex(blue) + 
              data.substr(dataOffset + 8)
	);
}

An enterprising programmer could no doubt use this to animate a rather more complex image. However, JavaScript is a pretty slow language, so the size of the image and the animation speed would probably be quite limited.

Again I apologise to users of Internet Explorer, but your browser is too old for this demonstration.

February 19, 2006

Embedding data within HTML

After creating the interesting, though perhaps ultimately slightly pointless, online Asciifier recently, I was intrigued to learn of another method of inserting image data directly into an HTML page. The underused data:URI scheme involves a straightforward encoding a small amounts of data. The smallest example I could come up with is this 1x1 white pixel.

<img src='data:image/gif;base64,R0lGODdhAQABAIAAAP///////yw
AAAAAAQABAAACAkQBADs='/>

Once again downtrodden users of the ancient Internet Explorer 6 are left out in the cold, as that browser is not in tune with such modern lingo as this. People viewing this page with less antiquated software will now see a delightful image from the great Henry Fuseli - Silence, 1799-1801.

Despite being around for a number of years, data:URI has not been extensively used. Is this because it's not well-known, or because it's not very useful? I'm afraid it may be the latter, and until Internet Explorer supports it, it will remain a toy for internet nerds alone.

January 24, 2006

Doctor Who's very special effects

Doctor Who has developed a reputation for its low budget special effects. Whilst recently watching some of Peter Davison's 1983 episodes I noticed that the TARDIS console display looked suspiciously like it had been generated by a BBC Micro. Did the BBC use a cheap home computer from 1981 to simulate the advanced computing power of hundreds, even thousands of years into the future?

The Twin Dilemma, broadcast in 1984, was the first storyline of Colin Baker's era as the doctor. Either by accident or design, a brief sequence during this program actually showed the BBC Basic and assembler code used to create the console display. Luckily, I managed to capture a few screenshots with which to remember this momentous occasion.

Here is the doctor, in rather bland garb, and his assistant du jour, Peri. The accompanying shot is of this episode's terrifying aliens, the Gastropods.
(Click on screenshots for larger pictures)

This is the command centre which contains the display of interest. The woman closest to the camera is "operating" the display.

I've transcribed the code below. If you want to have a play with BBC Basic then you can try an online BBC emulator written in Java, but note that the code given here is incomplete, and that you may need to tinker with the key mapping option to produce all of the BBC's keystrokes.

The code we can see is just the final lines of a display program. Up to line 400 it's in assembler, which I would guess is to be the procedure that does the actual printing to screen. Lines 410 to 610 are the definition of a procedure called title. This calls PROCdisplay a number of times, which is presumably the assembler procedure that we see the end of above. You can even see the RUN command at the bottom of the screen, ready for someone to press Return.

 TA&7A
360.AP:LDX&78:LDY#0:.AD:LDAM%,X:STA(&76),Y:CLC:
 TYA:ADC#8:TAY:DEX:BNEAD
370CLC:LDA&76:ADC#1:STA&76:LDA&77:ADC#0:STA&77
380DEC&7B:BNEAQ:CLC:LDA&74:ADC&82::STA&74:STA&76:LDA&75:
 ADC&83:STA&75:STA&77:LDA#8:STA&79:.AQ:DEC&7A:BNEAP
390CLC:LDA&72:ADC#1:STA&72:LDA&73:ADC#0:STA&73
400DEC&7F:BEQAZ;JMPAA:.AZ:RTS:J:NEXT:ENDPROC
410DEF PROCtitle
420REPEAT UNTIL INKEY(0)=32
455Xsize=4:Ysize=4:YOUR$="_______":PRINTTAB(6,7);:
 PROCdisplay
460Xsize=4:Ysize=4:YOUR$="X,V,773":PRINTTAB(6,6);:
 PROCdisplay
461REPEAT UNTIL INKEY(0)=32
465Xsize=2:Ysize=2:YOUR$="LAST LOCATION: 27:43":
 PRINTTAB(0,14);:PROCdisplay
466REPEAT UNTIL INKEY(0)=32
467Xsize=2:Ysize=2:YOUR$="LAST CONTACT: 12-99":
 PRINTTAB(0,20);:PROCdisplay
470REPEAT UNTIL INKEY(0)=32
475Xsize=2:Ysize=2:YOUR$="_______":PRINTTAB(2,29);:
 PROCdisplay
480Xsize=2:Ysize=2:YOUR$="BELIEVED DESTROYED":
 PRINTTAB(2,20);:PROCdisplay
520FORW=0to 463:NEXT:
610ENDPROC
>RUN

If you want to decipher the code, and you are not that familiar with BBC Basic, you should know:

  • spaces are usually ignored
  • : is a separator
  • A% is an integer variable named A
  • R$ is a string variable
  • &76 means hexadecimal number 76
  • DEF PROCexample ... ENDPROC is a procedure declaration
  • PROCexample calls the procedure
  • REPEAT UNTIL INKEY(0)=32 means pause until space is pressed
  • PRINTTAB(X,Y) sets up where on screen the next text will be written, with (0,0) the top left

Here's the output, which unsurprisingly does what the code specifies. If you look carefully you can see the angled bracket on the end of the bottom line where the computer is waiting for more input. The picture on the right shows the screen in situ, on the far left of shot.


The Cybermen - Thwarted by a BBC Micro

The very next storyline had the exact same occurrence, but with more advanced graphics. Here are the doctor and Peri again, as they appeared in Attack of the Cybermen, and the code itself, which appears for only a couple of frames.

I have copied as much as I can make out below. I have also annoted the parts that involve special BBC Basic commands. In reading the code, note that graphics are always done based on a hypothetical screen which is 1280 pixels wide and 1024 pixels high, with the origin (0,0) at the bottom left. This is distinct from text mode, which has an origin at the top left.

870X%=A%*SINB
880Y%=B%*COSB
890MOVE0,0
- fill a triangle between specifed point (X%,Y%) and last two points used in plotting actions
900PLOT85,X%,Y%
910NEXT
1090
1100ENDPROC
1110
1120
1130DEFPROCGRID
1140
1150
- redefine graphics origin to point (0,0)
1160VDU29,0;0;
- redefine colour 1 (red) to be absolute colour 7 (white)
1170VDU19,1,7,0,0,0
- set graphics colour to 1 (red)
1180X=5:GCOL0,1
1190LOCALX:LOCALY
1200FORX=0TO1275 STEP1275/N
1210FORY=0TO1020 STEP1028/N
1220MOVEX,0:DRAWX,Y:NEXTY:NEXTX
1230FORY=0TO1028 STEP1028/N
1240FORX=0TO1275 STEP1275/N
1250MOVE0,7:DRAWX,Y:NEXTX:NEXTY
1280
1290
1300
1310
1320ENDPROC
1330
1340
1350
1360END
RUN

This is the grid being drawn with its vertical lines first, from left to right. Then come the horizontal lines, from the bottom up.

Finally, you can see a circle being drawn out of triangles, which is probably done by the bit of code before line 1100. In the actual storyline, this denotes the location of the cybermen's transmitter.

I wonder if the BBC's innovation in using a common household microcomputer to produce effects for its leading science fiction program of the day was noted at the time. If not, then it's not too late to redress the balance, and praise their skilful use of meagre resources to produce a memorable program.

December 14, 2005

SQLite delight

If you've been reading the MovableType forums recently then you might have come away with the impression that the venerable Berkeley DB database is old, slow, and easy to corrupt. A similar response can be found if you Google for berkeley corrupt movable type.

Despite the fact that the only trouble I have had in almost three years was when my host upgraded their version of the Berkeley DB software, so my blog stopped working until my database was upgraded too, I was concerned about these aspersions being cast. Fortunately, it doesn't take much effort to discover that the BDB is still highly regarded in technical circles, and is often the best tool for the job. However, there are some areas where alternative databases are better suited.

Perl.com has a great concise technical comparison of BDB with the new contender SQLite. From this programmer's standpoint, and ignoring speed issues, SQLite is a clearly superior solution. The data itself is all neatly contained in a single file, as opposed to BDB's sprawling mass. Even more importantly, the data itself is exceedingly easy to query and manipulate, using standard SQL syntax. It feels the same as a "real" database, such as SQL Server or MySQL, which makes the transition between them all quite straightforward.

For these reasons, when I had the opportunity to move my MovableType database from BDB to SQLite with my transition to a new host, I did so. It immediately paid dividends, because I found that the data needed some coaxing to get the blog set up perfectly. Although a script is provided that theoretically moves the data from BDB to any of the supported SQL databases, I found that it did not actually run for me. Rather than debug the script, I decided to use MT's export and import facilities. This route does not maintain your MT settings and templates, but I had so much detritus from previous versions of MT around that I thought a clean start would be good.

After the initial import of my old blog entries to my new blog, I was disappointed to find that most of the individual entry archive names had changed - they were longer than before. For example, /archives/2005/11/worth_waiting_f_1.html had become /archives/2005/11/worth_waiting_for.html, thus breaking my permalinks. It turns out that the entries do not have their file names stored in the export file. This combined with the fact that the default Basename Length had been increased from 15 to 30 in the latest MT to produce different file names. Luckily this was easy to fix. After deleting my entries, setting the default back to 15, then importing again, I found the archive names back to how they should be.

Longer base names do produce more readable URLs, so I decided to go with the new default of 30. But what if I wanted to export and import my data in future? How could I import some entries with a basename of 15 and some with a length of 30. Luckily, with an SQL-compliant database this is easy. Just import everything with a length of 30, shorten the relevant ones, check for duplicates, and rename as appropriate.

Say, for example everything before 2004 used 15 character basenames. This command will shorten them:
UPDATE mt_entry SET entry_basename = substr(entry_basename,0,15) WHERE entry_created_on < date('2004-01-01')

Then, because some entries might now have identical names, we must seek them out:
select count(*) as num, entry_basename from mt_entry group by entry_basename order by num desc

If you find any with the same name, just use a numeric suffix, as MT itself does.

This fixing is all pleasantly hassle-free, due to the benefits of SQL compliance.

November 24, 2005

OpenOffice 2.0 - codenamed sloth?

It has been noted that OpenOffice 2.0 is slow to start. One of the tricks that is used to keep users from being too annoyed whilst they wait it to start is to show a progress bar, which gives a visual indication of how long the user will have to wait. In fact, users prefer a longer wait with a progress bar than a slightly shorter wait without the progress bar.

In OpenOffice's case, on my computer at least, the progress bar is decidedly useless. When I start any of the OpenOffice programs, the progress bar pops up and reaches 100% in under half a second. It then stays in that state for another 8 seconds until the program has fully loaded. Whilst I believe that 8 seconds is a long time to wait for a simple program to load on a fast computer, an improvement in the relation between the progress bar and what is actually happening will go a long way to improving the end-user experience.

November 13, 2005

Skybox seams

After learning about skyboxes for the first time only a few days ago, I decided it would be a useful addition to my 3D fractal generator FractalPeaks. Rather than controlling a fractal hovering in space, the skybox would be an easy way of surrounding the fractal with a realistic world. After following the great Microsoft Beginning Game Development tutorial I had a functional skybox, but I wanted higher quality original graphics.

In addition to Terragen, which is a great free program for generating skybox textures, you can download prepared texture collections specifically for skyboxes. DirectX is happy with both .tga and .jpg file types; I used the latter because they are smaller.

One thing to watch out for is the appearance of seams at the edge of the skybox textures. I didn't have a problem with the original sample, but one I downloaded had some pretty ugly borders. After trying the recommended procedure of setting the texture clamping, which in Managed DirectX is done like this:

device.SamplerState[0].AddressU = TextureAddress.Clamp;
I had no success.so then I tried:
device.SetSamplerState(0, Microsoft.DirectX.Direct3D.SamplerStageStates.AddressU, 3);
to overlap the textures. Again that failed.

I then thought of resizing my textures from their original 768x768 to a power of 2 that computers seem to like so much. At 512x512 the seams were completely gone. It doesn't look too much worse, so that's a pretty good outcome. After reading a bit more about textures, I believe that this problem usually only occurs with older cards. As I want my software to be usable by everyone I'll make sure to keep an eye on this in future.

November 8, 2005

Back to DirectX

After my last foray into the world of DirectX I didn't continue with doing much work in that area. I've been inspired to try playing with it again with the recent release of version 2 of the .Net Framework, and the associated free release of Microsoft's Visual Studio Express tools. The development IDEs weren't going to be free, but Microsoft have had a benevolent change of heart, releasing them free for the next year.

In addition to this shiny new development environment, Microsoft have been busy putting up some great new tutorials for people getting started with Managed DirectX coding at their Coding4Fun site. All in all, they're doing a good job of enticing new programmers to try their wares, which means more fine software being produced for all of us.

October 14, 2005

Firefox canvas demos

Mozilla Firefox 1.5 introduces the <canvas> drawing tag to play with. Apple's Safari browser already supports it, but until the strangely popular Internet Explorer does too it will have only limited usefulness. Nevertheless, that's no reason not to experiment.

After a brief play, I came up with some fractal examples.

Perhaps with universal browser support this will replace Flash. It's certainly much easier for a competent HTMLer to work with, with a minimal learning curve compared to any of the Flash creation languages.

Update 16 June 2006: Flame demo added.

Update 21 June 2006: Fractal zoom demo added.

September 19, 2005

Laszlo is flash

There are a variety of ways of creating Flash applications. A free, open source solution that has been gaining popularity is OpenLaszlo. It uses Java to compile javascript and XML source files into Flash - enough buzzwords to interest even the most jaded programmer.

After installing Laszlo, the first thing I noticed was how developer-focused the system is. To compile and run your Laszlo source you just need to naviagate to it in a browser, where it appears in a Laszlo frame along with all the essential links to docs and resources that you could need. I used vim to edit the source, then just refreshed the browser whenever I made a change. It was a bit slow to compile even my very small program, but I don't know whether this increases much for larger programs.

The included documentation and tutorials were great, with the exception that a few new features, such as drawing, were only described in the tips section of the Laszlo web site.

For a very few features, such as SOAP, the running Laszlo code must interact with a server-based java servlet. However, mostly you can just do a solo (ie. flash only) deployment. The server is still required for compilation and development.

For my first Laszlo program I created the television sizer. I spent a while putting together horrendous, but working, code. After a few days I got a better idea of how things were meant to work, and easily fixed my earlier efforts. So, while it was a bit of a jump from languages such as PHP, Perl, Python and ASP, it was only a small jump. The use of tags for everything made it feel like Cold Fusion, though much simpler and, as you'd expect, more graphically focused.

It's difficult to imagine it scaling well, but then how big would anyone want a flash application. Overall, it's been well worth learning, and might come in handy one of these days.

May 4, 2005

Programming the Topfield 5000 PVRt

One of the reasons for the popularity of the Topfield range of Personal Video Recorders is their open API, which allows users to write programs to modify the PVR's interface.

Once you've downloaded all of the API software from Topfield's Korean site, you'll notice that the documentation is a little sparse. Don't let that put you off, as there's plenty of help out there.

Note that if you don't install into c:\cygwin then you must ensure that the correct directory name is in the PATH, the C_INCLUDE, the CPLUS_INCLUDE and (this isn't mentioned in the guide) in TAP.LD.

The programming process is:

  • edit .c file
  • run build.bat to compile
  • if successful, use Altair to copy it across to the Toppy
  • test it on the Toppy
  • repeat from the start until bug free

If you have problems then the place to ask is in the Australian Topfield forums or the new UK Toppy forums. There really needs to be a programming Wiki to hold those commonly-asked questions, but there isn't one yet.

A great way to learn is to look at other programs to see how things are done. Most of the TAPs now available also provide their source.

A great sticking point for beginners is that the API documentation is not as comprehensive as it could be, and trial and error is usually required to complete your understanding of particular functions. The following example shows the problem I had when trying to create a TAP to show a new screen aspect ratio (14:9, half-way between the 4:3 of television, and 16:9 of cinema).

From the API pdf:

TAP_Channel_Scale
int TAP_Channel_Scale( int mainSub, long x, long y, long w, long h, bool anim )
� It changes the size of screen.
mainSub : 1 � main screen, 0 � sub screen
x, y : upper-left coordinate of the screen
w,h : width and height of the screen.
anim : if TRUE, it is scaled smoothly.
Return value : : If 0, there is no errors.

Good, that looks to be just what I need. I just need to zoom in and shifting the 16:9 picture left and up a bit.

After playing with this for a while I found that the width and height were not independent, and could not be increased. At this point I abandoned this TAP project. Proper documentation, in the API docs or a wiki, would have saved me a lot of time.

Regardless of the documentation problems, the fact that there's an API at all is a marvellous thing, and should be applauded.

April 20, 2005

Delphi 2005 Personal now available

The May 2005 edition of Australian Personal Computer magazine is carrying the Personal edition of Borland Delphi 2005. I usually find that APC is so content-free that it's not even worth browsing, but I justified the purchase this month by thinking of it as a free magazine attached to a $10 copy of Delphi.

I have only had a cursory glance at the software so far, but it promises to unify the IDE for my last two major projects, FractalPeaks (.Net, done in C# Builder) and WimpWall (Delphi 6). The old C# Builder was pleasantly lightweight, but carried some unfortunate bugs, so this new version is welcome. The new Delphi, on the other hand, carries a sense of forboding, given that no version since 3 has improved on its predecessor.

Update 3 Jan 2006: The French version can be downloaded from Developpez.com.

You may also still be able to order back issues of magazines which had it on their cover discs. These include:

Update 5 Oct 2006: Doom9 has another source, and good information about 3rd-party fixes.

March 1, 2005

Why to avoid Managed DirectX

When I released FractalPeaks I harboured the faint hope that some people would be able to just unzip it and run. However, after looking into the problems of installing Managed DirectX, I've revised that hope down to nothingness.

Not only must people have gone out of their way to explicitly install Managed DirectX in addition to DirectX, but they will have to have installed the December 2004 release (not Oct 04, Feb 05 or the upcoming Apr 05). If they don't have the right version, then the program with crash with some incomprehensible error message along the lines of

Application has generated an exception that could not be handled.

Assuming that there are some motivated souls who still wish to install the December 2004 Managed DirectX, what choices does Microsoft offer? Users are forced to download the 35MB redistributable to obtain the 3.5MB Managed DirectX installer, because Microsoft does not allow the distribution of the Managed DirectX installer by itself.

For FractalPeaks, the easiest solution would be to offer a download containing the dll files required. They would sit in the FractalPeaks folder, and not require installation. However, though this is by the far best solution for end-users, Microsoft does not allow the redistribution of the Managed DirectX dll files in this manner.

Much as I dislike large installers for tiny programs, in the interests of my end-users I have created an installation program for FractalPeaks which checks and installs the relevant software with as little user interaction as possible. It uses Nullsoft's NSIS, and was inspired by the installer for World Wind.

February 28, 2005

Installing Managed DirectX

As mentioned previously, the managed extensions for DirectX are not installed by default.

You'll need to use the 35MB DirectX 9.0c Redistributable for Software Developers - with Updated DirectX for Managed Code - (December 2004) to get the 3MB of Managed DirectX files.

  • If you haven't installed DirectX 9 yet:
    Install both DirectX9.0c and DirectX for Managed Code, by using the command:
    DXSETUP.EXE /InstallManagedDirectX

  • If you have already installed DirectX 9:
    Install just DirectX for Managed Code. Extract the MDXREDIST.MSI from the ManagedDX.cab file (WinZip or your favourite archive program should be able to open cab files) and launch MDXREDIST.MSI directly.

Note that some parts of Managed DirectX are not backwards compatible. Microsoft releases a new version every two or three months (eg. December 2004, Feb 2005), and the wrong version might not work at all with code written for a different version. However, you can have numerous versions installed simultaneously without a problem.

Some software, such as Media Portal, includes all of the .dll files required (ie. just in the exe directory, not requiring installation), to make a large but problem-free download and installation for their users.

This lack of backwards compatibility is mentioned elsewhere, and is seen by developers as a major impediment to the uptake of Managed DirectX as a mainstream language.

FractalPeaks released (prematurely?)

Yesterday I unleashed FractalPeaks, my 3D fractal explorer, on to the world. Unfortunately, it appears that the world is not ready. The trouble is that I wrote it using Microsoft's latest technology, the .NET Framework and Managed DirectX 9c. Whilst it has been great for the developer, it appears that non-developers will have a hard time getting their machines capable of running it.

I assumed that it would just be a matter of installing the .Net Framework and DirectX, but it seems that DirectX does not by default install the managed extensions required by .NET.

Once I've found out more about this whole topic I'll update my instuctions on installing FractalPeaks. I know that it's possible because the delightful MediaPortal has no problem; they don't even require the installation of DirectX with managed extensions. I might have to peek into their source code (one of the many benefits of open source).

After that's all sorted I'll do some more interesting blog articles about FractalPeaks itself.

February 4, 2005

Learning Direct3D (DirectX)

If you already know C# and a bit of trigonometry, then it should only take you a few hours a day for a week to learn the basics of Managed DirectX 9. I used the free Borland C# Builder, but I suspect that Microsoft Visual Studio (or Visual C# Express) would offer slightly more polished interfaces. C# Builder would sometimes fail to offer help on clicked functions, forcing me to navigate to the relevant help pages manually, and its autocompletion of functions (cf. Intellisense) was not comprehensive.

I found a number of DirectX 8 C++ and DirectX 9 C# tutorials useful. It's not always obvious how the calls change from the former to the later, but at least it shows you what is possible. I recommend following the tutorials listed below in the given order.

  1. Riemer's DirectX 9 Tutorial (C# DX9). A brief, easy-to-follow tutorial that quickly produces impressive results.
  2. Drunken Hyena Direct3D Tutorials (C# DX9). Covers pretty much the same areas as the previous tutorial, but explained differently and in more detail, so useful in filling in gaps.
  3. Craig Andera's DirectX Wiki(C# DX9). Goes much further than the previous tutorials, exploring topics such as materials, textures and lighting in great detail.
  4. Andy Pike's DirectX 8 Tutorials (C++ DX8). Don't let the C++ put you off. Goes into a lot of detail on a lot of topics.
  5. Using Managed DirectX to Write a Game (C# DX9). Unlike all of the other tutorials, this actually leads you into producing a playable game. It's not as detailed on theory, but has lots more practical advice.

October 3, 2004

WimpWall v0.3

I've just put out an unexpected new version of WimpWall, my freeware wallpaper changer. It's unexpected because I had thought that my last release was feature complete, but after a number of requests from users I decided to add one little option.

It is now possible to turn off the countdown dialog preceding wallpaper changes. I won't use this option myself, because I prefer the ability to cancel a change if I particularly like the current wallpaper, but I appreciate that some people prefer the silent approach.

Although adding this to WimpWall was pleasantly straightforward, it did necessiate rewriting the settings parsing code. This is because I had assumed that, as mentioned before, v0.2 was feature complete, and the settings would never change. In v0.3 I had to add the countdown setting. Related to this, to cater for people upgrading from v0.2, I had to change from a hard-coded to a modular method of parsing. Fortunately, this means that any future unexpected changes will be easy to accommodate.

With this new release I also added polish to a couple of items, which you'd never notice, but make me feel better.

August 17, 2004

Creating icons

The final creative step in creating WimpWall was to design a new icon to replace the default Delphi one. This is an essential step in creating a professional program. No matter how simple it is, you must have a unique icon.

I had two main problems. I am not good at designing icons, and I don't have any (working) icon design software. Delphi actually comes with an image editor, but for some reason it would only save corrupted icons for me. So, I abandoned that and had a quick look for a free icon editor on the net.

My requirements were: small, completely free (no nags or ads), load and save BMP and ICO, and a functional UI. I found all of these satisfied in @icon sushi. There were larger, more functional programs around, but being small is a virtue to me.

Finally, after a few brief aborted efforts, I again concluded that designing icons was far beyond me, so I grabbed the Mandelbrot icon from JM's Mandelbrot Explorer (which was created by that program), imported it into Photoshop, changed the hue, and saved it as a new icon. I'll just use a family of Mandebrot icons for all my software in future.

August 5, 2004

New free wallpaper changer

I've just put WimpWall, the wimpiest way to change your Windows wallpaper, out into the world.

There's a remarkable number of wallpaper changers already out there, basically because it's so simple to code. The actual work to tell Windows to set its desktop to use this_nice_picture.bmp is one simple well-documented line. Where the fun comes in is automating this process, and making it a little more functional. For example, unless you use the resource-hog of Active Desktop you can only use BMP format pictures. So you'd probably want your wallpaper changer to cope with JPEGs, by doing a conversion.

Another thing that I wanted, but couldn't find in one package with my other wants, was the ability to run once, such as at startup, then exit, so as not to use memory all the time. Also, I have my wallpapers categorised into different folders within a wallpaper folder, so I wanted to be able to just specify that main folder, and have the changer recurse down into the others.

I actually found some software that did both of these things. It was tiny, and had a minimal GUI interface. However, it offered no options on how to display the image (eg. tile, stretch or centre), and it sometimes chose the ugliest possiblity.

So, I installed Borland Delphi 6 Personal, from a magazine CD, and spent a few days writing the changer of my dreams. After finishing the major functionality, and polishing the GUI, I added a final convenience option. I gave a little 5 second warning before the picture is changed, allowing it to be cancelled. This was for those times when I'd set a wallpaper that I was particularly fond of, and I wasn't ready for it to be changed.

To finish my work on it today, I set up its web page, created a program icon for it (by changing the colour of my Mandelbrot Explorer program icon - I decided to keep the fractal theme), and finished documenting the code.

So, I installed Delphi 6 last Thursday, started WimpWall on Friday, and put it on the net today, Thursday of the following week. I guess it really is RAD.

August 3, 2004

Delphi 6 vs. Visual C# Express 2005 (Beta 1)

I remember fondly the pleasant days of churning out Windows utility after Windows utility in the RAD world of Borland Delphi 2 and 3. The Object Pascal language was a cohesive delight, and the IDE with "Code Insight" made finding the write variables a breeze. I used Delphi 3 until 2000, when my work took me in other directions.

Seeing the free downloads of the first beta of Visual C# Express, a lightweight version of Visual Studio for C# programming picqued my interest, so I grabbed and installed the hefty download. As well as the program itself, it also wanted to install the MS SQL client, Server Desktop engine, MS XML 6 and the .Net 2 framework beta (if I recall correctly). Anyway, you'd want broadband to get it.

Now, this is hardly a fair or comprehensive comparison. Delphi 6 is three years old, and Visual C# Express is only in its first beta.

Delphi 6 was good because:
  • The IDE was much smaller and lighter, and thus faster to load and exit
  • The IDE did not crash
  • Delphi programs do not require the .Net framework to run
  • Delphi has been popular for such a long time that any problems developer come up against are already documented on the web
Delphi 6 was bad because:
  • The IDE seemed hardly to have been updated since Delphi 3, and so felt old
  • "Code Insight" only worked occasionaly. Usually it didn't pop up any help.
  • The debugger was always a few lines out when flagging errors in my code
  • After a lot of programming in Javascript, C#, Perl and Python, the Pascal language seems overly verbose
  • Lots of work with elements integral to Windows, such as popping up a dialog to select a folder, and working with shortcut files, are reliant on finding and installing third-party components
Visual C# Express was good because:
  • The "Intellisense" was informative and worked perfectly
  • The .Net framework is comprehensive
  • C# is much less verbose than Pascal
  • Modern standards are fully supported and easy to use, such as retrieving and manipulating XML and SOAP
Visual C# Express was bad because:
  • It was a resource hog
  • It produced the biggest crashes I've ever seen, taking down my whole (Windows 2000) machine regularly
  • Developed software requires the .Net framework to be installed

July 22, 2004

Regex Rules!

Apparently Perl 6 will use verbose regular expressions (ie. extended whitespace mode) by default. If it's that highly thought of, then maybe it's time to consider using it too. Although I've never even considered it when writing my own code, I always wish that others would use it to make their code more understandable. This is especially the case since doing a bit more work in Python, where standardised, readable code-layout is enforced. As such, Five Habits for Successful Regular Expressions is highly recommended.

July 9, 2004

Creating Firefox extensions

Due to its comparative youth, there is a decided lack of information about writing extensions for Mozilla Firefox. Until it reaches its version 1 release, the specs are expected to remain in flux, and this has p