Category Archives: Design

NordiCHI day 1

The keynote was academic and based on a false dichotomy between the “second and third wave” of HCI.

The papers are academic and narrowly focused – but they mostly have practical results and some even have metrics to back up their arguments.

The design and industrial reports are more applicable, but don’t have the same rigor as the academic papers.

The organizers have done a great job – most of the talks have gone off without a hitch, and the reception with the Mayor last night was a treat.

Design vs Usability: Fight!

I had a short presentation yesterday in front of what seemed like all the software designers and usability gurus in Oslo.


The topic was obviously something near and dear to both designers and usability experts: how to get along with each other. Or (more likely) the title was like blood in the water: people wanted to see blood, to see the other side crushed, and here I was preaching peace, love and understanding.

They took it surprisingly well – they laughed at my misrepresentations and exaggerations. Several people were nice enough to buy me beer after the talk.

One thing that seems obvious after listening to the discussion is that the stereotypes are alive and well, even in the enlightened group that showed up at Scuba Bar last night.

Useless Error Messages

Our own software is guilty of this kind of stuff too, but this one is particularly annoying, since the message promises to specify the module that’s causing the problems. But does it appear? Nooooooo. Of course not.

A curse on the Microsoft developer who wrote this error message. May your capslock key become stuck at random intervals!
ASP error message

EA Downloader sucks

This is frustration that others also have problems with.

Why is it that almost every time I start EA’s downloading service to make sure I can play some Battlefield 2 – I get this slapped in my face?

I’m sure a lawyer somewhere is really proud of that text, but I don’t really care.

Even worse is really that the Downloader is too stupid to remember what I have installed, so it can’t update them automatically. I have to hunt around on some god-forsaken web page to find the right patch update for my version of Battlefield 2. Let’s face it – EA aren’t paying me enough to be their sys-admin. This stuff should just work.

Whenever I go to play some of Valve’s Half-Life I just get this:

Valve’s Steam service is smart enough to update itself and not hassle me every time itself or one of the apps its hosting. It subtly indicates that it is downloading stuff, but apart from a little line drawn in toolbar, I don’t even notice that it’s working.

People bitch and moan about Steam crashing or choking – but from my personal experience it’s never been a problem. It doesn’t get in the way of my objective: playing the games it holds.

EA’s download service, on the other hand, sucks donkey nuts.

PCs in the Jungle

I’ve been keeping track of the Jhai project for a couple of years now. Lee Felsenstein (one of the original 60s hackers) worked on designing and building a computer that could help Laotian and Viet-namese villagers communicate with each other. The design problems that came up during the field tests are quite different from the usual design problems. Intermittent network access is one thing. Intermittent power is tougher. Humidity and damp. Portability. Robustness. Cost. Lots of tough constraints to work within.
This week the project announced a project success. They’ve deployed and run for months out in the bush, running on local power sources without crashing. The latest update makes for interesting reading.

You can see a steady progression from Felsenstein’s Community Memory project in 60s Berkeley to this – essentially a bigger, distributed version of the same thing. The key is computer as commincation and community device.

The other point of interest is the Jhai project’s focus on economics. Economic principles function on all levels of society (as Grameen micro-banking illustrates). Economies require a free flow of information to function well. A networked computer enables the farmers – it gives them access to market information, and to education and learning.
The idea of putting cheap computers into dirt poor villages seems absurd. Surely a water-pump or plumbing are more important? But the idea seems to be working – the computer makes it possible for the farmers to earn enough to buy their own pump/generator/whatever.

The old dream of the personal computer as a possibility magnifier still lives, and that makes me happy.

Door usability

There are sliding doors into the underground station at Nationaltheateret in Oslo.

Obviously, people got confused, walked into panels that did not open automatically, that did not function as doors. The wall of glass doors has a “false affordance”; parts of it look like they would open, but don’t. So someone decided to paint arrows to help people distinguish the door parts from the non-door parts.

The arrows do not help.

Some arrows point towards the door, some point where the door is going to go. Like this:

 > >    <> > < < >   < < > > < <

Some of the arrows have fallen off, making it even harder to figure out.

A better solution would have been to put arrows only on the non-sliding parts, or better yet, add a half-tone or checkboard pattern to those parts instead of using an arrow. A clear window then indicates a doorway, while a translucent window indicates it functions as a wall.
I enjoy this little dance with the doors nearly every day, because it reminds me of the
first chapter in Don Norman’s book on Everyday Things. It features a glass-door trap as an example of poor design.

