Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

RE: Innenleben von PRINT

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
RatsDevSoftware



Anmeldungsdatum: 22.11.2007
Beiträge: 48

BeitragVerfasst am: 13.03.2008, 17:59    Titel: RE: Innenleben von PRINT Antworten mit Zitat

(echt traurig, dass man jetzt schon "RE: "-threads braucht peinlich )

Auf http://www.freebasic.net/index.php/download kann man den src der libs runterladen...

in der libfb-v0.18.3b-src.zip findet man im directory src\rtlib\win32 die platformabhängigen befehle für windows (u.a. I/O (größtenteils))...

da dürften interessant sein:
libfb_io_printbuff.c
libfb_io_printbuff_wstr.c
libfb_io_printer.c

am ehesten wohl die libfb_io_printbuff.c für die normale konsole:
Code:

/*
 *  libfb - FreeBASIC's runtime library
 *   Copyright (C) 2004-2007 The FreeBASIC development team.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  As a special exception, the copyright holders of this library give
 *  you permission to link this library with independent modules to
 *  produce an executable, regardless of the license terms of these
 *  independent modules, and to copy and distribute the resulting
 *  executable under terms of your choice, provided that you also meet,
 *  for each linked independent module, the terms and conditions of the
 *  license of that module. An independent module is a module which is
 *  not derived from or based on this library. If you modify this library,
 *  you may extend this exception to your version of the library, but
 *  you are not obligated to do so. If you do not wish to do so, delete
 *  this exception statement from your version.
 */

/*
 * io_printbuff.c -- low-level print to console function for Windows
 *
 * chng: oct/2004 written [v1ctor]
 *       nov/2004 fixed scrolling problem if printing at Bottom/Right w/o a newline [v1ctor]
 *       sep/2005 re-implemented all printing stuff [mjs]
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fb_con.h"

typedef struct _fb_PrintInfo {
    fb_Rect         rWindow;
    fb_Coord        BufferSize;
    WORD            wAttributes;
    HANDLE          hOutput;
    int             fViewSet;
} fb_PrintInfo;

static
void fb_hHookConScroll(struct _fb_ConHooks *handle,
                       int x1,
                       int y1,
                       int x2,
                       int y2,
                       int rows)
{
    fb_PrintInfo *pInfo = (fb_PrintInfo*) handle->Opaque;
    HANDLE hnd = pInfo->hOutput;
    int iBufferHeight, iScrollHeight, iClearFrom, iClearTo, iClearPos;

    SMALL_RECT srScroll;
    COORD dwDest;

    if( !pInfo->fViewSet ) {
        /* Try to move the window first ... */
        if( (handle->Border.Bottom+1) < pInfo->BufferSize.Y ) {
            int remaining = pInfo->BufferSize.Y - handle->Border.Bottom - 1;
            int move_size = ((remaining < rows) ? remaining : rows);

            handle->Border.Top += move_size;
            handle->Border.Bottom += move_size;

            rows -= move_size;
            if( rows==0 )
                return;
        }

        /* We're at the end of the screen buffer - so we have to
         * scroll the complete screen buffer */
        dwDest.X = dwDest.Y = 0;
        srScroll.Right = (SHORT) (pInfo->BufferSize.X-1);
        srScroll.Bottom = (SHORT) (pInfo->BufferSize.Y-1);
        iBufferHeight = pInfo->BufferSize.Y;

    } else {
        /* Scroll only the area defined by a previous VIEW PRINT */
        dwDest.X = (SHORT) handle->Border.Left;
        dwDest.Y = (SHORT) handle->Border.Top;
        srScroll.Right = (SHORT) handle->Border.Right;
        srScroll.Bottom = (SHORT) handle->Border.Bottom;
        iBufferHeight = handle->Border.Bottom - handle->Border.Top + 1;
    }

    if( iBufferHeight <= rows ) {
        /* simply clear the buffer */
        iClearFrom = handle->Border.Top;
        iClearTo = handle->Border.Bottom + 1;
    } else {
        /* Move some part of the console screen buffer to another
         * position. */
        CHAR_INFO FillChar;

        srScroll.Left = dwDest.X;
        srScroll.Top = (SHORT) (dwDest.Y + rows);

        iScrollHeight = srScroll.Bottom - srScroll.Top + 1;
        if( iScrollHeight < rows ) {
            /* Don't forget that we have to clear some screen buffer regions
             * not covered by the original scrolling region */
            iClearFrom = dwDest.Y + iScrollHeight;
            iClearTo = srScroll.Bottom + 1;
        } else {
            iClearFrom = iClearTo = 0;
        }

        FillChar.Attributes = pInfo->wAttributes;
        FillChar.Char.AsciiChar = 32;

        ScrollConsoleScreenBuffer( hnd, &srScroll, NULL, dwDest, &FillChar );
    }

    /* Clear all parts of the screen buffer not covered by the scrolling
     * region */
    if( iClearFrom!=iClearTo ) {
        SHORT x1 = handle->Border.Left;
        WORD attr = pInfo->wAttributes;
        DWORD width = handle->Border.Right - x1 + 1;
        for( iClearPos=iClearFrom; iClearPos!=iClearTo; ++iClearPos ) {
            DWORD written;
            COORD coord = { x1, (SHORT) iClearPos };
            FillConsoleOutputAttribute( hnd, attr, width, coord, &written);
            FillConsoleOutputCharacter( hnd, ' ', width, coord, &written );
        }
    }

    handle->Coord.Y = handle->Border.Bottom;
}

