{============================================================================} { PickFile.Pas - A unit that returns a filename selected by the user using } { the point and shoot method. } { You are free to modify and freely distribute the following } { source code in any way you feel neccessary. } { I plan on using it in some of my database programs in order } { for the user to select a databases for Him/Her to use. } { Author : Jim Luckas (76630,370) } { } { P.S. this is my first attempt at TP V4.0 (What a wonderfull experiance!) } {=============================================================================} unit pickfile; interface uses dos,crt; {$I-,S-,V-} Const Shadow = TRUE; NoShadow = FALSE; Var Picked: Boolean; {True if a file was picked} Function FPick(Path : PathStr; BorderColor,WinColor, TopX,TopY,Deep: Byte; Shadow : Boolean ) : PathStr; implementation type S_Type = string[13]; Function FAttr(path : PathStr) : Byte; var info: SearchRec; begin FindFirst(path,Directory,info); if DosError= 0 then FAttr := info.attr else FAttr := 0; end; {-----------------------------------------------------------------------------} { This is the Function that you call from your main program. } { Path = Search Path example. '*.pas' } { Deep = Maximum number of file names in the box. } { Shadow = Should the box have a shadow? } { This function returns the filename without the extension. } { Sample call : WriteLn(FPick('*.pas',White,White+Blue*16,10,10,23,Shadow)) } {-----------------------------------------------------------------------------} {--------------------------- Globals to be used by program -------------------} Const FNameLen = 13; BoxWidth = FNameLen + 2; ShadowWidth = BoxWidth + 2; Type Stack_Ptr = String[FNameLen]; Var HeapTop : ^Integer; PtrArray : Array[1..256] of ^Stack_Ptr; NuOfFiles, BotY,RecNum,Ypos : Byte; Function FPick(Path : PathStr; BorderColor,WinColor, TopX,TopY,Deep: Byte; Shadow : Boolean ) : PathStr; Var SearchDir : DirStr; SearchName : NameStr; SearchExt : ExtStr; {-----------------------------------------------------------------------------} { Return the last directory name in the string } {-----------------------------------------------------------------------------} Function LastDir(p:DirStr):DirStr; var i : integer; disk : string[5]; begin i := length(p); if p[i]='\' then begin dec(i); p[0] := chr(i); end; while (i>0) and not (p[i] IN ['\',':']) do dec(i); if (i>1) and (p[2]=':') then disk := p[1]+':' else disk := ''; { if p[i]='\' then disk := disk + ' ..\'; } LastDir := disk + Copy(p,i+1,255); end; {-----------------------------------------------------------------------------} { Draw the Display Box for the filenames } {-----------------------------------------------------------------------------} Procedure Draw_Frame; begin If NuOfFiles > (Deep-TopY) then {<- Decide How } BotY := Deep { Long to make } else BotY := (TopY + 1) + NuOfFiles; { Display Box } If Shadow then {<- Check to see if } Begin { we want a shodow } Window(TopX+1,TopY+1,TopX+ShadowWidth,BotY + 1); {<- Window the } TextAttr := $07; { shadow image } ClrScr; { and clear it } end; TextAttr := BorderColor; {<- Set the Frame color } Window(TopX,TopY,TopX+BoxWidth,BotY+1); {<- Window the file box } Inc(TopY); dec(BotY); Write('ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿'); { Now } GotoXY(3,1);Write(LastDir(SearchDir)); GotoXY(1,2); For Ypos := TopY to BotY do { Draw the } Write('³ ³'); { Box } Write('ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ'); { image } Inc(TopX); Deep := BotY - TopY; {<- Change to inside depth } GotoXY(6,Deep+3); If NuOfFiles > Deep+1 then {<- Let the user Know } Write(' more '); { theres more to come } end; {-----------------------------------------------------------------------------} { Store the FileNames in memory for now } {-----------------------------------------------------------------------------} Function Get_Files : Boolean; Var DirInfo : SearchRec; { Turbo's FileName Rec } Procedure AddFile(name:S_Type); begin inc(NuOfFiles); {<- Increment File Counter } New(PtrArray[NuOfFiles]); {<- Get new pointer } PtrArray[NuOfFiles]^ := name; {<- Store the FileName } end; begin NuOfFiles := 0; {<- Set Number of Files to 0 } FindFirst(SearchDir+Path,Archive, DirInfo); Get_Files := True; {<- Set Return to True } If DosError IN [0,18] then begin {<- Check to see if any files } While DosError = 0 do begin AddFile(DirInfo.name); FindNext(DirInfo); end; FindFirst(SearchDir+'*.*',Directory, DirInfo); If DosError=0 then begin {<- Check to see if any files } While DosError = 0 do begin with DirInfo do if (attr=Directory) and (name<>'.') then AddFile(name+'\'); FindNext(DirInfo); {<- Thanks Again } end end {if} else Get_Files := False; {<- If no files found Return False } end {if} else Get_Files := False; {<- If no files found Return False } end; {-----------------------------------------------------------------------------} { Function that returns a parsed file name. exp.(Test.pas would return Test) } {-----------------------------------------------------------------------------} Function ParsedFile( FileToParse : S_Type) : S_Type; { File name Passed } var d: DirStr; n: NameStr; x: ExtStr; begin if FileToParse[length(FileToParse)]='\' then ParsedFile := FileToParse else begin FSplit(FileToParse,d,n,x); while length(n) BotY then {<- Did we reach the } begin { Bottom of the } dec(Ypos); { Display and need } If RecNum <= NuOfFiles then { to Scroll Up } Scroll('U',TopX,TopY,FNameLen,deep,1,WinColor) else RecNum := NuOfFiles; end; If Ypos < TopY then {<- Did we reach the } begin { Top of the } inc(Ypos); { Display and need } If RecNum > 0 then { to Scroll Down } Scroll('D',TopX,TopY,FNameLen,Deep,1,WinColor) Else RecNum := 1; end; until (CH = #13) or (CH = #27); {<- Break out If Return or Esc } end; {-----------------------------------------------------------------------------} { This is where main function FPick Starts } {-----------------------------------------------------------------------------} var SelectionMade : Boolean; oldDeep,oldX,oldY : Integer; oldWind : record x,y : integer; attr : byte; max,min : word; end; DeepX,DeepY : Integer; begin if Deep<1 then Deep := 1; {Minimum value} {Change Deep to a screen position} Deep := Deep + TopY + 2; if Shadow then DeepY := ShadowWidth - BoxWidth else DeepY:= 0; if Deep+DeepY>hi(WindMax) then begin {adjust to end of screen} Deep := hi(WindMax)-DeepY; if Deep-TopY < 2 then begin {not enough room!} FPick := ''; DosError := 0; Exit; end; end; DeepX := TopX + BoxWidth + DeepY; DeepY := Deep + DeepY; oldDeep := Deep; oldX := TopX; oldY := TopY; with oldWind do begin x := WhereX; y := WhereY; attr := TextAttr; min := WindMin; max := WindMax; end; SelectionMade := FALSE; FSplit(FExpand(Path),SearchDir,SearchName,SearchExt); repeat Picked := FALSE; Path := SearchName+SearchExt; Mark(HeapTop); {<- Mark HeapTop } If Get_Files then {<- if Files Found Continue } begin Draw_Frame; {<- Draw the Display Frame } Draw_Files; {<- Fill Display with Files } Pick_File; {<- Pick a FileName } path := PtrArray[RecNum]^; SelectionMade := (path=''); if SelectionMade then path := SearchDir else begin path := FExpand(SearchDir + path); if path[length(path)]='\' then SearchDir := path else begin SelectionMade := TRUE; Picked := TRUE; end; end; end else begin path := ''; {<- No Files Found Ret '' } SelectionMade := TRUE; end; Release(HeapTop); {<- Release the memory used } {Restore the input parameters} TopX := oldX; TopY := oldY; Deep := oldDeep; {Clear up the screen} Window(TopX,TopY,DeepX,DeepY); TextAttr := oldWind.attr; GotoXY(1,1); ClrScr; until SelectionMade; {Restore the screen} with oldWind do begin Window(lo(min)+1,hi(min)+1,lo(max)+1,hi(max)+1); GotoXY(x,y); TextAttr := Attr; end; FPick := path; end; Begin End. { ------------------- DEMO PROGRAM --------------- } {--------------------------- Demo for PickFile.pas ---------------------------} { For a better description peruse pickfile.pas } {-----------------------------------------------------------------------------} { PickFile.tpu - Turbo unit for selecting a file from the directory } { PFdemo.pas - This pas file to demonstarate PickFile } { PickFile.pas - The source for PickFile.tpu. } { All yours to use as you wish. } { } { Function FPick (Path : PathStr; } { BorderColor,WindowColor, } { TopX,TopY,BotY,Shadow : Byte ) : PathStr; } { Shadow 1=yes 0=no } {----------------------------------------------------------------------} uses Dos,Crt,PickFile; Const OnBlack = 0; OnBlue = $10; OnGreen = $20; OnCyan = $30; OnRed = $40; OnMagenta = $50; OnBrown = $60; OnLightGray = $70; Var PathName : String[80]; FileName : PathStr; Starts : integer; Begin Textattr := White+OnBlue; ClrScr; Textattr := White+OnMagenta; Write('Enter a FileSpec : '); Starts := WhereX; ReadLn(PathName); Textattr := White+OnBlue; {------------------ This is where we call the function --------------------} FileName := FPick(PathName,White,White+OnBlue,Starts,WhereY+1,25,Shadow); {--------------------------------------------------------------------------} { TextAttr := $07; ClrScr; } If Picked then WriteLn('You selected : ',Filename) Else If Filename = '' then WriteLn('PickFile Aborted (',DosError,')') Else Writeln('You quit looking in : ',Filename); end.