[ Pobierz całość w formacie PDF ]
., Alameda, CA www.sybex.com2874c19.qxd 7/2/01 4:42 PM Page 837Windows Shell Programming 837If you look at similar examples built in other languages, you ll notice that to access theIPersistFile interface, the programs use custom calls to the QueryInterface method.Thetwo as expressions basically call QueryInterface for us.Once we have the IShellLink interface, we can call some of its methods, such as SetPathand SetWorkingDirectory:// get the name of the application fileFileName := ParamStr (0);// set the link propertiesShLink.SetPath (PChar (FileName));ShLink.SetWorkingDirectory (PChar (ExtractFilePath (FileName)));Once we ve set up the shell link object, we have to save it, depending on the status of thethree check boxes, calling the Save method of the IPersistFile interface of the object.Thesimplest version is the one used to save the link in the current directory:// save the file in the current dirif cbDir.Checked thenbegin// using a WideStringWFileName := ExtractFilePath (FileName) + EditName.Text + .lnk ;PFile.Save (PWChar (WFileName), False);end;The call to the Save method (which creates the physical LNK file) requires a pointer towide char parameter.The simplest way to obtain this is to declare a long string and thencast it to a PWChar.Do not try casting a plain string to PWChar the compiler will emit awarning and the program won t work!To create the shortcut on the desktop or in the Start menu, we should first determine thecorresponding system folder by looking up the proper value in the Registry.By writing theprogram this way, we ensure it will work on different versions of Windows and on localizedversions as well.Here is the source code for the last two check boxes:// save on the desktopif cbDesktop.Checked thenbeginReg := TRegIniFile.Create( Software\MicroSoft\Windows\CurrentVersion\Explorer );WFileName := Reg.ReadString ( Shell Folders , Desktop , ) + \ + EditName.Text + .lnk ;Reg.Free;PFile.Save (PWChar (WFileName), False);end;// save in the Start Menuif cbStartMenu.Checked thenbeginCopyright 2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c19.qxd 7/2/01 4:42 PM Page 838838 Chapter 19 " COM ProgrammingReg := TRegIniFile.Create( Software\MicroSoft\Windows\CurrentVersion\Explorer );WFileName := Reg.ReadString ( Shell Folders , Start Menu , ) + \ + EditName.Text + .lnk ;Reg.Free;PFile.Save (PWChar (WFileName), False);end;To look up the information in the Registry, I ve used the TRegIniFileclass, although there areother related classes in the VCL, such as the TRegistryclass.The effect of running this programand pressing the button is that Windows will add a new link in the directory of the project, onthe desktop, or in the Start menu.You can see an example of the program in Figure 19.5.FI GURE 19.5:The simple user interface ofthe ShCut example, andtwo shortcuts created withit in the project folder andon the desktopUsing Shell APIs and ObjectsAs an extra feature, the program can also add a new document to the list of recently usedones, calling the SHAddToRecentDocs method:procedure TForm1.Button2Click(Sender: TObject);varProjectFile: string;beginProjectFile := ChangeFileExt (ParamStr (0), .dpr );SHAddToRecentDocs (SHARD_PATH, PChar(ProjectFile));end;Copyright 2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c19.qxd 7/2/01 4:42 PM Page 839Windows Shell Programming 839This has very little to do with COM, and I ve added it to the example only to highlightthat there is a very large number of shell-related APIs, available in the ShlObj unit, besidesthe original and more limited ShellApi unit.Another example, available in the source code for this chapter and called FindFolders,highlights the use of another plain (non-COM) shell function, SHBrowseForFolder.In theexample you can see the following code:procedure TForm1.btnBrowseClick(Sender: TObject);varbi: TBrowseInfo;pidl: pItemIdList;strpath, displayname: string;beginSetLength (displayname, 100);bi.hwndOwner := Handle;bi.pidlRoot := nil;bi.pszDisplayName := pChar (displayname);bi.lpszTitle := Select a folder ;bi.ulFlags := bif_StatusText;bi.lpfn := nil;bi.lParam := 0;pidl := SHBrowseForFolder (bi);SetLength (strPath, 100);SHGetPathFromIdList (pidl, PChar(strPath));Edit1.Text := strPath;end;The FindFolders example even shows some Delphi-specific APIs to interact with files andfolders (available also on Linux) including SelectDirectory, which has the same effect ofSHBrowseForFolderbut a different user interface.The example also uses the DirectoryExistsand ForceDirectoriesfunctions, available in the FileCtrl unit.You can see how they are usedby looking in the source code of the example.NOTENotice that in Delphi 6, some of the Shell API is also encapsulated in the sample ShellListView,ShellTreeView, and ShellComboBox controls.I ve used these controls in a few examplesthroughout the book, including the DirDemo example of Chapter 18, Writing DatabaseComponents.Copyright 2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c19.qxd 7/2/01 4:42 PM Page 840840 Chapter 19 " COM ProgrammingThe To-Do File ApplicationAs a second example of integrating a Delphi program with the system shell, I ve tried to writea simple real-world application that uses file dragging and a context menu handler.I ll startwith the file dragging first, because this will actually introduce some of the techniques usedby the context menu handler.As I mentioned, this application is actually useful; you can use it to create a sort of to-dolist. It is based on a Paradox table that stores filenames and notes about the files.The formof the application has a DBGrid component showing only a single column containing thefilenames and a memo control hosting the notes related to the current file.You can see thisform at design time in Figure 19.6.FI GURE 19.6:The form of the ToDoFileexample at design timeTIPUsing a single-column DBGrid is the only way in Delphi to show a list of the available records ina list-box format.The alternative, of course, is to fill a list box with custom code and then man-ually navigate in the database table when the selection in the list box changes.This manualapproach is, of course, less efficient when we have many records, because the program needsto scan them all to fill the list box, while the DBGrid loads only the record it currently displays.Notice that the navigator component has no New Record button, and the DBGrid is setup as a read-only component.In fact, users should not be able to create new records exceptby dragging a file onto the form, and they re not allowed to change the filename field in anyway (except by deleting it).All the user can do is edit the notes field, entering a description ofthe operations to be done on the file.Copyright 2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c19
[ Pobierz całość w formacie PDF ]