static
int  fb_hHookConWrite (struct _fb_ConHooks *handle,
                       const void *buffer,
                       size_t length )
{
    fb_PrintInfo *pInfo = (fb_PrintInfo*) handle->Opaque;
    HANDLE hnd = pInfo->hOutput;
    const char *pachText = (const char *) buffer;
    CHAR_INFO *lpBuffer = alloca( sizeof(CHAR_INFO) * length );
    WORD wAttributes = pInfo->wAttributes;
    COORD dwBufferSize = { (SHORT) length, 1 };
    COORD dwBufferCoord = { 0, 0 };
    SMALL_RECT srWriteRegion = {
        (SHORT) handle->Coord.X,
        (SHORT) handle->Coord.Y,
        (SHORT) (handle->Coord.X + length - 1),
        (SHORT) handle->Coord.Y
    };
    size_t i;
    int result;

    for( i=0; i!=length; ++i ) {
        CHAR_INFO *pCharInfo = lpBuffer + i;
        pCharInfo->Attributes = wAttributes;
        pCharInfo->Char.AsciiChar = pachText[i];
    }
    result = WriteConsoleOutput( hnd,
                                 lpBuffer,
                                 dwBufferSize,
                                 dwBufferCoord,
                                 &srWriteRegion );
    return result;
}

