/* tsemenuscrollborland.c - Vertical scrolling menu demonstration
* Version 1.9 - 2025-01-07
* Compile with: bcc tsemenuscrollborland.c
*/
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define ENTER 13
#define ESC 27
#define ARROW_PREFIX 0
#define UP_ARROW 72
#define DOWN_ARROW 80
#define PGUP 73
#define PGDN 81
int getScreenRows(void) {
struct text_info ti;
gettextinfo(&ti);
return ti.screenheight;
}
int main(void) {
int quitB = FALSE;
int startI = 1;
int minI = 1;
int maxI = 0;
int windowSizeI;
int totalItemsI = 100; /* change this - total number of menu items */
int cursorI = 1;
int selectedI = 0;
int i;
int key;
int topRow = 1; /* Fixed top row for menu */
/* Initial screen setup */
_setcursortype(_NOCURSOR); /* Hide cursor */
clrscr();
do {
/* Recalculate window size dynamically */
windowSizeI = getScreenRows();
/* Adjust cursor position if window shrunk */
if (cursorI > windowSizeI) {
cursorI = windowSizeI;
}
/* Calculate based on current screen size */
maxI = totalItemsI - windowSizeI + 1;
if (maxI < minI) {
maxI = minI;
}
/* Adjust start position if needed */
if (startI > maxI) {
startI = maxI;
}
/* Redraw entire menu at fixed position */
for (i = 0; i < windowSizeI; i++) {
gotoxy(1, topRow + i);
/* Highlight the cursor position */
if (i + 1 == cursorI) {
textbackground(RED);
textcolor(YELLOW);
} else {
textbackground(BLUE);
textcolor(WHITE);
}
/* Print the number with padding to clear the line */
cprintf(" %3d%-74s", startI + i, "");
}
/* Get key and handle it */
key = getch();
/* Handle extended keys (arrows, function keys) */
if (key == ARROW_PREFIX || key == 224) {
key = getch();
switch (key) {
case UP_ARROW:
/* Same logic as TSE SAL version */
if (cursorI > 1) {
cursorI = cursorI - 1;
} else if (startI > minI) {
startI = startI - 1;
}
break;
case DOWN_ARROW:
/* Same logic as TSE SAL version */
if (cursorI < windowSizeI) {
cursorI = cursorI + 1;
} else if (startI < maxI) {
startI = startI + 1;
}
break;
case PGUP:
startI = startI - windowSizeI;
if (startI < minI) {
startI = minI;
}
break;
case PGDN:
startI = startI + windowSizeI;
if (startI > maxI) {
startI = maxI;
}
break;
}
} else {
/* Handle regular keys */
switch (key) {
case ENTER:
selectedI = startI + cursorI - 1;
quitB = TRUE;
break;
case 'q':
case 'Q':
quitB = TRUE;
break;
}
}
} while (!quitB);
/* Clean up display */
_setcursortype(_NORMALCURSOR); /* Restore cursor */
textbackground(BLACK);
textcolor(LIGHTGRAY);
clrscr();
/* Show final result if something was selected */
if (selectedI > 0) {
printf("You selected: %d\n", selectedI);
}
return 0;
}