⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textwind.cpp

📁 DOS下采用中断接收数据的串口通讯的例子,很难找到的好东西!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ****************** START OF TEXTWIND.CPP ******************
//
//
//
// This file contains all of the code needed to support the
// Text Windows used for example programs in this book.  These
// are "quick and dirty" text windows, using the BIOS for most of
// the work.

#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include <ctype.h>
#include <bios.h>
#include "textwind.h"

// This static data member keeps track of how many windows are
// open.  When the count drops to zero, cleanup work can be done.

int TextWindow::count = 0;

// write_char uses the BIOS function to write the current
// character using the window attribute.  This function is a
// protected member function, and is used by the << operator.

inline void TextWindow::write_char( unsigned char c )
{
    union REGS r;

    r.h.ah = 9;
    r.h.al = c;
    r.h.bl = attribute;
    r.h.bh = 0;
    r.x.cx = 1;
    int86( 0x10, &r, &r );
}

// This protected function uses the BIOS parameter to write a
// single character repeatedly.  This is much faster than writing
// individual characters in a loop.  It is used when writing the
// border and clearing the screen.

inline void TextWindow::write_repeated_chars( unsigned char c, 
                                              int count )
{
    union REGS r;

    r.h.ah = 9;
    r.h.al =  c;
    r.h.bl =  attribute;
    r.x.cx = count;
    r.h.bh = 0;
    int86( 0x10, &r, &r );
}

// This protected member function positions the cursor at the
// desired position relative to the text window.  The protected
// function doesn't check for validity of the row and column
// values.  It also doesn't set the row and column data
// members.

inline void TextWindow::position( int r, int c )
{
    union REGS rin;

    r += start_row;
    c += start_col;
    rin.h.ah = 2;
    rin.h.dh = (unsigned char) r;
    rin.h.dl = (unsigned char) c;
    rin.h.bh = 0;
    int86( 0x10, &rin, &rin );
}

// This public member function positions the cursor in a
// window.  It also stores the new position in the row and column
// data members.

int TextWindow::SetPosition( int r, int c )
{
    union REGS rin;

    if ( r < 0 || c < 0 )
        return 0;
    if ( r >= (int) height || c >= (int) width )
        return 0;
    row = (unsigned char) r;
    col = (unsigned char) c;
    r += start_row;
    c += start_col;
    rin.h.ah = 2;
    rin.h.dh = (unsigned char) r;
    rin.h.dl = (unsigned char) c;
    rin.h.bh = 0;
    int86( 0x10, &rin, &rin );
    return 1;
}

// This public member function positions the cursor in the current
// location of the window defined by *this.

void TextWindow::Goto( void )
{
    union REGS rin;

    rin.h.ah = 2;
    rin.h.dh = (unsigned char) ( row + start_row );
    rin.h.dl = (unsigned char) ( col + start_col );
    rin.h.bh = 0;
    int86( 0x10, &rin, &rin );
}

// This public function uses the BIOS to scroll a text window.

inline void TextWindow::Scroll( unsigned char line_count )
{
    union REGS r;

    r.h.ah = 6;
    r.h.al = line_count;
    r.h.ch = start_row;
    r.h.cl = start_col;
    r.h.dh = (unsigned char) ( start_row + height - 1 );
    r.h.dl = (unsigned char) ( start_col + width - 1 );
    r.h.bh = attribute;
    int86( 0x10, &r, &r );
}

// This routine writes a formated character to the output
// window.  Special processing is performed for the CR, LF, and
// BS keys.

BaseWindow& TextWindow::operator<<( char c )
{
    switch ( c ) {
        case '\r' :
            col = 0;
            break;
        case '\n' :
            col = 0;
        row += 1;
            break;

        case '\b' :
            if ( col > 0 )
                col--;
            break;
        default :
            position( row, col );
            write_char( c );
            col++;
            if ( col >= width ) {
                if ( wrap ) {
                    col = 0;
                    row++;
                } else
                    col--;
            }
    }
    if ( row >= height ) {
        row = (unsigned char) ( height - 1 );
        Scroll( 1 );
    }
    position( row, col );
    return *this;
}