/*:::::*/
void fb_ConsolePrintBufferEx( const void *buffer, size_t len, int mask )
{
    const char *pachText = (const char *) buffer;
    int win_left, win_top, win_cols, win_rows;
    int view_top, view_bottom;
    fb_PrintInfo info;
    fb_ConHooks hooks;

    /* Do we want to correct the console cursor position? */
    if( (mask & FB_PRINT_FORCE_ADJUST)==0 ) {
        /* No, we can check for the length to avoid unnecessary stuff ... */
        if( len==0 )
            return;
    }

    FB_LOCK();

    if( FB_CONSOLE_WINDOW_EMPTY() ) {
        /* output was redirected! */
        DWORD dwBytesWritten;
        while( len!=0 &&
               WriteFile( __fb_out_handle,
                          pachText,
                          len,
                          &dwBytesWritten,
                          NULL ) == TRUE )
        {
            pachText += dwBytesWritten;
            len -= dwBytesWritten;
        }
        FB_UNLOCK();
        return;
    }

   fb_ConsoleGetView( &view_top, &view_bottom );
    fb_hConsoleGetWindow( &win_left, &win_top, &win_cols, &win_rows );

    hooks.Opaque        = &info;
    hooks.Scroll        = fb_hHookConScroll;
    hooks.Write         = fb_hHookConWrite ;
    hooks.Border.Left   = win_left;
    hooks.Border.Top    = win_top + view_top - 1;
    hooks.Border.Right  = win_left + win_cols - 1;
    hooks.Border.Bottom = win_top + view_bottom - 1;

    info.hOutput        = __fb_out_handle;
    info.rWindow.Left   = win_left;
    info.rWindow.Top    = win_top;
    info.rWindow.Right  = win_left + win_cols - 1;
    info.rWindow.Bottom = win_top + win_rows - 1;
    info.fViewSet       = hooks.Border.Top!=info.rWindow.Top
        || hooks.Border.Bottom!=info.rWindow.Bottom;

    {
        CONSOLE_SCREEN_BUFFER_INFO screen_info;

        if( !GetConsoleScreenBufferInfo( __fb_out_handle, &screen_info ) ) {
            hooks.Coord.X = hooks.Border.Left;
            hooks.Coord.Y = hooks.Border.Top;
            info.BufferSize.X = FB_SCRN_DEFAULT_WIDTH;
            info.BufferSize.Y = FB_SCRN_DEFAULT_HEIGHT;
            info.wAttributes = 7;
        } else {
            hooks.Coord.X = screen_info.dwCursorPosition.X;
            hooks.Coord.Y = screen_info.dwCursorPosition.Y;
            info.BufferSize.X = screen_info.dwSize.X;
            info.BufferSize.Y = screen_info.dwSize.Y;
            info.wAttributes = screen_info.wAttributes;
        }

        if( __fb_con.scrollWasOff ) {
            __fb_con.scrollWasOff = FALSE;
            ++hooks.Coord.Y;
            hooks.Coord.X = hooks.Border.Left;
            fb_hConCheckScroll( &hooks );
        }

        fb_ConPrintTTY( &hooks,
                        pachText,
                        len,
                        TRUE );

        if( hooks.Coord.X != hooks.Border.Left
            || hooks.Coord.Y != (hooks.Border.Bottom+1) )
        {
            fb_hConCheckScroll( &hooks );
        }
        else
        {
            __fb_con.scrollWasOff = TRUE;
            hooks.Coord.X = hooks.Border.Right;
            hooks.Coord.Y = hooks.Border.Bottom;
        }

        {
            COORD dwCoord = { (SHORT) hooks.Coord.X, (SHORT) hooks.Coord.Y };
            SetConsoleCursorPosition( info.hOutput,
                                      dwCoord );
        }
    }

    if( hooks.Border.Top!=win_top && !info.fViewSet ) {
        /* Now we have to ensure that the window shows the right part
         * of the screen buffer when it was moved previously ... */
        SMALL_RECT srWindow =
        {
            (SHORT) hooks.Border.Left,
            (SHORT) hooks.Border.Top,
            (SHORT) hooks.Border.Right,
            (SHORT) hooks.Border.Bottom
        };
        SetConsoleWindowInfo( info.hOutput, TRUE, &srWindow );
    }

    fb_hUpdateConsoleWindow( );

    FB_UNLOCK();
}

/*:::::*/
void fb_ConsolePrintBuffer( const char *buffer, int mask )
{
    return fb_ConsolePrintBufferEx( buffer, strlen(buffer), mask );
}


Die Funktion fb_hHookConWrite scheint etwas in die konsole zu schreiben, die funktion fb_hHookConScroll scheint die konsole zu scrollen...

die funktion fb_ConsolePrintBuffer scheint wohl dann das "endgültige" frontend zu sein...
_________________
visit our Homepage!
shift ist verschwendung...
...o gott - ich fang schon wieder an zu spammen...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
RatsDevSoftware



Anmeldungsdatum: 22.11.2007
Beiträge: 48

BeitragVerfasst am: 22.03.2008, 15:10    Titel: Antworten mit Zitat

Und wer's gerne FB-Style will. für den habe ich auch die Beispiele aus der MSDN zu einer Demolib zusammenübersetzt:
http://www.freebasic-portal.de/index.php?s=code&id=121
_________________
visit our Homepage!
shift ist verschwendung...
...o gott - ich fang schon wieder an zu spammen...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz