Thursday, June 30, 2005

Last Day at Agni

It's my last day at Agni Software. It's been a remarkable 7 years here, and I've had a lot of fun and learning at Agni. I was a tinhorn when I started, and I'm a little less of one now - I don't file notches on my guns, but I haven't learnt to shoot any better. (They keep moving the targets!)

Arun and Chirag, my co-founders, will continue to grow Agni, and I wish them and everyone at Agni the very best for the brightest possible future. We're all very good friends, and I'm sure there's going to be a lot of getting together for coffee. (they're teetotallers, so beer is out) (No, that's not why I'm leaving! :) )

I'll be around on the blog scene, and I'll tell you all about my new job. Tomorrow.

Skype - and how to use it in Delphi

Skype has a public API, and it's almost impossible to find. Actually there's no specific file for the API - Skype itself responds to calls using WM_COPYDATA. It'll also send you notifications - stuff that you must handle in your form's Message Handler.

Ok, this isn't that simple to explain. Check out a sample Skype Tracer that I've developed, and it's available at: Let me know what you think...

Sunday, June 26, 2005

.Text Comment Spam

I got hit recently with a lot of Comment Spam on my TeamB blog. It was incredibly boring to sit and delete all of the spam comments - which, because of what I would only call laziness, had grown to around 500 in number - since .Text only allows you to delete one comment at a time! And each time it would bring up a confirmation web page from the server, and then, when you select "Yes, I know what I'm doing, just delete the darn message" it throws up another page with "Message Deleted" or something like that. You have to then click once more to get back to the message list. Note: I don't have access to the database.

Obviously this could be rectified by changing some code. The .Text source is available - so maybe it could be modified.

I downloaded the .Text source and then managed to actually get it compiled and running on my laptop. What I started to do was to check how the code worked - and it turns out there's a way to enter "comments" by creating a "trackback" to your page. I'm not going to reveal how - but the source code of the page reveals all.

Solution: Simply remove trackbacks from your page. Let people actually enter the trackback in, as a comment. And introduce a CAPTCHA in the comment entry page.

The CAPTCHA solution is fairly well documented. You can downloadThe Clearscreen CAPTCHA control for .Text by Miguel Jiminez and install/run it.

For removing trackbacks: Go to your web.config on your .Text site and remove the lines starting with <HttpHandler and that contain the text pingback or trackback. Or set enableTrackBacks="false" and enablePingBacks="false" in the <Tracking element.

No trackbacks then? Maybe the comment api can be modified to allow it as a different field - I don't think I'll have time to do this, but if anyone has, please let me know.

Friday, June 17, 2005

Setting Focus with MessageDlg

One of the things I've had to do manually many times is to have dialog boxes pop up, but logically "OK" should not be the focussed button. (Like "Do you want to format this disk?")

In Delphi, you'd usually call MessageDlg for a dialog that had a Yes/No/Cancel or an Ok/Cancel input only - but that doesn't give you a way to change the focus or default button. So here's how you would do it - call MessageDlgFocus instead:

ButtonNames: array[TMsgDlgBtn] of string = (
'Yes', 'No', 'OK', 'Cancel', 'Abort', 'Retry', 'Ignore',
'All', 'NoToAll', 'YesToAll', 'Help');

function MessageDlgWithFocus(const Msg: string;
DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons;
FocusBtn: TMsgDlgBtn;
HelpCtx: Longint): Integer;
var Btn: TComponent;
with CreateMessageDialog(Msg, DlgType, Buttons) do
HelpContext := HelpCtx;
Position := poScreenCenter;

Btn := FindComponent( ButtonNames[FocusBtn] );
if (Btn <> nil) and (Btn is TWinControl) then
ActiveControl := Btn as TWinControl;

Result := ShowModal;

Call it with:

MessageDlgWithFocus('test', mtCOnfirmation,
[mbOk, mbCancel], mbCancel, 0);

This code will bring up a dialog with OK and Cancel buttons, and the Cancel button is focussed.