Too Cool for Internet Explorer

Foreword: I write this article especially with two projects in mind: “Eventscripts” and “Truecrypt”. Come and get me.

The species called “Programmer” seems to be a bit thin-skinned when it comes to issues only “related” to their work.

The first thing is documentation:
Eventscripts is the best example for a lack of documentation. Eventscripts is a scripting engine which enables one to write gaming server related scripts for CS:S for instance. Eventscripts uses python for the underlying scripting engine, but adds a vast amount of increments to it regarding the game events and so on.
There is a wiki containing documentation, but it is by no means complete. many commands are missing, others are incomplete, others are simply wrong. IT IS A PAIN IN THE ASS to write a script with this bad documentation.
I started a conversation regarding this issue with the Eventscripts creators, and it degenerated fast into a conflict, arguing about whose job it is to do documentation.
Since the wiki is writable for everyone, the creators have the opinion that the users have to write this documentation.
But how i ask, how can a user write this documentation without knowing what a command can do? or even not knowing that some commands exist?
IMHO it is always the job of the programmers to document their work! I also write code i publish (mostly unter GPL), but i would never even think of publishing it without a complete documentation!

The second thing is behaviour that is not caused by the program but by the operating system:
I assume you all know Truecrypt: When one creates a large container file in Truecrypt, he will most probably leave the creation process running over night, since it takes many hours to create.
The problem is: after creating and formatting the container, the operating system needs to do a task which requires system privileges. The system asks the user to give it to this process, but since no one is on the keyboard, it runs into a timeout and tells Truecrypt that the format was unsuccessful. Truecrypt then tells the user that it could not format the container AND DELETES the nevertheless successful created container.
The argument in the forum why this bug isn’t fixed is that it is a issue with the operating system, therefore it’s not the Truecrypt programmers fault. They easily could fix it by requesting the admin privileges for the process on the beginning of the formatting.

So, what is it with programmers to accept their own babies to be incomplete or faulty by simply stating that’s not their fault? I could never do that! It would break the rule of delivering a complete and usable product!

So to all the programmers out there: Stop whining and start writing cool, complete and usable software!!!

Meine 10 Grundregeln für die erfolgreiche Windows Programmierung:

  1. Halte dich auf jeden Fall an die Microsoft GUI Gestaltungsregeln, außer du bist Programmierer bei Microsoft!
  2. Wenn du Marktführer werden willst gestalte die GUI so kompliziert das die User einen halbjährigen Kurs besuchen müssen um sie benutzen zu können. So kannst du auch gleich an den Kursen verdienen!
  3. Gestalte den Ausschaltknopf in deiner Software so kompliziert das keiner es schafft ihn zu bedienen. Die User sollen sowieso dein Programm benutzen und es nicht ausschalten!
  4. Programmiere kleine Algorithmen niemals selbst, wozu gibt es schließlich 150 MB große Bibliothek die das selbe leisten wie 20 Zeilen Code?
  5. Sollte dein Programm einmal unerwarteterweise doch abstürzen sind Fehlermeldungen wie “Dieser Fehler dürfte niemals auftreten” oder „Fehler 3523456“ OK, sonst würde der User ja wissen was schiefgegangen ist und könnte sich beschweren!.
  6. Baue in dein Programm auf keinen Fall eine Erkennung ein ob das Programmfenster innerhalb des sichtbaren Bildschirms liegt, schließlich ist der User selbst schuld das er den 2. Monitor der bei der letzten Benutzung angeschlossen war diesmal nicht dabei hat!
  7. Stecke 50% des Geldes das du zur Programmierung zur Verfügung hast in das Marketing, Marketing ist schließlich wichtiger als ein fehlerfreies Produkt!
  8. Gestalte niemals eine einfach zu benutzende Oberfläche, es ist für den User viel spannender wenn er alles suchen und rätseln muss ob dies der Knopf ist den er braucht!
  9. Beim jedem Versionssprung deiner Software solltest du sämtliche Bedienelemente im aussehen verändern, an einen anderen Platz setzen und in der Funktionsweise ändern, schließlich zahlt der User ja gutes Geld und soll dafür auch was geboten bekommen!
  10. Solltest du Open Source Software Programmieren: Lass es, User kostenlos zufrieden zu stellen ist Kommunismus!

Wenn du all diese Regeln befolgst ist dir ein vermögen wie das von Bill Gates schon sicher.

You know the dilemma, you want to write a simple tweeting PHP script and have to mess around with the Twitter API.
With the following small script you can tweet with a simple function call. It IS that simple (And SSL secured!!!).

