home *** CD-ROM | disk | FTP | other *** search
- Unit SlctDir;
- {========================================================================}
- Interface
- Uses
- Dos;
- Function SelectDir(FileAreaPath : PathStr) : PathStr;
- {========================================================================}
- Implementation
- Uses
- Crt, MfmStr, Screen;
- Type
- ListPtr = ^ListRecord;
- ListRecord = Record
- Next, Prev : ListPtr;
- Attr : Byte;
- Name : String[12];
- End;
- Var
- DirInfo : SearchRec;
- FirstEntry, CurrentEntry, TempEntry : ListPtr;
- TempRecord : ListRecord;
- NoOfEntries, CurrentEntryNo : Word;
- NoEntryToShow : Byte;
- CurrentDrive : Byte;
- ForChar : Char;
- Msr : Registers;
- DriveList, TempString : String;
- {========================================================================}
- Procedure BuildDirList(FileSpec : PathStr);
- Begin
- FirstEntry := NIL; NoOfEntries := 0;
- FindFirst(FileSpec, AnyFile, DirInfo);
- While DosError = 0 Do
- Begin
- If DirInfo.Name = '.' Then FindNext(DirInfo);
- If DirInfo.Attr = Directory Then
- Begin
- New(CurrentEntry); Inc(NoOfEntries);
- If FirstEntry = NIL Then
- Begin
- FirstEntry := CurrentEntry;
- CurrentEntry^.Prev := NIL;
- End
- Else
- Begin
- CurrentEntry^.Prev := TempEntry;
- TempEntry^.Next := CurrentEntry;
- End;
- CurrentEntry^.Next := NIL;
- CurrentEntry^.Attr := DirInfo.Attr;
- CurrentEntry^.Name := DirInfo.Name;
- TempEntry := CurrentEntry;
- End;
- FindNext(DirInfo);
- End;
- End;
- {========================================================================}
- Procedure SortDirList;
- Var
- Exchange : Boolean;
- Begin
- If FirstEntry <> NIL Then
- Begin
- New(TempEntry);
- Repeat
- Exchange := False;
- CurrentEntry := FirstEntry;
- While CurrentEntry^.Next <> NIL Do
- Begin
- If CurrentEntry^.Name > CurrentEntry^.Next^.Name Then
- Begin
- TempEntry^.Attr := CurrentEntry^.Attr;
- CurrentEntry^.Attr := CurrentEntry^.Next^.Attr;
- CurrentEntry^.Next^.Attr := TempEntry^.Attr;
- TempEntry^.Name := CurrentEntry^.Name;
- CurrentEntry^.Name := CurrentEntry^.Next^.Name;
- CurrentEntry^.Next^.Name := TempEntry^.Name;
- Exchange := True;
- End;
- CurrentEntry := CurrentEntry^.Next;
- End;
- Until (Not Exchange);
- Dispose(TempEntry);
- End;
- End;
- {========================================================================}
- Procedure DisplayDirList;
- Begin
- If FirstEntry <> NIL Then
- Begin
- CurrentEntry := FirstEntry;
- WriteLn(' File List ');
- WriteLn('-----------');
- WriteLn(CurrentEntry^.Name);
- While CurrentEntry^.Next <> NIL Do
- Begin
- CurrentEntry := CurrentEntry^.Next;
- WriteLn(CurrentEntry^.Name);
- End;
- End;
- End;
- {========================================================================}
- Procedure RemoveDirList;
- Begin
- If FirstEntry <> NIL Then
- Begin
- CurrentEntry := FirstEntry;
- While CurrentEntry^.Next <> NIL Do
- Begin
- TempEntry := CurrentEntry;
- CurrentEntry := CurrentEntry^.Next;
- Dispose(TempEntry);
- End;
- Dispose(CurrentEntry);
- End;
- End;
- {========================================================================}
- Function DisplayEntryNo(EntryNo : Byte) : String;
- Var
- EntryNoCtr : Byte;
- Begin
- If FirstEntry <> NIL Then
- Begin
- TempEntry := FirstEntry; EntryNoCtr := 1;
- While (EntryNoCtr < EntryNo) And (EntryNoCtr < NoOfEntries) Do
- Begin
- TempEntry := TempEntry^.Next;
- Inc(EntryNoCtr);
- End;
- If EntryNoCtr = EntryNo Then
- Begin
- DisplayEntryNo := TempEntry^.Name+Copy(' ',1,12-Length(TempEntry^.Name));
- TempRecord.Attr := TempEntry^.Attr;
- TempRecord.Name := TempEntry^.Name;
- End
- Else
- Begin
- DisplayEntryNo := ' ';
- TempRecord.Attr := 0;
- TempRecord.Name := '';
- End;
- End
- Else
- Begin
- DisplayEntryNo := 'None';
- End;
- End;
- {========================================================================}
- Procedure DisplayEntryList(StartFrom : Word; Col, Row : Byte);
- Var
- Lsi : Word;
- Begin
- If FirstEntry <> NIL Then
- Begin
- AnsiGotoXYNew(Col,Row);
- If StartFrom > 1 Then WriteLn(' ^ ') Else WriteLn('═══');
- Inc(Row);
- For Lsi := StartFrom To StartFrom+(NoEntryToShow-1) Do
- Begin
- AnsiGotoXYNew(Col,Row);
- WriteLn(DisplayEntryNo(Lsi));
- Inc(Row);
- End;
- AnsiGotoXYNew(Col,Row);
- If NoOfEntries > StartFrom+(NoEntryToShow-1) Then WriteLn(' v ') Else WriteLn('═══');
- Inc(Row);
- End;
- End;
- {========================================================================}
- Procedure DoubleBox(Col, Row, Height, Width : Byte);
- Var
- Dbb : Byte;
- Begin
- AnsiGotoXYNew(Col,Row); Write('╔');
- For Dbb := 1 To Width-1 Do Write('═');
- Write('╗');
- For Dbb := 1 To Height Do
- Begin
- AnsiGotoXYNew(Col,Row+Dbb); Write('║');
- AnsiGotoXYNew(Col+Width,Row+Dbb); Write('║');
- End;
- AnsiGotoXYNew(Col,Row+Dbb); Write('╚');
- For Dbb := 1 To Width-1 Do Write('═');
- Write('╝');
- End;
- {========================================================================}
- Function SelectDir(FileAreaPath : PathStr) : PathStr;
- Const
- NoOfFiles = 15;
- Col = 2;
- Row = 2;
- Var
- SelPos, Sfb : Byte;
- Sfc : Char;
- TopChanged : Boolean;
- TopEntry : Word;
- D: DirStr;
- N: NameStr;
- E: ExtStr;
- Begin
- AnsiClearScreen;
- FSplit(FExpand(FileAreaPath),D,N,E);
- BuildDirList(FileAreaPath);
- SortDirList;
- If FirstEntry <> NIL Then
- Begin
- SelPos := 1;
- TopEntry := 1;
- TopChanged := True;
- NoEntryToShow := NoOfFiles;
- DoubleBox(Col,Row,NoEntryToShow+1,15);
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write('<');
- Repeat
- If TopChanged Then
- Begin
- DisplayEntryList(TopEntry,Col+2,Row);
- AnsiGotoXYNew(41,15); Write('D - Change Drive');
- AnsiGotoXYNew(41,16); Write('Q - Quit to Area Select');
- AnsiGotoXYNew(41,17); Write('S - Select Directory');
- TopChanged := False;
- End;
- AnsiGotoXYNew(50,1); AnsiClearToEol;
- If Pos('..',DisplayEntryNo(SelPos)) > 0 Then
- Begin
- Write(D);
- End
- Else
- Begin
- Write(AllTrim(D+DisplayEntryNo(SelPos))+'\');
- End;
- Repeat
- Sfb := GetInput;
- Sfc := Upcase(Chr(Sfb));
- If Sfb = 0 Then
- Begin
- Sfb := GetInput;
- Case Sfb Of
- 71 : Sfc := '7';
- 72 : Sfc := '8';
- 73 : Sfc := '9';
- 75 : Sfc := '4';
- 77 : Sfc := '6';
- 79 : Sfc := '1';
- 80 : Sfc := '2';
- 81 : Sfc := '3';
- End;
- End;
- Until Sfc In [#13,#27,'1','2','3','7','8','9','D','Q','S'];
- Case Sfc Of
- '1' : Begin
- If SelPos < NoOfEntries Then
- Begin
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write(' ');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write(' ');
- SelPos := NoOfEntries;
- If NoOfEntries > NoOfFiles Then
- Begin
- TopEntry := (NoOfEntries-NoOfFiles)+1;
- TopChanged := True;
- End;
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write('<');
- End;
- End;
- '2' : Begin
- If SelPos < NoOfEntries Then
- Begin
- If (SelPos-TopEntry)+2 > NoOfFiles Then
- Begin
- Inc(TopEntry);
- TopChanged := True;
- Inc(SelPos);
- End
- Else
- Begin
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write(' ');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write(' ');
- Inc(SelPos);
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write('<');
- End;
- End;
- End;
- '3' : Begin
- If SelPos < NoOfEntries Then
- Begin
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write(' ');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write(' ');
- If NoOfEntries < NoOfFiles Then
- Begin
- SelPos := NoOfEntries;
- End
- Else
- Begin
- If SelPos+NoOfFiles < NoOfEntries Then
- Begin
- SelPos := SelPos+NoOfFiles;
- TopEntry := TopEntry+NoOfFiles;
- TopChanged := True;
- End
- Else
- Begin
- SelPos := NoOfEntries;
- TopEntry := (NoOfEntries-NoOfFiles)+1;
- TopChanged := True;
- End;
- End;
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write('<');
- End;
- End;
- '7' : Begin
- If SelPos > 1 Then
- Begin
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write(' ');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write(' ');
- SelPos := 1;
- AnsiGotoXYNew(Col+1,Row+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+1); Write('<');
- End;
- If TopEntry > 1 Then
- Begin
- TopEntry := 1;
- TopChanged := True;
- End;
- End;
- '8' : Begin
- If SelPos > 1 Then
- Begin
- If SelPos = TopEntry Then
- Begin
- Dec(TopEntry);
- TopChanged := True;
- Dec(SelPos);
- End
- Else
- Begin
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write(' ');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write(' ');
- Dec(SelPos);
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write('<');
- End;
- End;
- End;
- '9' : Begin
- If SelPos > 1 Then
- Begin
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write(' ');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write(' ');
- If NoOfEntries < NoOfFiles Then
- Begin
- SelPos := 1;
- End
- Else
- Begin
- If SelPos-NoOfFiles > 1 Then
- Begin
- SelPos := SelPos-NoOfFiles;
- If TopEntry > NoOfFiles Then
- Begin
- TopEntry := TopEntry-NoOfFiles;
- End
- Else
- Begin
- TopEntry := SelPos;
- End;
- TopChanged := True;
- End
- Else
- Begin
- SelPos := 1;
- TopEntry := 1;
- TopChanged := True;
- End;
- End;
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write('<');
- End;
- End;
- 'D' : Begin
- DriveList := '';
- Msr.Ah := $19;
- MsDos(Msr);
- CurrentDrive := Msr.Al;
- For ForChar := 'A' To 'Z' Do
- Begin
- Msr.Ah := $0E;
- Msr.Dl := Ord(ForChar) - Ord('A');
- MsDos(Msr);
- Msr.Ah := $19;
- MsDos(Msr);
- If Msr.Al = Msr.Dl Then DriveList := DriveList+(Char(Msr.Al+Ord('A')))+': ';
- End;
- Msr.Ah := $0E;
- Msr.Dl := CurrentDrive;
- MsDos(Msr);
- AnsiGotoXYNew(1,25);
- Write(DriveList);
- AnsiGotoXYNew(41,23);
- Write('Select drive: ');
- Repeat
- Sfc := Upcase(ReadKey);
- Until (Pos(Sfc,DriveList) > 0) Or (Sfc = #27);
- If Sfc <> #27 Then
- Begin
- GetDir(Ord(Sfc)-(Ord('A')-1),TempString);
- AnsiGotoXYNew(41,21); ClrEol;
- Write(TempString);
- If Copy(TempString,Length(TempString),1) <> '\' Then TempString := TempString+'\';
- FSplit(FExpand(TempString+N+E),D,N,E);
- FileAreaPath := D+N+E;
- RemoveDirList;
- BuildDirList(FileAreaPath);
- SortDirList;
- SelPos := 1;
- TopEntry := 1;
- TopChanged := True;
- NoEntryToShow := NoOfFiles;
- AnsiClearScreen;
- DoubleBox(Col,Row,NoEntryToShow+1,15);
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write('<');
- Sfc := ' ';
- End;
- End;
- End;
- If (Sfc = #13) And (TempRecord.Attr = Directory) Then
- Begin
- FSplit(FExpand(D+TempRecord.Name+'\'+N+E),D,N,E);
- FileAreaPath := D+N+E;
- RemoveDirList;
- BuildDirList(FileAreaPath);
- SortDirList;
- SelPos := 1;
- TopEntry := 1;
- TopChanged := True;
- NoEntryToShow := NoOfFiles;
- AnsiClearScreen;
- DoubleBox(Col,Row,NoEntryToShow+1,15);
- AnsiGotoXYNew(Col+1,Row+(SelPos-TopEntry)+1); Write('>');
- AnsiGotoXYNew(Col+14,Row+(SelPos-TopEntry)+1); Write('<');
- Sfc := ' ';
- End;
- Until Sfc In [#27,'S','Q'];
- If Sfc In [#27,'Q'] Then
- Begin
- SelectDir := '';
- End
- Else
- Begin
- If Pos('..',DisplayEntryNo(SelPos)) > 0 Then
- Begin
- SelectDir := D;
- End
- Else
- Begin
- SelectDir := AllTrim(D+DisplayEntryNo(SelPos))+'\';
- End;
- End;
- CurrentEntryNo := SelPos;
- End;
- RemoveDirList;
- End;
- {========================================================================}
- Begin
- End.
- {========================================================================}
-