Computing: Free Pascal Programming

Opening associated files in a Free Pascal application.


Windows file association associates given file types (given file extensions) to a given application. This means, that if you double-click a file with these extensions, the associated application opens and the double-clicked file is automatically processed. Examples: Supposing Windows default applications, double-clicking a .txt file opens this file for editing in Notepad, double-clicking a .mp3 file plays this file in Windows Music, having selected to do file associations when installing the Lazarus IDE, double-clicking a .lpi, .lpr, or .pas file opens Lazarus with the project or source file loaded. You can easily associate a custom file type with a Free Pascal application, that you developed yourself, by right-clicking the file, choosing Open, browsing to your application and selecting to always use this application for this file type. You can also use my WinFileAssociation application to do so.

As an example, consider my Flag quiz application. The quiz data (set of countries, used in a given quiz) is stored in files, that I gave the extension .fqz. You can associate .fqz files with the FlagQuiz application as described above, or doing it from within the application. If done so, double-clicking a .fqz file, runs the FlagQuiz program, but how to do, in the Free Pascal source code, to automatically use the file, that has been double-clicked?

Similar to command line programs, there are parameters passed to a GUI application, when running it. And similar to command line programs, we can use the Free Pascal functions ParamCount and ParamStr to read the parameter(s) passed. Double-clicking a file passes the path of this file as first parameter to the associated application. So, if ParamCount = 1, we can use ParamStr(1) to retrieve the name of the .fqz file to be opened.

The following code checks if there is actually a parameter passed. If yes, the application uses the corresponding .fqz file, otherwise it uses a default quiz file (located in the /quiz subdirectory of the folder, containing the executable).

// Application launched by double-click of a .fqz file
if ParamCount = 1 then begin
    // Flag file path is passed as 1st parameter
    sQuizDir := ExtractFileDir(ParamStr(1));
    FileName := ExtractFileName(ParamStr(1));
end
// Application launched by double-click of the executable
else begin
    // Flag file path is default quiz
    sQuizDir := GetCurrentDir + '/quiz'; DoDirSeparators(sQuizDir);
    FileName := 'europe_sel.fqz';
end;


This normally works fine. But what, if we need other data files, located in the program folder or a subdirectory of the program folder? In the code above, we used GetCurrentDir to retrieve the path of the default .fqz file, but can we use this function to retrieve the flag images, located in the /flags subdirectory of the folder, containing the executable? The answer is NO! Or, at least, not necessarily. In the case, where the application is launched by double-clicking the executable, there is no problem, but if it is launched by double-clicking a .fqz file, located for example in the /quiz folder, the program would not find the flag image files. Do you see why? Because, when double-clicking the .fqz file, your current directory is ProgramDirectory/quiz and constructing a flag image path by setting it to GetCurrentDir + '/flags' would give ProgramDirectory/quiz/flags (instead of ProgramDirectory/flags)! There is a simple work-around. In fact, the ParamStr function may be called with argument 0. This does not return a program parameter (thus does not affect ParamCount), but ParamStr(0) always returns the path of the executed program itself.

Here the code, as I use it in my FlagQuiz application, the included .fqz files being located in the /quiz subdirectory of the program folder and the flag images in its /flags subdirectory (and custom .fqz files may be stored wherever you want):

sProgDir := ExtractFileDir(ParamStr(0));
// Application launched by double-click of a .fqz file
if ParamCount = 1 then begin
    // Flag file path is passed as 1st parameter
    sQuizDir := ExtractFileDir(ParamStr(1));
    FileName := ExtractFileName(ParamStr(1));
end
// Application launched by double-click of the executable
else begin
    // Flag file path is default quiz
    sQuizDir := sProgDir + '/quiz'; DoDirSeparators(sQuizDir);
    FileName := 'europe_sel.fqz';
end;
sFlagsDir := sProgDir + '/flags'; DoDirSeparators(sFlagsDir);
NewQuiz(sQuizDir, sFlagsDir, FileName, iFlags, sTitleEN, sTitleDE, aFlags);



If you find this text helpful, please, support me and this website by signing my guestbook.