Direct Manipulation Multi-Touch-screens

I want a user interface this cool and this interactive. (Full video at google)
Multi-touch interaction experiments

Unlike the wall-size display that Tom Cruise used in Minority Report, this stuff is real.

The cool thing here is that the user interface supports multiple touch-points, so that you can use both hands and multiple fingers to manipulate the objects on the screen. You can thus rotate an image by pinning a corner and dragging the other corner with your other hand. You can scale and object by dragging its corners further apart. The whole UI becomes much more interactive and manipulable, in a way that should make the whole UI a sort of simulated, cartoon reality. Like a cartoon, everything is squishy and stretchable.

Randy Smith did some interesting UI work on this type of system via ARK (Alternate Reality Kit), but it was limited by having a single mouse pointer.

Self is another system that would work well with this kind of GUI – the objects have a virtual physicality that lends itself to direct manipulation. One of the GUIs built on Self implemented the Disney laws of animation, so that windows bounce and deform much like Bugs Bunny would, rather than just appearing out of thin air.


I’m improving the installer for a web application. It’s a windows installer. It needs to register a MIME type with the server. This is important to do, since Windows 2003 server will not serve unknown Mime types. (Neither will Windows 2000 after the Lockdown tool has been used).

WMI is the preferred mechanism for diddling IIS settings, but it turns out you can’t rely on WMI being installed. So we need to user ADSI, the underlying technology.

ADSI is a maze of little automation objects, all poorly documented. There’s plenty of documentation. It’s just that most of it is pointless drivel. Undocumentation as some have called it.

The ADSI incantations necessary have been recorded by wizened elders.

Unfortunately these incantations need to be converted to C++ in order to work inside an installer. There is a heavy bias against using script in installers. Partly because script may not be installed, or if it is installed, it’s a lower version than we require. So a hardened C++ version is needed.

In case anyone needs to know, here is how to tweak ADSI to add a mime-type to IIS from C++. It’s not pretty – being a frankenstein monster of cut-and-paste snippets from various places.

char buf[BUFLEN];
strcpy(buf, "");

_bstr_t rdfType = ".rdf";

_bstr_t bsMimePath = "IIS://localhost/MimeMap";

IADs* pContainer = NULL;
HRESULT hr = ADsGetObject( bsMimePath, IID_IADs, (void**) &pContainer);
if( SUCCEEDED(hr) && pContainer != NULL )
_variant_t varMimeMap;
_bstr_t nameMimeMap = "MimeMap";
hr = pContainer->GetEx( nameMimeMap, &varMimeMap);
if( SUCCEEDED(hr) && ((varMimeMap.vt & VT_ARRAY) == VT_ARRAY) )
bool bFoundRdfType = false;

// MIME map is an array that we can redim and add an item to the end
SAFEARRAY* pArrMimeMap = varMimeMap.parray;
LONG lIdx, lHigh;
::SafeArrayGetLBound(pArrMimeMap, 1, &lIdx);
::SafeArrayGetUBound(pArrMimeMap, 1, &lHigh);
for(LONG i = lIdx; i < = lHigh; i++)
_variant_t elem;
hr = ::SafeArrayGetElement(pArrMimeMap, &i, (void*) &elem);
if( SUCCEEDED(hr) && ((elem.vt & VT_DISPATCH) == VT_DISPATCH) )

