📄 useldir.pas
字号:
Items.AddObject(Root, OpenedBMP);
Inc(IndentLevel);
TempPath := Copy(Directory, Length(Root)+1, Length(Directory));
end
else
TempPath := Directory;
if (Length(TempPath) > 0) then
begin
if AnsiLastChar(TempPath)^ <> '\' then
begin
BackSlashPos := AnsiPos('\', TempPath);
while BackSlashPos <> 0 do
begin
DirName := Copy(TempPath, 1, BackSlashPos - 1);
if IndentLevel = 0 then DirName := DirName + '\';
Delete(TempPath, 1, BackSlashPos);
Items.AddObject(DirName, OpenedBMP);
Inc(IndentLevel);
BackSlashPos := AnsiPos('\', TempPath);
end;
end;
Items.AddObject(TempPath, CurrentBMP);
end;
NewSelect := Items.Count - 1;
Siblings := TStringList.Create;
try
Siblings.Sorted := True;
{ read all the dir names into Siblings }
ReadDirectoryNames(Directory, Siblings);
for i := 0 to Siblings.Count - 1 do
Items.AddObject(Siblings[i], ClosedBMP);
finally
Siblings.Free;
end;
finally
Items.EndUpdate;
end;
if HandleAllocated then
ItemIndex := NewSelect;
end;
procedure TDirectoryListBox.ReadBitmaps;
begin
OpenedBMP := TBitmap.Create;
OpenedBMP.LoadFromResourceName(HInstance, 'OPENFOLDER');
ClosedBMP := TBitmap.Create;
ClosedBMP.LoadFromResourceName(HInstance, 'CLOSEDFOLDER');
CurrentBMP := TBitmap.Create;
CurrentBMP.LoadFromResourceName(HInstance, 'CURRENTFOLDER');
end;
procedure TDirectoryListBox.DblClick;
begin
inherited DblClick;
OpenCurrent;
end;
procedure TDirectoryListBox.Change;
begin
if FFileList <> nil then FFileList.SetDirectory(Directory);
SetDirLabelCaption;
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TDirectoryListBox.DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState);
var
Bitmap: TBitmap;
bmpWidth: Integer;
dirOffset: Integer;
begin
with Canvas do
begin
FillRect(Rect);
bmpWidth := 16;
dirOffset := Index * 4 + 2; {add 2 for spacing}
Bitmap := TBitmap(Items.Objects[Index]);
if Bitmap <> nil then
begin
if Bitmap = ClosedBMP then
dirOffset := (DirLevel (Directory) + 1) * 4 + 2;
bmpWidth := Bitmap.Width;
BrushCopy(Bounds(Rect.Left + dirOffset,
(Rect.Top + Rect.Bottom - Bitmap.Height) div 2,
Bitmap.Width, Bitmap.Height),
Bitmap, Bounds(0, 0, Bitmap.Width, Bitmap.Height),
Bitmap.Canvas.Pixels[0, Bitmap.Height - 1]);
end;
TextOut(Rect.Left + bmpWidth + dirOffset + 4, Rect.Top, DisplayCase(Items[Index]))
end;
end;
function TDirectoryListBox.GetItemPath (Index: Integer): string;
var
CurDir: string;
i, j: Integer;
Bitmap: TBitmap;
begin
Result := '';
if Index < Items.Count then
begin
CurDir := Directory;
Bitmap := TBitmap(Items.Objects[Index]);
if Index = 0 then
Result := ExtractFileDrive(CurDir)+'\'
else if Bitmap = ClosedBMP then
Result := SlashSep(CurDir,Items[Index])
else if Bitmap = CurrentBMP then
Result := CurDir
else
begin
i := 0;
j := 0;
Delete(CurDir, 1, Length(ExtractFileDrive(CurDir)));
while j <> (Index + 1) do
begin
Inc(i);
if i > Length (CurDir) then
break;
if CurDir[i] in LeadBytes then
Inc(i)
else if CurDir[i] = '\' then
Inc(j);
end;
Result := ExtractFileDrive(Directory) + Copy(CurDir, 1, i - 1);
end;
end;
end;
procedure TDirectoryListBox.CreateWnd;
begin
inherited CreateWnd;
BuildList;
ItemIndex := DirLevel (Directory);
end;
procedure TDirectoryListBox.CMFontChanged(var Message: TMessage);
begin
inherited;
ResetItemHeight;
end;
procedure TDirectoryListBox.ResetItemHeight;
var
nuHeight: Integer;
begin
nuHeight := GetItemHeight(Font);
if nuHeight < (OpenedBMP.Height + 1) then nuHeight := OpenedBmp.Height + 1;
ItemHeight := nuHeight;
end;
function TDirectoryListBox.GetDrive: char;
begin
Result := FDirectory[1];
end;
procedure TDirectoryListBox.SetDrive(Value: char);
begin
if (UpCase(Value) <> UpCase(Drive)) then
SetDirectory (Format ('%s:', [Value]));
end;
procedure TDirectoryListBox.SetDirectory(const NewDirectory: string);
var
DirPart: string;
FilePart: string;
NewDrive: Char;
begin
if Length (NewDirectory) = 0 then Exit;
if (FileCompareText(NewDirectory, Directory) = 0) then Exit;
ProcessPath (NewDirectory, NewDrive, DirPart, FilePart);
try
if Drive <> NewDrive then
begin
FInSetDir := True;
if (FDriveCombo <> nil) then
FDriveCombo.Drive := NewDrive
else
DriveChange(NewDrive);
end;
finally
FInSetDir := False;
end;
SetDir(DirPart);
end;
procedure TDirectoryListBox.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
if (Word(Key) = VK_RETURN) then
OpenCurrent;
end;
procedure TDirectoryListBox.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) then
begin
if (AComponent = FFileList) then FFileList := nil
else if (AComponent = FDriveCombo) then FDriveCombo := nil
else if (AComponent = FDirLabel) then FDirLabel := nil;
end;
end;
procedure TDirectoryListBox.SetDirLabelCaption;
var
DirWidth: Integer;
begin
if FDirLabel <> nil then
begin
DirWidth := Width;
if not FDirLabel.AutoSize then DirWidth := FDirLabel.Width;
FDirLabel.Caption := MinimizeName(Directory, FDirLabel.Canvas, DirWidth);
end;
end;
{ TFileListBox }
const
DefaultMask = '*.*';
constructor TFileListBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width := 145;
{ IntegralHeight := True; }
FFileType := [ftNormal]; { show only normal files by default }
GetDir(0, FDirectory); { initially use current dir on default drive }
FMask := DefaultMask; { default file mask is all }
MultiSelect := False; { default is not multi-select }
FLastSel := -1;
ReadBitmaps;
Sorted := True;
Style := lbOwnerDrawFixed;
ResetItemHeight;
end;
destructor TFileListBox.Destroy;
begin
ExeBMP.Free;
DirBMP.Free;
UnknownBMP.Free;
inherited Destroy;
end;
procedure TFileListBox.Update;
begin
ReadFileNames;
end;
procedure TFileListBox.CreateWnd;
begin
inherited CreateWnd;
ReadFileNames;
end;
function TFileListBox.IsMaskStored: Boolean;
begin
Result := DefaultMask <> FMask;
end;
function TFileListBox.GetDrive: char;
begin
Result := FDirectory[1];
end;
procedure TFileListBox.ReadBitmaps;
begin
ExeBMP := TBitmap.Create;
ExeBMP.Handle := LoadBitmap(HInstance, 'EXECUTABLE');
DirBMP := TBitmap.Create;
DirBMP.Handle := LoadBitmap(HInstance, 'CLOSEDFOLDER');
UnknownBMP := TBitmap.Create;
UnknownBMP.Handle := LoadBitmap(HInstance, 'UNKNOWNFILE');
end;
procedure TFileListBox.ReadFileNames;
var
AttrIndex: TFileAttr;
I: Integer;
FileExt: string;
MaskPtr: PChar;
Ptr: PChar;
AttrWord: Word;
FileInfo: TSearchRec;
SaveCursor: TCursor;
Glyph: TBitmap;
const
Attributes: array[TFileAttr] of Word = (faReadOnly, faHidden, faSysFile,
faVolumeID, faDirectory, faArchive, 0);
begin
{ if no handle allocated yet, this call will force
one to be allocated incorrectly (i.e. at the wrong time.
In due time, one will be allocated appropriately. }
AttrWord := DDL_READWRITE;
if HandleAllocated then
begin
{ Set attribute flags based on values in FileType }
for AttrIndex := ftReadOnly to ftArchive do
if AttrIndex in FileType then
AttrWord := AttrWord or Attributes[AttrIndex];
ChDir(FDirectory); { go to the directory we want }
Clear; { clear the list }
I := 0;
SaveCursor := Screen.Cursor;
try
MaskPtr := PChar(FMask);
while MaskPtr <> nil do
begin
Ptr := StrScan (MaskPtr, ';');
if Ptr <> nil then
Ptr^ := #0;
if FindFirst(MaskPtr, AttrWord, FileInfo) = 0 then
begin
repeat { exclude normal files if ftNormal not set }
if (ftNormal in FileType) or (FileInfo.Attr and AttrWord <> 0) then
if FileInfo.Attr and faDirectory <> 0 then
begin
I := Items.Add(Format('[%s]',[FileInfo.Name]));
if ShowGlyphs then
Items.Objects[I] := DirBMP;
end
else
begin
FileExt := AnsiLowerCase(ExtractFileExt(FileInfo.Name));
Glyph := UnknownBMP;
if (FileExt = '.exe') or (FileExt = '.com') or
(FileExt = '.bat') or (FileExt = '.pif') then
Glyph := ExeBMP;
I := Items.AddObject(FileInfo.Name, Glyph);
end;
if I = 100 then
Screen.Cursor := crHourGlass;
until FindNext(FileInfo) <> 0;
FindClose(FileInfo);
end;
if Ptr <> nil then
begin
Ptr^ := ';';
Inc (Ptr);
end;
MaskPtr := Ptr;
end;
finally
Screen.Cursor := SaveCursor;
end;
Change;
end;
end;
procedure TFileListBox.Click;
begin
inherited Click;
if FLastSel <> ItemIndex then
Change;
end;
procedure TFileListBox.Change;
begin
FLastSel := ItemIndex;
if FFileEdit <> nil then
begin
if Length(GetFileName) = 0 then
FileEdit.Text := Mask
else
FileEdit.Text := GetFileName;
FileEdit.SelectAll;
end;
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TFileListBox.SetShowGlyphs(Value: Boolean);
begin
if FShowGlyphs <> Value then
begin
FShowGlyphs := Value;
if (FShowGlyphs = True) and (ItemHeight < (ExeBMP.Height + 1)) then
ResetItemHeight;
Invalidate;
end;
end;
function TFileListBox.GetFileName: string;
var
idx: Integer;
begin
{ if multi-select is turned on, then using ItemIndex
returns a bogus value if nothing is selected }
idx := ItemIndex;
if (idx < 0) or (Items.Count = 0) or (Selected[idx] = FALSE) then
Result := ''
else
Result := Items[idx];
end;
procedure TFileListBox.SetFileName(const NewFile: string);
begin
if AnsiCompareFileName(NewFile, GetFileName) <> 0 then
begin
ItemIndex := SendMessage(Handle, LB_FindStringExact, 0,
Longint(PChar(NewFile)));
Change;
end;
end;
procedure TFileListBox.SetFileEdit(Value: TEdit);
begin
FFileEdit := Value;
if FFileEdit <> nil then
begin
FFileEdit.FreeNotification(Self);
if GetFileName <> '' then
FFileEdit.Text := GetFileName
else
FFileEdit.Text := Mask;
end;
end;
procedure TFileListBox.DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState);
var
Bitmap: TBitmap;
offset: Integer;
begin
with Canvas do
begin
FillRect(Rect);
offset := 2;
if ShowGlyphs then
begin
Bitmap := TBitmap(Items.Objects[Index]);
if Assigned(Bitmap) then
begin
BrushCopy(Bounds(Rect.Left + 2,
(Rect.Top + Rect.Bottom - Bitmap.Height) div 2,
Bitmap.Width, Bitmap.Height),
Bitmap, Bounds(0, 0, Bitmap.Width, Bitmap.Height),
Bitmap.Canvas.Pixels[0, Bitmap.Height - 1]);
offset := Bitmap.width + 6;
end;
end;
TextOut(Rect.Left + offset, Rect.Top, Items[Index])
end;
end;
procedure TFileListBox.SetDrive(Value: char);
begin
if (UpCase(Value) <> UpCase(FDirectory[1])) then
ApplyFilePath (Format ('%s:', [Value]));
end;
procedure TFileListBox.SetDirectory(const NewDirectory: string);
begin
if AnsiCompareFileName(NewDirectory, FDirectory) <> 0 then
begin
{ go to old directory first, in case not complete pathname
and curdir changed - probably not necessary }
if DirectoryExists(FDirectory) then
ChDir(FDirectory);
ChDir(NewDirectory); { exception raised if invalid dir }
GetDir(0, FDirectory); { store correct directory name }
ReadFileNames;
end;
end;
procedure TFileListBox.SetFileType(NewFileType: TFileType);
begin
if NewFileType <> FFileType then
begin
FFileType := NewFileType;
ReadFileNames;
end;
end;
procedure TFileListBox.SetMask(const NewMask: string);
begin
if FMask <> NewMask then
begin
FMask := NewMask;
ReadFileNames;
end;
end;
procedure TFileListBox.CMFontChanged(var Message: TMessage);
begin
inherited;
ResetItemHeight;
end;
procedure TFileListBox.ResetItemHeight;
var
nuHeight: Integer;
begin
nuHeight := GetItemHeight(Font);
if (FShowGlyphs = True) and (nuHeight < (ExeBMP.Height + 1)) then
nuHeight := ExeBmp.Height + 1;
ItemHeight := nuHeight;
end;
procedure TFileListBox.ApplyFilePath(const EditText: string);
var
DirPart: string;
FilePart: string;
NewDrive: Char;
begin
if AnsiCompareFileName(FileName, EditText) = 0 then Exit;
if Length (EditText) = 0 then Exit;
ProcessPath (EditText, NewDrive, DirPart, FilePart);
if FDirList <> nil then
FDirList.Directory := EditText
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -