Tuesday, October 31, 2006

Double-click

To learn and to practise what is learned
time and again is pleasure, is it not?

To have friends come from afar (to share learning)
is happiness, is it not?

To be unperturbed when not appreciated by
others is gentlemanly, is it not?

--- K'UNG-FU-TZU, Lun Yu (circa 500 BC)


Do you know that there exists a mouse with double-click button? If you don't, now you know!

What happens when you double-click on the file (or shortcut) in Windows operating system (OS)? Based on the file extension (usually 2, 3 or 4 letters after the last dot in the file name) OS determines its file type and then executes an application that can open (display) selected file. BTW, this is the default behaviour - you can set that this action is triggered by single-click:


We've already seen that using doknir it is possible to open (view) files with the extension .PS or .DJVU. Wouldn't it be nice to open such files directly using double-click? Well, after first two steps it is not difficult to make the third step: We will write a simple Delphi executable (called "doknir launcher") that will, when executed by double-click on a file, copy that file to the incoming folder. The source follows:

We need three functions: to get "My documents" folder (because there is our incoming folder), to get the file size and to copy file:
---

function GetMyDocuments: string;
var
Res: Bool;
Path: array[0..Max_Path] of Char;
begin
Res := ShGetSpecialFolderPath(0, Path, csidl_Personal, False);
if not Res then raise
Exception.Create('Could not determine My Documents path');
Result := Path;
end; // GetMyDocuments
...
function GetFSize(cFile: string): Int64;
var
fs: TFileStream;
begin
fs:=NIL;
result:=-1;
try
fs:=TFileStream.Create(cFile,
fmOpenRead+fmShareDenyNone);
result:=fs.Size;
finally
fs.Free;
end;
end; // GetFSize
...
function FileCopy(cF, cT: string):integer;
begin
CopyFile( PChar(cF), PChar(cT), FALSE );
result:=0;
end; // F
ileCopy
---
I could use OnCreate event to copy file, but I prefer timer (I named it Launcher) because it gives me more flexibility:
---
 procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Caption:=CmdLine;
Label2.Caption:=ParamStr(1);
cFileDok:=ParamStr(1);
cMyDok:=GetMyDocuments()+'/[_doknir_]';
cPhase:='WAIT';
Launcher.Enabled:=TRUE; // enable timer
end; // FormCreate
...
procedure TForm1.LauncherTimer(Sender: TObject);
var
nSize: integer;
cTo: string;
begin
Launcher.Enabled:=FALSE;
if cFileDok='' then begin Close; Exit end;
if not FileExists(cFileDok) then begin
ShowMessage('File not accessible!');
Close; Exit;
end;
cPhase:='LAUNCH';
nSize:=GetFSize(cFileDok);
if nSize<0>
ShowMessage('Error<0');
end else if nSize=0 then begin
ShowMessage('Error=0');
end else begin // nSize>0
try
cTo:=cMyDok+'\'+ExtractFileName(cFileDok);
FileCopy(cFileDok, cTo);
except
ShowMessage('Error copy: '+cFileDok);
end;
end;
Close;
end; //LauncherTimer
---

Now we will try to "teach" Windows how to open files using our new "doknir launcher". First we have to find a file that we wish to view in doknir (for example PDF file). Press [Shift] and right-click on it. There should be "Open with ..." option visible in the pop-up menu - select it. The following dialog appears:

Click on button [Browse...] to select newly created "doknir launcher" executable, check "Alway use the selected program to open this kind of file" and press OK. This means that from now on whenever we will double-click on PDF file, it will be displayed in doknir. We can repeat above steps for other file types. For example, I've associated 'doknir launcher' to the following file extensions: .PDF, .PS, .DJVU and .SXW. Nice, is it not?

[]