IDispatchPtr pMimeType = elem.pdispVal;
if(pMimeType != NULL)
DISPID idExtension = 0;
_bstr_t propName = "Extension";
BSTR pName = (BSTR)propName;
BSTR* ppName = & pName;
hr = pMimeType->GetIDsOfNames( IID_NULL, ppName, 1, LOCALE_USER_DEFAULT, &idExtension );
if( SUCCEEDED(hr) )
DISPPARAMS dispparamsNoArgs;
memset( &dispparamsNoArgs, 0, sizeof(dispparamsNoArgs));
_variant_t varResult;
hr = pMimeType->Invoke( idExtension, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if( SUCCEEDED(hr) )
_bstr_t tmp = varResult.bstrVal;
if( tmp == rdfType )
bFoundRdfType = true;


// add one element
if( ! bFoundRdfType )
_bstr_t fileType = ".rdf";
_bstr_t mimeType = "application/octet-stream";
_variant_t varFileType = fileType;
_variant_t varMimeType = mimeType;

hr = CLSIDFromProgID( nameMimeMap, &CLSID_MimeType );
if( SUCCEEDED(hr) )
IDispatchPtr pMimeType;
hr = ::CoCreateInstance( CLSID_MimeType, NULL, CLSCTX_ALL, IID_IDispatch, (void**) &pMimeType );

DISPID idExtension = -1;
DISPID idMimeType = -1;

_bstr_t propName = "Extension";
BSTR pName = (BSTR)propName;
BSTR* ppName = & pName;
if( SUCCEEDED(hr) )
hr = pMimeType->GetIDsOfNames( IID_NULL, ppName, 1, LOCALE_USER_DEFAULT, &idExtension );
if( SUCCEEDED(hr) )
dispParam.cArgs = 1;
dispParam.cNamedArgs = 1;
dispParam.rgvarg = & varFileType;
dispParam.rgdispidNamedArgs = &propPut;
hr = pMimeType->Invoke( idExtension, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispParam, NULL, NULL, NULL);
if( SUCCEEDED(hr) )
propName = "MimeType";
pName = (BSTR)propName;
ppName = & pName;
hr = pMimeType->GetIDsOfNames( IID_NULL, ppName, 1, LOCALE_USER_DEFAULT, &idMimeType );
if( SUCCEEDED(hr) )
dispParam.cArgs = 1;
dispParam.cNamedArgs = 1;
dispParam.rgvarg = & varMimeType;
dispParam.rgdispidNamedArgs = &propPut;
if( SUCCEEDED(hr) )
bounds.lLbound = lIdx;
bounds.cElements = lHigh - lIdx + 1 + 1;
hr = ::SafeArrayRedim(pArrMimeMap, &bounds);
if( SUCCEEDED(hr) )
hr = ::SafeArrayGetUBound(pArrMimeMap, 1, &lHigh);
_variant_t varMimeObj = (IDispatch*) pMimeType;
if( SUCCEEDED(hr) )
hr = ::SafeArrayPutElement(pArrMimeMap, &lHigh, &varMimeObj);
if( SUCCEEDED(hr) )
hr = pContainer->PutEx( ADS_PROPERTY_UPDATE, nameMimeMap, varMimeMap );
if( SUCCEEDED(hr) )
hr = pContainer->SetInfo();

if( SUCCEEDED(hr) )
strcpy(buf, "Added Mime type for .RDF files to IIS");
strcpy(buf, "Failed to add MIME type to IIS");
strcpy(buf, "MIME type already registered in IIS");




WikiCalc and REST architecture

Dan Bricklin the co-inventor of the spreadsheet has started to build a web-based spreadsheet – WikiCalc

As office software moves onto the web, it can become more open and collaborative. Consider a web-based spreadsheet, where every cell is addressable through a URL.

If the spreadsheet is at

then the first cell of the spreadsheet should be adressable as

Ok -  now consider a spreadsheet somewhere else – the second spreadsheet could reference the results of a calculation in my sheet by reference to the URL of the cell in the spreadsheet. The second spreadsheet could contain a formula like this:

= 2 *
This is just a straightforward application of the REST architecture.

This could be a great way for government to expose standard values. Income tax rates, VAT rates and so on – easily referenced and automatically updated.

http// returns the VAT on goods in 2006 (25% in Norway).
http// returns the VAT on goods at the moment.

When the rate is changed next year, the current value is updated – and all applications that reference it get the new, fresh value without a software-update.
Now imagine what happens if we extend this to all XML documents through XPath – i.e pretend that the web server is smart enough to dig into an XML document and pull out a fragment, rather than just sending back the entire document. i.e. URLs that reference bits of a document using XPath, not just entire documents:  – this gives us the entire document.[0] – would in an ideal world give us the contents of the first second level heading: “What is REST?”

Imagine how easily you could glue together web-applications with this kind addressing…

The text fragment extraction wouldn’t have to be done by the web-server, it could just as well be done by the application. The point is that the URL would make integration with existing, well-formed content much much easier. And while much content out there isn’t well-formed (and so can’t be addressed in this way), the next generation of Office tools will output suitable content by default.

When everything is addressable, then everything becomes intertwingled. A point of potential intergration. Lots of places for leverage.

Of course, all the hard problems of versioning and formatting don’t go away, but they apply to all kinds of solutions, not just this one.