home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 September
/
Chip_2001-09_cd1.bin
/
zkuste
/
delphi
/
kolekce
/
d123456
/
DFS.ZIP
/
pidlhelp.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1999-02-23
|
15KB
|
408 lines
{$I DFS.INC} { Standard defines for all Delphi Free Stuff components }
{ -----------------------------------------------------------------------------}
{ PidlHelp Unit v1.00 }
{ -----------------------------------------------------------------------------}
{ System Control Pack helper unit. Lots of utility functions for working with }
{ PItemIDList variables. }
{ }
{ Copyright 1999, Brad Stowers. All Rights Reserved. }
{ }
{ Copyright: }
{ All Delphi Free Stuff (hereafter "DFS") source code is copyrighted by }
{ Bradley D. Stowers (hereafter "author"), and shall remain the exclusive }
{ property of the author. }
{ }
{ Distribution Rights: }
{ You are granted a non-exlusive, royalty-free right to produce and distribute }
{ compiled binary files (executables, DLLs, etc.) that are built with any of }
{ the DFS source code unless specifically stated otherwise. }
{ You are further granted permission to redistribute any of the DFS source }
{ code in source code form, provided that the original archive as found on the }
{ DFS web site (http://www.delphifreestuff.com) is distributed unmodified. For }
{ example, if you create a descendant of TDFSColorButton, you must include in }
{ the distribution package the colorbtn.zip file in the exact form that you }
{ downloaded it from http://www.delphifreestuff.com/mine/files/colorbtn.zip. }
{ }
{ Restrictions: }
{ Without the express written consent of the author, you may not: }
{ * Distribute modified versions of any DFS source code by itself. You must }
{ include the original archive as you found it at the DFS site. }
{ * Sell or lease any portion of DFS source code. You are, of course, free }
{ to sell any of your own original code that works with, enhances, etc. }
{ DFS source code. }
{ * Distribute DFS source code for profit. }
{ }
{ Warranty: }
{ There is absolutely no warranty of any kind whatsoever with any of the DFS }
{ source code (hereafter "software"). The software is provided to you "AS-IS", }
{ and all risks and losses associated with it's use are assumed by you. In no }
{ event shall the author of the softare, Bradley D. Stowers, be held }
{ accountable for any damages or losses that may occur from use or misuse of }
{ the software. }
{ }
{ Support: }
{ All DFS source code is provided free of charge. As such, I can not guarantee }
{ any support whatsoever. While I do try to answer all questions that I }
{ receive, and address all problems that are reported to me, you must }
{ understand that I simply can not guarantee that this will always be so. }
{ }
{ Clarifications: }
{ If you need any further information, please feel free to contact me directly.}
{ This agreement can be found online at my site in the "Miscellaneous" section.}
{------------------------------------------------------------------------------}
{ Feel free to contact me if you have any questions, comments or suggestions }
{ at bstowers@pobox.com. }
{ The lateset version of my components are always available on the web at: }
{ http://www.delphifreestuff.com/ }
{ See SCP.txt for notes, known issues, and revision history. }
{ -----------------------------------------------------------------------------}
{ Date last modified: February 23, 1999 }
{ -----------------------------------------------------------------------------}
unit PidlHelp;
interface
uses
{$IFDEF DFS_COMPILER_3_UP}
ShlObj, ActiveX,
{$ELSE}
MyShlObj, OLE2,
{$ENDIF}
Windows;
type
// These map to the SHGDN_xxx constants. uses in GetDisplayName function.
TDisplayNameType = (dntNormal, dntInFolder, dntForParsing);
// Create a new, empty PIDL of the given size. Mostly useful only for the other
// helpers like CopyPIDL and ConcatPIDLs. Result must be released with FreePIDL
function CreatePIDL(Size: UINT): PItemIDList;
// Release the system memory associated with the PIDL. Checks for NIL first.
procedure FreePIDL(var AnID: PItemIDList);
// Returns how much memory the PIDL uses.
function GetPidlSize(pidl: PItemIDList): integer;
// Create a new PIDL by adding ID2 onto the end of ID1. Result must be Free
// with FreePIDL.
function ConcatPIDLs(ID1, ID2: PItemIDList): PItemIDList;
// Create a new PItemIDList from an existing one. Result must be released with
// FreePIDL.
function CopyPIDL(AnID: PItemIDList): PItemIDList;
// Compare two PIDLs to see if they are the same.
function ComparePIDLs(ID1, ID2: PItemIDList): boolean;
// Returns to the next ID in the given list of IDs. The return value is only a
// pointer into the real PIDL, so don't free it or rely on it if the list is
// released.
function NextPIDL(PIDL: PItemIDList): PItemIDList;
// Returns the number of IDs in the ID list.
function PIDLCount(PIDL: PItemIDList): integer;
// Create copy of the current (first) ID from the ID list. This is used to
// create a relative PIDL from part of a fully qualified PIDL. The result must
// be released with FreePIDL.
function CopyFirstID(AnID: PItemIDList): PItemIDList;
// Create a copy of the last ID in the ID list. This is used to create a
// relative PIDL from part of a fully qualified PIDL. The result must be
// released with FreePIDL.
function CopyLastID(IDList: PItemIDList): PItemIDList;
// Create a new PIDL that contains all IDs except for the last. The result must
// be released with FreePIDL.
function CopyParentPIDL(var IDList: PItemIDList): PItemIDList;
// Return the "display name" for a PIDL. This is the string that Explorer shows
// to the user, and it changes based on user settings. For example, for a file
// name the extension may or may not be shown based on the user's preferences.
function GetDisplayName(const ShellFolder: IShellFolder; IDList: PItemIDList;
NameType: TDisplayNameType): string;
// Get a PItemIDList that represents the given pathname. The var ID parameter
// must be released with FreePIDL.
function GetPIDLFromPath(Handle: HWND; const ShellFolder: IShellFolder;
const APath: string; var ID: PItemIDList): boolean;
// Get the image index of the PIDL in the system image list. Use this only for
// fully qualified PIDLs. Relative won't work.
function GetIconIndex(IDList: PItemIDList; Flags: UINT): integer;
// Get the image index of the PIDL in the system image list for normal and
// selected icons. Use this only for fully qualified PIDLs. Relative won't
// work.
procedure GetNormalAndSelectedIcons(IDList: PItemIDList; var Normal,
Selected: integer);
var
// Used throught this unit. It's a shared thing provided by the system, so
// this variable can be used whereever you might need it. It's created in
// the unit initialization and released in finalization.
ShellMalloc: IMalloc;
implementation
uses
ShellAPI;
function GetPidlSize(pidl: PItemIDList): integer;
begin
Result := 0;
if pidl <> NIL then
begin
Inc(Result, SizeOf(pidl^.mkid.cb));
while pidl^.mkid.cb <> 0 do
begin
Inc(Result, pidl^.mkid.cb);
Inc(longint(pidl), pidl^.mkid.cb);
end;
end;
end;
function CreatePIDL(Size: UINT): PItemIDList;
begin
Result := ShellMalloc.Alloc(Size);
if Result <> NIL then
FillChar(Result^, Size, #0);
end;
procedure FreePIDL(var AnID: PItemIDList);
begin
if AnID <> NIL then
begin
ShellMalloc.Free(AnID);
AnID := NIL;
end;
end;
function ConcatPIDLs(ID1, ID2: PItemIDList): PItemIDList;
var
S1, S2: UINT;
begin
if (ID1 <> NIL) then
S1 := GetPIDLSize(ID1) - SizeOf(ID1.mkid.cb)
else
S1 := 0;
S2 := GetPIDLSize(ID2);
Result := CreatePIDL(S1 + S2);
if Result <> NIL then
begin
if (ID1 <> NIL) then
Move(ID1^, Result^, S1);
Move(ID2^, PChar(Result)[S1], S2);
end;
end;
// Create a new PItemIDList from existing. Call responsible for freeing it.
function CopyPIDL(AnID: PItemIDList): PItemIDList;
var
Size: integer;
begin
Size := GetPidlSize(AnID);
if Size > 0 then
begin
Result := ShellMalloc.Alloc(Size); // Create the memory
FillChar(Result^, Size, #0); // Initialize the memory to zero
Move(AnID^, Result^, Size); // Copy the current ID
end else
Result := NIL;
end;
function ComparePIDLs(ID1, ID2: PItemIDList): boolean;
var
S1, S2, x: UINT;
begin
Result := FALSE;
if (ID1 = NIL) and (ID2 = NIL) then
begin
Result := TRUE;
exit;
end;
if (ID1 = NIL) or (ID2 = NIL) then exit;
S1 := GetPIDLSize(ID1);
S2 := GetPIDLSize(ID2);
if S1 <> S2 then exit;
Result := TRUE;
for x := 0 to pred(S1) do
begin
if PChar(ID1)[x] <> PChar(ID2)[x] then
begin
Result := FALSE;
exit;
end;
end;
end;
// Returns to the next ID in the given list of IDs
function NextPIDL(PIDL: PItemIDList): PItemIDList;
begin
if PIDL.mkid.cb > 0 then
Result := PItemIDList(Longint(PIDL) + PIDL.mkid.cb)
else // At end of list.
Result := NIL;
end;
// Returns the number of IDs in the ID list.
function PIDLCount(PIDL: PItemIDList): integer;
begin
Result := 0;
if PIDL <> NIL then
begin
while PIDL.mkid.cb > 0 do
begin
PIDL := NextPIDL(PIDL);
inc(Result);
end;
end;
end;
// Create copy of the current ID from the ID list. This is used to create a
// relative PIDL from part of a fully qualified PIDL.
function CopyFirstID(AnID: PItemIDList): PItemIDList;
var
Size: integer;
begin
// How much memory do we need? Note that this allocates enough memory for
// the current ID, plus enough for the mkid.cb member of another one. The
// extra is used as the "termintor" of the PIDL. It is set to zero in the
// FillChar below.
Size := AnID.mkid.cb + SizeOf(AnID.mkid.cb);
Result := ShellMalloc.Alloc(Size); // Create the memory
if Result = NIL then exit; // If the shell couldn't allocate memory, get out
FillChar(Result^, Size, #0); // Initialize the memory to zero
Move(AnID^, Result^, AnID.mkid.cb); // Copy the current ID
end;
function CopyLastID(IDList: PItemIDList): PItemIDList;
var
MarkerID: PItemIDList;
begin
Result := NIL;
MarkerID := IDList;
if IDList <> NIL then
begin
while IDList.mkid.cb <> 0 do
begin
MarkerID := IDList;
IDList := NextPIDL(IDList);
end;
Result := CopyPIDL(MarkerID);
end;
end;
function CopyParentPIDL(var IDList: PItemIDList): PItemIDList;
var
Last, Size: integer;
Source: PItemIDList;
begin
Size := 0;
Last := 0;
if IDList <> NIL then
begin
Source := IDList;
Inc(Size, SizeOf(Source^.mkid.cb));
while Source^.mkid.cb <> 0 do
begin
Last := Source^.mkid.cb;
Inc(Size, Source^.mkid.cb);
Inc(Longint(Source), Source^.mkid.cb);
end;
Dec(Size, Last);
end;
if Size > 0 then
begin
Result := ShellMalloc.Alloc(Size); // Create the memory
FillChar(Result^, Size, #0); // Initialize the memory to zero
Move(IDList^, Result^, Size - SizeOf(Source^.mkid.cb)); // Copy the current ID
end else
Result := NIL;
end;
function GetDisplayName(const ShellFolder: IShellFolder; IDList: PItemIDList;
NameType: TDisplayNameType): string;
const
NAMETYPEAPI: array[TDisplayNameType] of DWORD = (SHGDN_NORMAL, SHGDN_INFOLDER,
SHGDN_FORPARSING);
var
Str: TStrRet;
begin
if ShellFolder.GetDisplayNameOf(IDList, NAMETYPEAPI[NameType],
Str) = NOERROR then
begin
case Str.uType of
STRRET_WSTR: Result := WideCharToString(Str.pOleStr);
STRRET_OFFSET: Result := PChar(UINT(IDList) + Str.uOffset);
STRRET_CSTR: Result := Str.cStr;
else
Result := '';
end;
end else
Result := '';
end;
function GetPIDLFromPath(Handle: HWND; const ShellFolder: IShellFolder;
const APath: string; var ID: PItemIDList): boolean;
var
OLEStr: array[0..MAX_PATH] of TOLEChar;
Eaten: ULONG;
Attr: ULONG;
begin
try
Result := Succeeded(ShellFolder.ParseDisplayName(Handle, NIL,
StringToWideChar(APath, OLEStr, MAX_PATH), Eaten, ID, Attr));
except
Result := FALSE;
end;
end;
// Use this only for fully qualified PIDLs. Relative won't work.
function GetIconIndex(IDList: PItemIDList; Flags: UINT): integer;
var
SFI: TSHFileInfo;
begin
if SHGetFileInfo(PChar(IDList), 0, SFI, SizeOf(TSHFileInfo), Flags) = 0 then
Result := -1
else
Result := SFI.iIcon;
end;
// Use this only for fully qualified PIDLs. Relative won't work.
procedure GetNormalAndSelectedIcons(IDList: PItemIDList; var Normal,
Selected: integer);
begin
Normal := GetIconIndex(IDList, SHGFI_PIDL or SHGFI_SYSICONINDEX or
SHGFI_SMALLICON);
Selected := GetIconIndex(IDList, SHGFI_PIDL or SHGFI_SYSICONINDEX or
SHGFI_SMALLICON or SHGFI_OPENICON);
end;
initialization
// Get the shell memory allocation interface that everyone uses.
SHGetMalloc(ShellMalloc);
finalization
// Release the shell memory allocation interface.
{$IFDEF DFS_COMPILER_2}
ShellMalloc.Release;
{$ENDIF}
end.