Here’s the function:

function tweet($user, $pass, $text) {
	unset($GLOBALS['tweetError']);
	if(strlen($text) > 140) { $GLOBALS['tweetError'] = 'TEXT TOO LONG: '.$text; return false; }
	$tweet = curl_init();
	curl_setopt($tweet, CURLOPT_URL, 'https://www.twitter.com/statuses/update.xml');
	curl_setopt($tweet, CURLOPT_SSL_VERIFYPEER, 0);
	curl_setopt($tweet, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($tweet, CURLOPT_HTTPHEADER, array('Authorization: Basic '.base64_encode($user.':'.$pass)));
	curl_setopt($tweet, CURLOPT_POST, 1);
	curl_setopt($tweet, CURLOPT_POSTFIELDS, 'status='.utf8_encode($text));
	if(!$return = curl_exec($tweet)) $GLOBALS['tweetError'] = 'CURL ERROR: '.curl_error($tweet);
	else if($returnData = simplexml_load_string($return)) {
		if(!isSet($returnData->error)) $GLOBALS['tweetSuccess'] = 'Created at: '.$returnData->created_at.'Text: '.utf8_decode($returnData->text);
		else $GLOBALS['tweetError'] = 'TWITTER ERROR: '.$returnData->error;
	} else $GLOBALS['tweetError'] = 'RETURN IS NOT XML: '.$return;
	curl_close($tweet);
	return (isSet($GLOBALS['tweetError']))?false:true;
}

To make a tweet just call the function:

tweet("username", "password", "My cool tweet!");

The function returns “true” if successful or “false” if not.
To echo out the error or success messages, just use this code:

if(tweet("username", "password", "My cool tweet!")) {
	echo 'Tweet Successful!'.$GLOBALS['tweetSuccess'];
} else {
	echo 'Tweet Error!'.$GLOBALS['tweetError'];
}

If there was an error, the error description is saved in $GLOBALS['tweetError'], and if the tweet was successful, the time and the text itself is saved in $GLOBALS['tweetSuccess'].

Have fun and happy (automatic?) tweeting.

The most AJAX frameworks are bloated with many functions you’ll never use or need. Who wants 60 KB of JavaScript if your only need is to send and load data? I Don’t.

I have found somewhere a short howto for AJAX, and derived (rewritten) the smallest AJAX framework ever out of it:

var ajax = false;
if(window.XMLHttpRequest) ajax = new XMLHttpRequest();
else if(window.ActiveXObject) {
	try { ajax = new ActiveXObject("Msxml2.XMLHTTP"); }
	catch (e) {
		try { ajax = new ActiveXObject("Microsoft.XMLHTTP"); }
		catch (e) {}
	}
}

function ajaxGetContent(type, url, parameter, output_function) {
	if(!ajax) eval(output_function + '(false);');
	ajax.onreadystatechange = function() {
		if(output_function != 'void' && ajax.readyState == 4) {
			if(ajax.status == 200) eval(output_function + '(ajax.responseText);');
			else eval(output_function + '(false);');
		}
	}
	if(type == "post") {
		ajax.open('POST', url, true);
		ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		ajax.send(parameter);
	} else {
		ajax.open('GET', url + ((parameter.length > 0)?"?":"") + parameter, true);
		ajax.send(null);
	}
}

That’s short, isn’t it?

To get the data you want you have to simply call the function and define a function which will be called after the data arrives:

ajaxGetContent('post', '/myURL/index.php', 'a=b', 'myDataCallBack');

function myDataCallBack(myContent) {
	if(myContent == false) {
		// something went wrong
	} else {
		// have fun with your data
	}
}

And if you want to send data only and don’t care of the answer, use this syntax:

ajaxGetContent('post', '/myURL/index.php', 'a=b', 'void');

Some explanation:
- type = How to send the data (Parameters). “post” or “get”.
- url = Where to send it to.
- parameter = URL-style parameters. Never use a question mark!
- output_function = The function which will be called after the data is received.

This Tool is tested in Opera 9+10, Firefox 2+3 and MSIE 7+8.

Have fun!

When you create a div layer with 100% width and height, the height is always only the height of the browser window, not of the page content (which can be much higher).

To solve this, give the layer div an id and use the following JS code inside the layer div:

<script type="text/javascript">document.getElementById("yourlayerid").style.height = document.getElementsByTagName("body")[0].offsetHeight + "px";</script>

The code is very simple, it gets the height of the content (the body element) and gives it the layer div.

Tested in Opera, Firefox and *barf* MSIE (8).