Mega Code Archive

 
Categories / Delphi / Examples
 

Searching for favourites

Uses TSearchRec to loop through the Explorer favourites, which really are inifiles. Result is beeing placed in HTML and text files. NOTE: This article is a couple of years old. And while the code still works fine as an example of using inifiles and recursive searches - Internet Explorer has had export possibilities built into the program. ** Collecting Explorer Favourites Johan Lindgren Recently a person at work was leaving for another company. Beeing a journalist, she was very interested in bringing the long list of favourite internet links that she had collected during her time with us. This is really a valueble journalistic tool these days. Well, if she were going to a company also equiped with Windows and Explorer you could simply copy the folder holding the favourites. But since she was going to a MAC-based company using Netscape it was a different situation. There might be a way in Explorer to do this. And there might be programs out there doing this. But I found none so I did a program to do it. What the program does is simply recursively search the folder with the Explorer favourites and adding it all to a textfile and a HTML-file. The big advantage with storing the result in the HTML-format is that you can make the links active and thus the file useful in any browser. First of all there is an ini-file with settings for the searchpath to the favourites and the searchpath and names of the files where the result is to be stored. The file is named "favoriter.ini" and is placed in the same folder as the exe-file. (Some words you encounter are in Swedish!) The inifile: [Favoriter] WindowsFavoriter=c:\windows\favoriter\ HTMLsave=c:\favoriter.html TEXTsave=c:\favoriter.txt It is important to get the search path right for the program to work. The program consist of a richedit to hold the text result, a button to start, a button to close and a status bar. (Which is not necessary at all.) The operation is pretty straight forward. When you click the start button the code attached to that button is executed. The search starts and if a subfolder is encountered a separate procedure is called. This procedure is recalled for each subfolder encountered. So the program will search out every subfolder. This is search block from the click event. The routine in the procedure is very similar. (See the complete program listing.) test := FindFirst(sokmapp+'*.*', faAnyFile, SearchRec); //See if we get any result from our first search if test = 0 then //if we got a result. Indicated by a 0 in the FindFirst function!! while test = 0 do begin //As long as we get 0's from our Searches there are more files or folders to process case searchrec.Attr of //Check to see what attribute the searchresult had 16 : begin //If it was a 16 it is a sub folder if (searchrec.name <> '.') and (searchrec.name <> '..') then //Check to see that it is not a . or a .. which are symbols for the folder above and the same folder SokIEnMapp (sender,sokmapp+'\'+searchrec.name,searchrec.name); //If it was another folder, call a subroutine to investigate that folder end; 32 : begin //If it was a 32 it is a file if ansilowercase(extractfileext(searchrec.name)) = '.url' then begin //if the file name ends with .url it is an explorer favourite inifil := tinifile.create (sokmapp+searchrec.name); //Create an inifile object for this file try temptext :=inifil.readstring ('InternetShortcut','URL',''); //Read the actual link from the file richedit1.Lines.Add (stringreplace(searchrec.name,extractfileext(searchrec.name),'')+'='+temptext);//Show the file name and the link in the richedit statusbar1.SimpleText := searchrec.name; //Show the filename in the status bar statusbar1.Update; //Update the status bar application.processmessages; //And give windows a chance to catch up grunder.Add ('<li><a href="'+temptext+'">'+stringreplace(searchrec.name,extractfileext(searchrec.name),'')+'</a></li>'); //Add the favourite to our temporary stringlist finally inifil.Free; //Free the inifile object end; end; end; end; test := findnext(searchrec); //Call findnext to see if there are more files or folders end; findclose(searchrec); //Release the search object The resulting HTML-file contains the name of the link and the actual link in a <A href= tag which makes the file useful. ... Johan Lindgren is an ex-journalist, now working with technical development for the Swedish News Agency (Tidningarnas Telegrambyrå). It involves work with SGML, XML and XSL. He uses Delphi to produce the various pieces of software that is needed. He can be reached at johan.lindgren@tt.se Sourcecode: unit favvo; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls,inifiles, ExtCtrls; type Tfavu = class(TForm) RichEdit1: TRichEdit; Panel1: TPanel; startsearch: TButton; StatusBar1: TStatusBar; Button1: TButton; procedure startsearchClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure SokIEnMapp (sender : Tobject;sokpath,katalog : string); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } SearchRec: TSearchRec; //The overall search object sokmapp, htmlut, textut : string; //Strings for holding the folder to search and the files for the search results htmlspar : tstringlist; //String list to hold the HTML file end; function KollaSlutet (rad,slut : string) : string; function StringReplace (text,byt,mot : string ) :string; var favu: Tfavu; implementation {$R *.DFM} //======= When program is launched ========// procedure Tfavu.FormCreate(Sender: TObject); var inifil : TIniFile; //Inifile-object to read user preferences exepath : string; //Searchpath for the application begin exepath := extractfilepath (application.exename); //Extract the searchpath for the application exepath := kollaslutet(exepath,'\'); //Call a function that checks that the first string ends with the second string inifil := tinifile.create(exepath+'favoriter.ini'); //Create the inifile object with the exepath combined with the inifile name. try sokmapp := inifil.readstring('Favoriter','WindowsFavoriter','c:\windows\favoriter\'); //Get the searchpath for the folder containing the explorer favourites sokmapp := kollaslutet(sokmapp,'\'); //Call the routine "kollaslutet" to make sure that the string ends with a \ htmlut := inifil.readstring('Favoriter','HTMLsave','c:\favoriter.html'); //Get the name and path to the file where the html result is to be stored textut := inifil.readstring('Favoriter','TEXTsave','c:\favoriter.txt'); //Get the name and the path to the file where the text result is to be stored finally inifil.free; //Free the resources for the inifile object end; htmlspar := tstringlist.create; //Create the stringlist to hold the HTML result end; //====== Clicking the button to start collecting the favourites ========// procedure Tfavu.startsearchClick(Sender: TObject); var inifil : TIniFile; //Inifile object to get the content of the favourites temptext : string; //Temporary string for storing test : integer; //Integer for checking the search results grunder : TStringList; //STring list to hold searchresult from one folder begin screen.cursor := crHourglass; //Show the hourglass to let the user know we're busy grunder := TStringList.create; //Create the stringlist htmlspar.add ('<html><head><title>Internet Favourites</title></head><body>');//Set up the first HTML elements in that stringlist try test := FindFirst(sokmapp+'*.*', faAnyFile, SearchRec); //See if we get any result from our first search if test = 0 then //if we got a result. Indicated by a 0 in the FindFirst function!! while test = 0 do begin //As long as we get 0's from our Searches there are more files or folders to process case searchrec.Attr of //Check to see what attribute the searchresult had faDirectory : begin //If it was a 16 it is a sub folder if (searchrec.name <> '.') and (searchrec.name <> '..') then //Check to see that it is not a . or a .. which are symbols for the folder above and the same folder SokIEnMapp (sender,sokmapp+'\'+searchrec.name,searchrec.name); //If it was another folder, call a subroutine to investigate that folder end; 32 : begin //If it was a 32 it is a file if ansilowercase(extractfileext(searchrec.name)) = '.url' then begin //if the file name ends with .url it is an explorer favourite inifil := tinifile.create (sokmapp+searchrec.name); //Create an inifile object for this file try temptext :=inifil.readstring ('InternetShortcut','URL',''); //Read the actual link from the file richedit1.Lines.Add (stringreplace(searchrec.name,extractfileext(searchrec.name),'')+'='+temptext);//Show the file name and the link in the richedit statusbar1.SimpleText := searchrec.name; //Show the filename in the status bar statusbar1.Update; //Update the status bar application.processmessages; //And give windows a chance to catch up grunder.Add ('<li><a href="'+temptext+'">'+stringreplace(searchrec.name,extractfileext(searchrec.name),'')+'</a></li>'); //Add the favourite to our temporary stringlist finally inifil.Free; //Free the inifile object end; //try finally end; //if .url end;//case 32 end; //case test := findnext(searchrec); //Call findnext to see if there are more files or folders end; //while findclose(searchrec); //Release the search object htmlspar.Text := htmlspar.text + '<b>Various links</b><ul>'+grunder.text+'</ul>';//Add to the HTML stringlist a header line and the results from this folder htmlspar.add ('</body></html>'); //Finally add the closing HTML elements htmlspar.SaveToFile (htmlut); //Save the HTML stringlist to the designated name richedit1.lines.SaveToFile (textut); //Save the lines of the richedit to the designated file. Make sure to have plaintext=true in the richedit finally grunder.free; //Free the stringlist screen.cursor := crDefault; //Restore the cursor end; end; //======= Procedure to search in a specific folder =====// procedure Tfavu.SokIEnMapp (sender : Tobject;sokpath,katalog : string); var undermapp : tsearchrec; //Searchresult for this specific folder inifil : tinifile; //Inifile to read content from url-files temptext : string; //Temporary string test2 : integer; //Integer to see what search result we got begin richedit1.lines.add (katalog); //Start by adding the name of the folder to be searched to the richedit statusbar1.SimpleText := katalog; //Do the same with the status bar statusbar1.Update; //Update the status bar application.processmessages; //Make sure windows get's a chance htmlspar.add (' <b>'+katalog+'</b><ul>'); //Add the name of the folder to the HTML string list test2 := findfirst(sokpath+'\*.*',faAnyFile,Undermapp); //Start a search in the sub folder if test2 = 0 then //If we get a 0 we scored a hit while test2 = 0 do begin //As long as we keep finding new folders or files case undermapp.attr of //Check the attribute of the search result 16 : begin //If it was a 16 it is a subfolder if (undermapp.name <> '.') and (undermapp.name <> '..') then //As long as the name is not . or .. we continue our search SokIEnMapp (sender,sokpath+'\'+undermapp.name,undermapp.name); //Call the same routine to keep searching subfolders end; //16 32 : begin //32 means a file if ansilowercase(extractfileext(undermapp.name)) = '.url' then begin //If the filename ends with .url it is an explorer favourite inifil := tinifile.create (sokpath+'\'+undermapp.name); //Create an inifile object for this file try temptext :=inifil.readstring ('InternetShortcut','URL',''); //Read the link in the file richedit1.Lines.Add (stringreplace(undermapp.name,extractfileext(undermapp.name),'')+'='+temptext); //Add this to the richedit statusbar1.SimpleText := undermapp.name; //Show the name of the file in the status bar statusbar1.Update; //Update the status bar application.processmessages; //Let windows do it's business htmlspar.Add ('<li><a href="'+temptext+'">'+stringreplace(undermapp.name,extractfileext(undermapp.name),'')+'</a></li>');//Add the filename and the link to the HTML stringlist finally inifil.Free; //free the inifile object end; //try end; //if end; //32 end; test2 := findnext (undermapp); //call find next to keep searching end; //while htmlspar.add ('</ul>'); //Add a closing tag to the html string list findclose (undermapp); //Call find close to close the search object end; //======== When closing the program ==========// procedure Tfavu.Button1Click(Sender: TObject); begin close; //Close the application end; procedure Tfavu.FormDestroy(Sender: TObject); begin htmlspar.free; //Free the resourse for the html string list end; //================ Functions ==============// //========== Check that a string ends with a specific string =============// function KollaSlutet (rad,slut : string) : string; begin if length(rad)>0 then //Make sure theres something there to check if rad[length(rad)] <> slut then rad := rad+slut;//If it does not end with the proper ending - add it result := rad; //Return the string end; //========== Function to change the first occurance of byt against mot in text ===========// function StringReplace (text,byt,mot : string ) :string; var plats : integer; begin if pos(byt,text) > 0 then begin //if byt exist in text plats := pos(byt,text); //Note where it is delete (text,plats,length(byt)); //Remove the part matching byt insert (mot,text,plats); //insert mot in the proper place end; //if byt existed in text result := text; //in any case return the text end; end