📄 vlistview.pas
字号:
unit VListView;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, ToolWin, ShlObj, ImgList, Menus, ExtCtrls, Grids,
Outline, DirOutln;
type
PShellItem = ^TShellItem;
TShellItem = record
FullID,
ID: PItemIDList;
Empty: Boolean;
DisplayName,
TypeName: string;
ImageIndex,
Size,
Attributes: Integer;
ModDate: string;
end;
TForm1 = class(TForm)
ListView: TListView;
ToolbarImages: TImageList;
PopupMenu1: TPopupMenu;
DirectoryOutline1: TDirectoryOutline;
Splitter1: TSplitter;
MainMenu1: TMainMenu;
CoolBar1: TCoolBar;
ToolBar2: TToolBar;
btnBack: TToolButton;
ToolButton3: TToolButton;
btnLargeIcons: TToolButton;
btnSmallIcons: TToolButton;
btnList: TToolButton;
btnReport: TToolButton;
da1: TMenuItem;
O1: TMenuItem;
M1: TMenuItem;
Delete1: TMenuItem;
P1: TMenuItem;
H1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure ListViewData(Sender: TObject; Item: TListItem);
procedure btnBrowseClick(Sender: TObject);
procedure cbPathKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure cbPathClick(Sender: TObject);
procedure btnLargeIconsClick(Sender: TObject);
procedure ListViewDblClick(Sender: TObject);
procedure ListViewDataHint(Sender: TObject; StartIndex,
EndIndex: Integer);
procedure ListViewKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure ListViewDataFind(Sender: TObject; Find: TItemFind;
const FindString: String; const FindPosition: TPoint;
FindData: Pointer; StartIndex: Integer; Direction: TSearchDirection;
Wrap: Boolean; var Index: Integer);
procedure ListViewCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
procedure ListViewCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean);
procedure btnBackClick(Sender: TObject);
procedure Form1Close(Sender: TObject; var Action: TCloseAction);
procedure O1Click(Sender: TObject);
private
FPIDL: PItemIDList;
FIDList: TList;
FIShellFolder,
FIDesktopFolder: IShellFolder;
FPath: string;
procedure SetPath(const Value: string); overload;
procedure SetPath(ID: PItemIDList); overload;
procedure PopulateIDList(ShellFolder: IShellFolder);
procedure ClearIDList;
procedure CheckShellItems(StartIndex, EndIndex: Integer);
function ShellItem(Index: Integer): PShellItem;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses ShellAPI, ActiveX, ComObj, CommCtrl, FileCtrl;
//PIDL MANIPULATION
procedure DisposePIDL(ID: PItemIDList);
var
Malloc: IMalloc;
begin
if ID = nil then Exit;
OLECheck(SHGetMalloc(Malloc));
Malloc.Free(ID);
end;
function CopyITEMID(Malloc: IMalloc; ID: PItemIDList): PItemIDList;
begin
Result := Malloc.Alloc(ID^.mkid.cb + SizeOf(ID^.mkid.cb));
CopyMemory(Result, ID, ID^.mkid.cb + SizeOf(ID^.mkid.cb));
end;
function NextPIDL(IDList: PItemIDList): PItemIDList;
begin
Result := IDList;
Inc(PChar(Result), IDList^.mkid.cb);
end;
function GetPIDLSize(IDList: PItemIDList): Integer;
begin
Result := 0;
if Assigned(IDList) then
begin
Result := SizeOf(IDList^.mkid.cb);
while IDList^.mkid.cb <> 0 do
begin
Result := Result + IDList^.mkid.cb;
IDList := NextPIDL(IDList);
end;
end;
end;
procedure StripLastID(IDList: PItemIDList);
var
MarkerID: PItemIDList;
begin
MarkerID := IDList;
if Assigned(IDList) then
begin
while IDList.mkid.cb <> 0 do
begin
MarkerID := IDList;
IDList := NextPIDL(IDList);
end;
MarkerID.mkid.cb := 0;
end;
end;
function CreatePIDL(Size: Integer): PItemIDList;
var
Malloc: IMalloc;
HR: HResult;
begin
Result := nil;
HR := SHGetMalloc(Malloc);
if Failed(HR) then
Exit;
try
Result := Malloc.Alloc(Size);
if Assigned(Result) then
FillChar(Result^, Size, 0);
finally
end;
end;
function CopyPIDL(IDList: PItemIDList): PItemIDList;
var
Size: Integer;
begin
Size := GetPIDLSize(IDList);
Result := CreatePIDL(Size);
if Assigned(Result) then
CopyMemory(Result, IDList, Size);
end;
function ConcatPIDLs(IDList1, IDList2: PItemIDList): PItemIDList;
var
cb1, cb2: Integer;
begin
if Assigned(IDList1) then
cb1 := GetPIDLSize(IDList1) - SizeOf(IDList1^.mkid.cb)
else
cb1 := 0;
cb2 := GetPIDLSize(IDList2);
Result := CreatePIDL(cb1 + cb2);
if Assigned(Result) then
begin
if Assigned(IDList1) then
CopyMemory(Result, IDList1, cb1);
CopyMemory(PChar(Result) + cb1, IDList2, cb2);
end;
end;
//SHELL FOLDER ITEM INFO
function GetDisplayName(ShellFolder: IShellFolder; PIDL: PItemIDList;
ForParsing: Boolean): string;
var
StrRet: TStrRet;
P: PChar;
Flags: Integer;
begin
Result := '';
if ForParsing then
Flags := SHGDN_FORPARSING
else
Flags := SHGDN_NORMAL;
ShellFolder.GetDisplayNameOf(PIDL, Flags, StrRet);
case StrRet.uType of
STRRET_CSTR:
SetString(Result, StrRet.cStr, lStrLen(StrRet.cStr));
STRRET_OFFSET:
begin
P := @PIDL.mkid.abID[StrRet.uOffset - SizeOf(PIDL.mkid.cb)];
SetString(Result, P, PIDL.mkid.cb - StrRet.uOffset);
end;
STRRET_WSTR:
Result := StrRet.pOleStr;
end;
end;
function GetShellImage(PIDL: PItemIDList; Large, Open: Boolean): Integer;
var
FileInfo: TSHFileInfo;
Flags: Integer;
begin
FillChar(FileInfo, SizeOf(FileInfo), #0);
Flags := SHGFI_PIDL or SHGFI_SYSICONINDEX or SHGFI_ICON;
if Open then Flags := Flags or SHGFI_OPENICON;
if Large then Flags := Flags or SHGFI_LARGEICON
else Flags := Flags or SHGFI_SMALLICON;
SHGetFileInfo(PChar(PIDL),
0,
FileInfo,
SizeOf(FileInfo),
Flags);
Result := FileInfo.iIcon;
end;
function IsFolder(ShellFolder: IShellFolder; ID: PItemIDList): Boolean;
var
Flags: UINT;
begin
Flags := SFGAO_FOLDER;
ShellFolder.GetAttributesOf(1, ID, Flags);
Result := SFGAO_FOLDER and Flags <> 0;
end;
function ListSortFunc(Item1, Item2: Pointer): Integer;
begin
Result := SmallInt(Form1.FIShellFolder.CompareIDs(
0,
PShellItem(Item1).ID,
PShellItem(Item2).ID
));
end;
{TForm1}
//GENERAL FORM METHODS
procedure TForm1.FormCreate(Sender: TObject);
var
FileInfo: TSHFileInfo;
ImageListHandle: THandle;
NewPIDL: PItemIDList;
begin
OLECheck(SHGetDesktopFolder(FIDesktopFolder));
FIShellFolder := FIDesktopFolder;
FIDList := TList.Create;
ImageListHandle := SHGetFileInfo('C:\',
0,
FileInfo,
SizeOf(FileInfo),
SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
SendMessage(ListView.Handle, LVM_SETIMAGELIST, LVSIL_SMALL, ImageListHandle);
ImageListHandle := SHGetFileInfo('C:\',
0,
FileInfo,
SizeOf(FileInfo),
SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
SendMessage(ListView.Handle, LVM_SETIMAGELIST, LVSIL_NORMAL, ImageListHandle);
OLECheck(
SHGetSpecialFolderLocation(
Application.Handle,
CSIDL_DRIVES,
NewPIDL)
);
SetPath(NewPIDL);
//ActiveControl := cbPath;
//cbPath.SelStart := 0;
// cbPath.SelLength := Length(cbPath.Text);
end;
procedure TForm1.btnBrowseClick(Sender: TObject);
var
S: string;
begin
S := '';
if SelectDirectory('Select Directory', '', S) then
SetPath(S);
end;
{procedure TForm1.cbPathKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_RETURN then
begin
if cbPath.Text[Length(cbPath.Text)] = ':' then
cbPath.Text := cbPath.Text + '\';
SetPath(cbPath.Text);
Key := 0;
end;
end;
procedure TForm1.cbPathClick(Sender: TObject);
var
I: Integer;
begin
I := cbPath.Items.IndexOf(cbPath.Text);
if I >= 0 then
SetPath(PItemIDList(cbPath.Items.Objects[I]))
else
SetPath(cbPath.Text);
end;}
procedure TForm1.btnLargeIconsClick(Sender: TObject);
begin
ListView.ViewStyle := TViewStyle((Sender as TComponent).Tag);
end;
procedure TForm1.ListViewDblClick(Sender: TObject);
var
RootPIDL,
ID: PItemIDList;
begin
if ListView.Selected <> nil then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -