// Change Directory #include #include #include #include #include #include #include const int MAXIMUM_NUMBER_OF_SUBDIRECTORIES = 200; const int NAME_LENGTH = 24; const int DISPLAY_HEIGHT = 16; const int PATH_WIDTH = 40; const int GUTTER_WIDTH = 2; const int DISPLAY_WIDTH = 1+PATH_WIDTH+GUTTER_WIDTH+NAME_LENGTH+1; const int CORNER_ROW = (25-DISPLAY_HEIGHT)/2; const int CORNER_COLUMN = (80-DISPLAY_WIDTH)/2; static char path[MAX_PATH]; static struct directory_struct { char name[MAX_PATH]; char alternate_name[8+1+3+1]; } directory[MAXIMUM_NUMBER_OF_SUBDIRECTORIES]; static unsigned number_of_directories; static unsigned this_directory; static unsigned highlight; static unsigned row, column; static unsigned save_cursor; static unsigned short save_screen[DISPLAY_HEIGHT*DISPLAY_WIDTH]; static char TMS[] = "*** Too many subdirectories ***"; static int key(void) { int k = getch(); if (k == 0) k = 256 + getch(); return k; } static void display_string(char *string, unsigned length, bool highlight) { int hlight = highlight ? 112<<8 : 7<<8; static short buffer[80]; unsigned i; for (i = 0; i < length; i++) buffer[i] = hlight + (*string!=0 ? *string++ : ' '); puttext(column + 1, CORNER_ROW + row + 1, column + length, CORNER_ROW + row + 1, buffer); column += length; } static void restore_screen(void) { puttext(CORNER_COLUMN+1, CORNER_ROW+1, CORNER_COLUMN + DISPLAY_WIDTH, CORNER_ROW + DISPLAY_HEIGHT, save_screen); //set_cursor(save_cursor-0x100); } static void remove_directory_from_path(char *p) { register char *s; register char *t; for (s=path; *s!=0; s++) if (*s == '\\') t = s; if (p!=NULL) strcpy(p, t+1); if (t==path) t++; *t = 0; } static void append_string_to_path(char *s) { register char *t = path; while (*t!=0) t++; do { if (t < path+sizeof(path)) *t++ = *s; else { restore_screen(); fputs("Directory path is too long", stderr); exit(1); } } while (*s++ != 0); } static void add_directory_to_path(char *s) { if (path[1] != 0) append_string_to_path("\\"); append_string_to_path(s); } static bool find_directories(void) { unsigned n = 0; add_directory_to_path("*.*"); WIN32_FIND_DATA f; HANDLE h = FindFirstFile(path, &f); if (h != INVALID_HANDLE_VALUE) { do { if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && f.cFileName[0] != '.') { if (n < MAXIMUM_NUMBER_OF_SUBDIRECTORIES) { strcpy(directory[n].name, f.cFileName); strcpy(directory[n++].alternate_name, f.cAlternateFileName); } else { row = DISPLAY_HEIGHT-1; column = CORNER_COLUMN+1; display_string(TMS, sizeof(TMS), false); } } } while (FindNextFile(h, &f)); FindClose(h); } remove_directory_from_path(NULL); if (n > 0) { unsigned i; bool exchange = true; while (exchange) { exchange = false; for (i=0; i+1 0) { struct directory_struct temp; exchange = true; temp = directory[i]; directory[i] = directory[i+1]; directory[i+1] = temp; } } } number_of_directories = n; this_directory = 0; return true; } return false; } static void move_left() { char parent[MAX_PATH]; remove_directory_from_path(parent); find_directories(); this_directory = number_of_directories; do { if (strcmp(directory[--this_directory].name, parent)==0) break; } while (this_directory > 0); highlight = this_directory <= DISPLAY_HEIGHT-4 ? this_directory : DISPLAY_HEIGHT-4; } static void change_directory(const char *directory) { static char path[MAXPATH]; static char drive[MAXDRIVE]; static char dir[MAXDIR]; fnsplit(_argv[0], drive, dir, NULL, NULL); fnmerge(path, drive, dir, "CDD3J6UF", ".BAT"); FILE *f = fopen(path, "w"); fputs("ECHO OFF\n", f); if (directory != NULL) fprintf(f, "CD \"%s\"\n", directory); fclose(f); } void main() { //save_cursor = cursor(); //set_cursor(25<<8); static unsigned short image[DISPLAY_WIDTH*DISPLAY_HEIGHT]; { unsigned i, j; for (i=0; i 0) { this_directory--; highlight = highlight > 0 ? highlight-1 : 0; no_change = false; } break; case 336: // Down if (this_directory+1 < number_of_directories) { this_directory++; highlight = highlight < DISPLAY_HEIGHT-4 ? highlight+1 : DISPLAY_HEIGHT-4; no_change = false; } break; case 331: // Left if (path[1] != 0) { move_left(); no_change = false; } break; case 333: // Right add_directory_to_path(directory[this_directory].name); if (find_directories()) { highlight = 0; no_change = false; } else remove_directory_from_path(NULL); break; case '\\': change_directory("\\"); restore_screen(); return; case 13: // Enter add_directory_to_path(directory[this_directory].name); change_directory(path); restore_screen(); return; case 27: // Esc change_directory(NULL); restore_screen(); return; } } } }