📄 bsfilectrl.pas
字号:
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 TbsSkinDirectoryListBox.Loaded;
begin
inherited;
if (csDesigning in ComponentState)
then
begin
GetDir(0, FDirectory);
BuildList;
end;
end;
procedure TbsSkinDirectoryListBox.CreateWnd;
begin
inherited;
BuildList;
ItemIndex := DirLevel (Directory);
end;
function TbsSkinDirectoryListBox.GetDrive: char;
begin
Result := FDirectory[1];
end;
procedure TbsSkinDirectoryListBox.SetDrive(Value: char);
begin
if (UpCase(Value) <> UpCase(Drive)) then
SetDirectory (Format ('%s:', [Value]));
end;
procedure TbsSkinDirectoryListBox.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 TbsSkinDirectoryListBox.ListBoxKeyPress;
begin
inherited;
if (Word(Key) = VK_RETURN) then
OpenCurrent;
end;
procedure TbsSkinDirectoryListBox.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 TbsSkinDirectoryListBox.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;
{ TbsSkinFileListBox }
const
DefaultMask = '*.*';
constructor TbsSkinFileListBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width := 145;
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;
Sorted := True;
end;
destructor TbsSkinFileListBox.Destroy;
begin
inherited Destroy;
end;
procedure TbsSkinFileListBox.Update;
begin
ReadFileNames;
end;
procedure TbsSkinFileListBox.CreateWnd;
begin
inherited;
ReadFileNames;
end;
procedure TbsSkinFileListBox.Loaded;
begin
inherited;
if (csDesigning in ComponentState)
then
begin
GetDir(0, FDirectory);
ReadFileNames;
end;
end;
function TbsSkinFileListBox.IsMaskStored: Boolean;
begin
Result := DefaultMask <> FMask;
end;
function TbsSkinFileListBox.GetDrive: char;
begin
Result := FDirectory[1];
end;
procedure TbsSkinFileListBox.ReadFileNames;
var
AttrIndex: TFileAttr;
I: Integer;
FileExt: string;
MaskPtr: PChar;
Ptr: PChar;
AttrWord: Word;
FileInfo: TSearchRec;
SaveCursor: TCursor;
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]));
end
else
begin
FileExt := AnsiLowerCase(ExtractFileExt(FileInfo.Name));
I := Items.AddObject(FileInfo.Name, nil);
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 TbsSkinFileListBox.ListBoxClick;
begin
inherited;
if FLastSel <> ItemIndex then
Change;
end;
procedure TbsSkinFileListBox.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;
function TbsSkinFileListBox.GetFileName: string;
var
idx: Integer;
begin
idx := ItemIndex;
if (idx < 0) or (Items.Count = 0) or (Selected[idx] = FALSE) then
Result := ''
else
Result := Items[idx];
end;
procedure TbsSkinFileListBox.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 TbsSkinFileListBox.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 TbsSkinFileListBox.SetDrive(Value: char);
begin
if (UpCase(Value) <> UpCase(FDirectory[1])) then
ApplyFilePath (Format ('%s:', [Value]));
end;
procedure TbsSkinFileListBox.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 TbsSkinFileListBox.SetFileType(NewFileType: TFileType);
begin
if NewFileType <> FFileType then
begin
FFileType := NewFileType;
ReadFileNames;
end;
end;
procedure TbsSkinFileListBox.SetMask(const NewMask: string);
begin
if FMask <> NewMask then
begin
FMask := NewMask;
ReadFileNames;
end;
end;
procedure TbsSkinFileListBox.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
if NewDrive <> #0 then
SetDirectory(Format('%s:%s', [NewDrive, DirPart]))
else
SetDirectory(DirPart);
if (Pos('*', FilePart) > 0) or (Pos('?', FilePart) > 0) then
SetMask (FilePart)
else if Length(FilePart) > 0 then
begin
SetFileName (FilePart);
if FileExists (FilePart) then
begin
if GetFileName = '' then
begin
SetMask(FilePart);
SetFileName (FilePart);
end;
end;
end;
end;
function TbsSkinFileListBox.GetFilePath: string;
begin
Result := '';
if GetFileName <> '' then
Result := SlashSep(FDirectory, GetFileName);
end;
procedure TbsSkinFileListBox.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) then
begin
if (AComponent = FFileEdit) then FFileEdit := nil
else if (AComponent = FDirList) then FDirList := nil
else if (AComponent = FFilterCombo) then FFilterCombo := nil;
end;
end;
{ TbsSkinFilterComboBox }
constructor TbsSkinFilterComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FFilter := SDefaultFilter;
MaskList := TStringList.Create;
end;
destructor TbsSkinFilterComboBox.Destroy;
begin
MaskList.Free;
inherited Destroy;
end;
procedure TbsSkinFilterComboBox.CreateWnd;
begin
inherited CreateWnd;
BuildList;
end;
function TbsSkinFilterComboBox.IsFilterStored: Boolean;
begin
Result := SDefaultFilter <> FFilter;
end;
procedure TbsSkinFilterComboBox.SetFilter(const NewFilter: string);
begin
if AnsiCompareFileName(NewFilter, FFilter) <> 0 then
begin
FFilter := NewFilter;
if HandleAllocated then BuildList;
Change;
end;
end;
procedure TbsSkinFilterComboBox.SeTbsSkinFileListBox (Value: TbsSkinFileListBox);
begin
if FFileList <> nil then FFileList.FFilterCombo := nil;
FFileList := Value;
if FFileList <> nil then
begin
FFileList.FreeNotification(Self);
FFileList.FFilterCombo := Self;
end;
end;
procedure TbsSkinFilterComboBox.Click;
begin
inherited Click;
Change;
end;
function TbsSkinFilterComboBox.GetMask: string;
begin
if ItemIndex < 0 then
ItemIndex := Items.Count - 1;
if ItemIndex >= 0 then
begin
Result := MaskList[ItemIndex];
end
else
Result := '*.*';
end;
procedure TbsSkinFilterComboBox.BuildList;
var
AFilter, MaskName, Mask: string;
BarPos: Integer;
begin
Items.Clear;
MaskList.Clear;
AFilter := Filter;
BarPos := AnsiPos('|', AFilter);
while BarPos <> 0 do
begin
MaskName := Copy(AFilter, 1, BarPos - 1);
Delete(AFilter, 1, BarPos);
BarPos := AnsiPos('|', AFilter);
if BarPos > 0 then
begin
Mask := Copy(AFilter, 1, BarPos - 1);
Delete(AFilter, 1, BarPos);
end
else
begin
Mask := AFilter;
AFilter := '';
end;
Items.Add(MaskName);
MaskList.Add(Mask);
BarPos := AnsiPos('|', AFilter);
end;
ItemIndex := 0;
end;
procedure TbsSkinFilterComboBox.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FFileList) then
FFileList := nil;
end;
procedure TbsSkinFilterComboBox.Change;
begin
if FFileList <> nil then FFileList.Mask := Mask;
inherited Change;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -