#include #include #include #include #include #include typedef struct { char Name[9]; char Ext[4]; char Attribute; unsigned int Date; unsigned int Time; unsigned long Size; int Tag; } FileStruc; typedef struct { char Name[13]; } FileNameStruc; #define MAXFILES 500 FileStruc *ScanDir( char *Mask, int Type ); char *FileName( FileStruc *f ); int GComm( void ); void HideCursor( void ); void BlockErase( int x, int y, int xx, int yy ); void DrawBox( int x, int y, int xx, int yy ); void DrawBox1( int x, int y, int xx, int yy ); void HLin( int x, int y, int xx, int yy ); void ChangeBlock( int x, int y, int xx, int yy, unsigned char attrib ); void AtSay( int x, int y, register char *s ); void AtSayF( int x, int y, char *fmt, ... ); void NPrintFA( int len, unsigned char attrib, char *fmt, ... ); int GetLine( char *s, int len, int start ); void TcclibInitialize( void ); extern int ScdirDone; extern unsigned char A_NORMAL; extern unsigned char A_REVERSE; int CompareFileNames( FileNameStruc *A, FileNameStruc *B ) { return( strcmp( A->Name, B->Name ) ); } char *GetFile( int x, int y, int xx, int yy, char *Mask, int FileAttrib, int ExtOn ) { register FileNameStruc *File; register int i; int j, cols, rows, Width, files, top, oldptr, oldtop; static char RetName[15]; FileStruc *fp; int ptr; char *Scr1, *Scr2; int ch; TcclibInitialize(); cols = xx - x + 1; rows = yy - y + 1; if ( cols < 14 || rows < 4 ) return( NULL ); if ( ( Scr1 = (char *) calloc( rows*2, cols ) ) == NULL ) return( NULL ); if ( ( Scr2 = (char *) calloc( 6, 14 ) ) == NULL ) return( NULL ); if ( ( File = (FileNameStruc *) calloc( MAXFILES, 13 ) ) == NULL ) return( NULL ); gettext( x, y, xx, yy, Scr1 ); BlockErase( x, y, xx, yy ); DrawBox( x, y, xx, yy ); gotoxy( x+1, y ); NPrintFA( cols-4, A_REVERSE, " %s ", Mask ); x++; y++; xx--; yy--; files = 0; ScdirDone = 1; while ( ( fp = ScanDir( Mask, FileAttrib ) ) != NULL && files < MAXFILES-1 ) { if ( ExtOn ) strcpy( File[files++].Name, FileName( fp ) ); else strcpy( File[files++].Name, fp->Name ); } if ( ExtOn ) Width = 14; else Width = 10; rows -= 2; cols = (xx - x + 3) / Width; qsort( File, files, sizeof( FileNameStruc ), CompareFileNames ); top = 0; RedrawFiles: BlockErase( x, y, xx, yy ); if ( top > 0 ) AtSay( xx-9, yy+1, "PgUp/" ); else HLin( xx-9, yy+1, xx-5, yy+1 ); if ( cols * rows + top < files ) { AtSay( xx-4, yy+1, "PgDn" ); } else HLin( xx-5, yy+1, xx-1, yy+1 ); for ( i=0; i ( i * rows + j + top ) ) AtSayF( x + Width * i, y + j, "%s", File[i * rows + j + top].Name ); ptr = 0; for (;;) { ChangeBlock( x, y, xx, yy, A_NORMAL ); ChangeBlock( x + ( ptr / rows * Width ), y + ( ptr % rows ), x + ( ptr / rows * Width ) + Width - 3, y + ( ptr % rows ), A_REVERSE ); oldptr = ptr; oldtop = top; HideCursor(); switch( ch = GComm() ) { case CR: strcpy( RetName, File[ptr + top].Name ); puttext( x-1, y-1, xx+1, yy+1, Scr1 ); free( Scr1 ); free( Scr2 ); free( File ); return( RetName ); case ESC: puttext( x-1, y-1, xx+1, yy+1, Scr1 ); free( Scr1 ); free( Scr2 ); free( File ); return( NULL ); case DOWN: if ( ptr < rows * cols - 1 ) ptr++; break; case UP: if ( ptr ) ptr--; break; case RIGHT: if ( ptr < rows * cols - rows ) ptr += rows; break; case LEFT: if ( ptr >= rows ) ptr -= rows; break; case PGDN: if ( top + rows * cols < files ) { top += rows * cols; goto RedrawFiles; } break; case PGUP: if ( top ) { top -= rows * cols; if ( top < 0 ) top = 0; goto RedrawFiles; } break; default: if ( ch > ' ' && ch < 128 ) { gettext( x-1, y, x+12, y+2, Scr2 ); BlockErase( x-1, y, x+12, y+2 ); DrawBox1( x-1, y, x+12, y+2 ); AtSay( x+2, y, "New File" ); gotoxy( x, y+1 ); putch( ch ); memset( RetName, 0, sizeof (RetName) ); RetName[0] = ch; if ( -1 == GetLine( RetName, 12, 1 ) ) { puttext( x-1, y, x+12, y+2, Scr2 ); break; } puttext( x-1, y-1, xx+1, yy+1, Scr1 ); free( Scr1 ); free( Scr2 ); free( File ); return( RetName ); } break; } if ( top < 0 ) top = 0; if ( !strlen( File[top+ptr].Name ) ) { ptr = oldptr; top = oldtop; } } }