// This routine writes a formated string to the output
// window.  Special processing is performed for the CR, LF, and
// BS keys.

BaseWindow& TextWindow::operator<<( char *s )
{
    unsigned char c;

    while ( ( c = *s++ ) != '\0' ) {
        switch ( c ) {
            case '\r' :
                col = 0;
                break;
            case '\n' :
                col = 0;
                row += 1;
                break;
            case '\b' :
                if ( col > 0 )
                    col--;
                break;
            default :
                position( row, col );
                write_char( c );
                col++;
                if ( col >= width ) {
                    if ( wrap ) {
                        col = 0;
                        row += 1;
                    } else
                        col--;
                }
                break;
        }
        if ( row >= height ) {
            row = (unsigned char) ( height - 1 );
            Scroll( 1 );
        }
        position( row, col );
    }
    return *this;
}

BaseWindow& TextWindow::operator<<( int c )
{
    return operator<<( (char) c );
}

// The only constructor for a text window just defines the
// starting row and column, and the width and height.
// Constructing a window doesn't actually draw anything on the
// screen.

TextWindow::TextWindow( int r, int c, int w, int h )
{
    count++;
    start_row = (unsigned char ) r;
    start_col = (unsigned char ) c;
    width = (unsigned char) w;
    height = (unsigned char) h;
    border = 0;
    save_buffer = 0;
    row = 0;
    col = 0;
}

// The destructor for a text window restores any saved data
// that was under the window.  It also repositions the cursor if
// the last window was just closed.

TextWindow::~TextWindow( void )
{
    if ( save_buffer ) {
        restore_window();
        if ( border )
            restore_border();
        delete[] save_buffer;
    }
    count--;
    if ( count == 0 ) {
        start_row = 0;
        start_col = 0;
        position( 23, 0 );
    }
}

// Clearing the window is easy.

void TextWindow::Clear( void )
{
    Scroll( 0 );
}

// This function writes the border out around the window.  If
// a save buffer has been established, the data under the border
// is saved.

void TextWindow::AddBorder( void )
{
    unsigned char r;
    SaveCursor a;

    if ( save_buffer && border == 0 )
        save_border();
    border = 1;
    position( -1, -1 );
    write_char( 218 );
    position( -1, width );
    write_char( 191 );
    position( height, -1 );
    write_char( 192 );
    position( height, width );
    write_char( 217 );
    for ( r = 0 ; r < height ; r++ ) {
        position( r, -1 );
        write_char( 179 );
        position( r, width );
        write_char( 179 );
    }
    position( -1, 0 );
    write_repeated_chars( 196, width );
    position( height, 0 );
    write_repeated_chars( 196, width );
}

// The title just gets displayed on top of the border.

void TextWindow::DisplayTitle( char *s )
{
    int col = 0;

    if ( ( strlen( s ) + 2 ) > width )
        return;
    if ( !border )
        AddBorder();
    SaveCursor save_it;
    position( -1, col++ );
    write_char( 180 );
    while ( *s ) {
        position( -1, col++ );
        write_char( *s++ );
    }
    position( -1, col );
    write_char( 195 );
}

// Popup windows save the area under the window.  This
// function saves the main window, another one saves the border
// area.

void TextWindow::save_window( void )
{
    union REGS rpos;
    union REGS rread;
    union REGS rout;
    int i;
    SaveCursor save_it;

// Allocate enough space for the window plus the border.  To 
// simplify the storage issues, I treat the save buffer as the 
// screen array followed by a border array.  The border array 
// will have weird indexing, but the screen array won't.

    if ( save_buffer == 0 )
        save_buffer = new unsigned int[(width+2)*(height+2)];
    if ( save_buffer ) {
        i = 0;
        rpos.h.ah = 2;
        rpos.h.bh = 0;
        rread.h.ah = 8;
        rread.h.bh = 0;
        for ( rpos.h.dh = start_row ;
              rpos.h.dh < (unsigned char) (start_row+height);
              rpos.h.dh++ )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -