📄 textwind.cpp
字号:
for ( rpos.h.dl = start_col ;
rpos.h.dl < (unsigned char) (start_col+width);
rpos.h.dl++ ) {
int86( 0x10, &rpos, &rout );
int86( 0x10, &rread, &rout );
save_buffer[ i++ ] = rout.x.ax;
}
}
}
// When a popup window is destroyed, the area under it is
// restored. This function restores the text under the window,
// but doesn't do anything about the border.
void TextWindow::restore_window( void )
{
union REGS rpos;
union REGS rwrite;
union REGS rout;
int i;
SaveCursor save_it;
if ( !save_buffer )
return;
i = 0;
rpos.h.ah = 2;
rpos.h.bh = 0;
rwrite.h.ah = 9;
rwrite.h.bh = 0;
rwrite.x.cx = 1;
for ( rpos.h.dh = start_row ;
rpos.h.dh < (unsigned char) ( start_row + height );
rpos.h.dh++ )
for ( rpos.h.dl = start_col ;
rpos.h.dl < (unsigned char) ( start_col + width );
rpos.h.dl++ ) {
int86( 0x10, &rpos, &rout );
rwrite.h.al = (unsigned char) save_buffer[ i ];
rwrite.h.bl = (unsigned char)(save_buffer[i++]>>8);
int86( 0x10, &rwrite, &rout );
}
}
// When a popup window is saved, the border has to be saved as
// well. The main window is saved in a standard row by column
// order in the save buffer. The border area is stored somewhat
// more haphazardly, right here.
void TextWindow::save_border( void )
{
union REGS rpos;
union REGS rread;
union REGS rout;
int i;
SaveCursor save_it;
if ( save_buffer == 0 )
return;
i = width * height;
rpos.h.ah = 2;
rpos.h.bh = 0;
rread.h.ah = 8;
rread.h.bh = 0;
for ( rpos.h.dl = (unsigned char) ( start_col - 1 );
rpos.h.dl < (unsigned char) ( start_col + width + 1 ) ;
rpos.h.dl++ ) {
rpos.h.dh = (unsigned char) ( start_row - 1 );
int86( 0x10, &rpos, &rout );
int86( 0x10, &rread, &rout );
save_buffer[ i++ ] = rout.x.ax;
rpos.h.dh = (unsigned char) ( start_row + height );
int86( 0x10, &rpos, &rout );
int86( 0x10, &rread, &rout );
save_buffer[ i++ ] = rout.x.ax;
}
for ( rpos.h.dh = start_row ;
rpos.h.dh < (unsigned char) ( start_row + height ) ;
rpos.h.dh++ ) {
rpos.h.dl = (unsigned char) ( start_col - 1 );
int86( 0x10, &rpos, &rout );
int86( 0x10, &rread, &rout );
save_buffer[ i++ ] = rout.x.ax;
rpos.h.dl = start_col;
rpos.h.dl = (unsigned char)( rpos.h.dl + width );
int86( 0x10, &rpos, &rout );
int86( 0x10, &rread, &rout );
save_buffer[ i++ ] = rout.x.ax;
}
}
// This protected function restores the border in the same odd
// order that it was saved.
void TextWindow::restore_border( void )
{
union REGS rpos;
union REGS rwrite;
union REGS rout;
int i;
SaveCursor save_it;
if ( save_buffer == 0 )
return;
i = width * height;
rpos.h.ah = 2;
rpos.h.bh = 0;
rwrite.h.ah = 9;
rwrite.h.bh = 0;
rwrite.x.cx = 1;
for ( rpos.h.dl = (unsigned char) ( start_col - 1 );
rpos.h.dl < (unsigned char)( start_col + width + 1 );
rpos.h.dl++ ) {
rpos.h.dh = (unsigned char) ( start_row - 1 );
int86( 0x10, &rpos, &rout );
rwrite.h.al = (unsigned char) save_buffer[ i ];
rwrite.h.bl = (unsigned char)( save_buffer[ i++ ] >> 8 );
int86( 0x10, &rwrite, &rout );
rpos.h.dh = (unsigned char) ( start_row + height );
int86( 0x10, &rpos, &rout );
rwrite.h.al = (unsigned char) save_buffer[ i ];
rwrite.h.bl = (unsigned char)( save_buffer[ i++ ] >> 8 );
int86( 0x10, &rwrite, &rout );
}
for ( rpos.h.dh = start_row;
rpos.h.dh < (unsigned char) ( start_row + height ) ;
rpos.h.dh++ ) {
rpos.h.dl = (unsigned char) ( start_col - 1 );
int86( 0x10, &rpos, &rout );
rwrite.h.al = (unsigned char) save_buffer[ i ];
rwrite.h.bl = (unsigned char) ( save_buffer[ i++ ] >> 8 );
int86( 0x10, &rwrite, &rout );
rpos.h.dl = (unsigned char) ( start_col + width );
int86( 0x10, &rpos, &rout );
rwrite.h.al = (unsigned char) save_buffer[ i ];
rwrite.h.bl = (unsigned char) ( save_buffer[ i++ ] >> 8 );
int86( 0x10, &rwrite, &rout );
}
}
// A popup window is just like a text window except that it
// has an automatic save buffer and save cursor. The constructor
// doesn't do anything except make a text window and then save
// it.
PopupWindow::PopupWindow( int r, int c, int w, int h )
: TextWindow( r, c, w, h )
{
save_window();
}
// This internal utility routine hides the cursor by moving it
// off the screen. It is used when in the menu code.
inline void hide_cursor( void )
{
union REGS r;
r.h.ah = 2;
r.h.dh = 25;
r.h.dl = 0;
r.h.bh = 0;
int86( 0x10, &r, &r );
}
int Menu( char *menu[] )
{
int items;
int maxlen;
int length;
int i;
int c;
int selection;
items = 0;
maxlen = 0;
while ( ( length = strlen( menu[ items ] ) ) != 0 ) {
items++;
if ( length > maxlen )
maxlen = length;
}
if ( items == 0 )
return -1;
PopupWindow w( 5, 25, maxlen + 2, items );
w.Clear();
w.AddBorder();
for ( i = 0 ; i < items ; i++ ) {
w.SetPosition( i, 1 );
w << menu[ i ];
}
selection = 0;
for ( ; ; ) {
w.SetAttribute( REVERSE_ATTRIBUTE );
w.SetPosition( selection, 1 );
w << menu[ selection ];
hide_cursor();
while ( ( c = w.ReadKey() ) == 0 )
;
w.SetAttribute( NORMAL_ATTRIBUTE );
w.SetPosition( selection, 1 );
w << menu[ selection ];
switch ( c ) {
case 27 : //Escape
return( -1 );
case 13 : // CR
return( selection );
case HOME :
selection = 0;
break;
case END :
selection = items - 1;
break;
case DOWN :
if ( selection < ( items - 1 ) )
selection++;
break;
case UP :
if ( selection > 0 )
selection--;
break;
default :
for ( i = ( selection + 1 ) % items ;
i != selection ;
i = ( i + 1 ) % items ) {
if (toupper(c)==toupper(menu[i][0]))
{
selection = i;
break;
}
}
break;
}
}
#ifdef _MSC_VER
return -1;// To pass /W4 under Microsoft, not really needed
#endif
}
int ReadLine( char *prompt, char *buffer, int length )
{
int c;
int count;
PopupWindow w( 5, 10, 60, 1 );
w.Clear();
w.AddBorder();
w << prompt << ' ';
count = 0;
for ( ; ; ) {
while ( ( c = w.ReadKey() ) == 0 )
;
switch ( c ) {
case ESC :
return 0;
case CR :
buffer[ count ] = '\0';
return 1;
case BS :
if ( count > 0 ) {
count--;
w << BS;
w << ' ';
w << BS;
}
break;
default :
if ( c >= ' ' && c <= 0x7f ) {
if ( count < length ) {
buffer[ count++ ] = (char) c;
w << c;
}
}
}
}
#ifdef _MSC_VER
return -1; // To pass /W4 under Microsoft, not really needed
#endif
}
// ReadKey returns a 0 if no key is ready. The _bios_keybrd()
// routine under Borland C++ has trouble if a Ctrl-Break has been
// pressed, so I replace it with the equivalet int86() function
// call for that compiler only.
int TextWindow::ReadKey( void )
{
#ifdef __TURBOC__
union REGS r;
r.h.ah = 1;
int86( 0x16, &r, &r );
if ( r.x.flags & 0x40 ) // Test for the zero flag
return 0;
r.h.ah = 0;
int86( 0x16, &r, &r );
if ( r.h.al != 0 )
return r.h.al;
else
return r.x.ax;
#else // #ifdef __TURBOC__
int c;
// Under Borland C, this function will never return true if CTRL-BREAK
// has been pressed, effectively closing the keyboard.
if ( _bios_keybrd( _KEYBRD_READY ) == 0 )
return 0;
c = _bios_keybrd( _KEYBRD_READ );
if ( ( c & 0xff ) == 0 ) // A normal ASCII key
return c;
else
return c & 0xff; // A function or other extended key
#endif // #ifdef __TURBOC__ ... #else
}
// This is an unsophisticated way to change to 43 line mode, or 50
// line mode on a VGA. Note that it doesn't disable EGA cursor
// emulation, so if you try to change the cursor size, strange things
// might happen. All this routine does to change modes is select the
// appropriate size font, 8x8 for 43 line mode, else 8x14 or 8x16.
void Set43LineMode( int control )
{
union REGS r;
if ( control ) {
r.h.ah = 0x11;
r.h.al = 0x12;
r.h.bl = 0;
int86( 0x10, &r, &r );
} else {
r.h.ah = 0x14; // Change to 11 for EGA
r.h.al = 0x12;
r.h.bl = 0;
int86( 0x10, &r, &r );
r.h.ah = 0;
r.h.al = 3; // Change to 2 for BW80
int86( 0x10, &r, &r );
}
}
// ****************** END OF TEXTWIND.CPP ******************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -