2013-02-21 7 views
6

Podobnie jak Vim: Po uruchomieniu powoduje przejście do innego "bufora". Kiedy vim się zamyka, użytkownik widzi poprzednią zawartość wiersza poleceń.Jak zrobić aplikację konsoli C# dla systemu Windows, która "respektuje" poprzednią zawartość konsoli?

Czy ktoś wie, jak to zrobić przy użyciu C#?

Dzięki

Edit: Użytkownik nie będzie już zobaczyć wyjście z aplikacji. Mam nadzieję, że lepiej to wyjaśni.

+1

Opisywany przez Ciebie przykład to sposób, w jaki aplikacja konsolowa C# będzie działać, jeśli zostanie wywołana z wiersza poleceń; jeśli uruchomisz aplikację konsolową, a następnie ją zamkniesz, powrócisz do poprzedniej linii poleceń. Czy może czegoś brakuje? – Dutts

+0

Myślę, że plakat oznacza, że ​​żadne wyjście z aplikacji nie powinno już być na konsoli, ale raczej to, co było przed wykonaniem. – Matt

+0

@Richard Aplikacje, takie jak dir lub cat, będą wypluwać na tym samym "buforze" konsoli. Aplikacje takie jak vim przerysowują dużo tekstu w oknie konsoli, ale po jego zamknięciu użytkownik powraca do wyświetlania poleceń, które wpisał, w tym vim. Całe wyjście, które vim włożył do okna, zniknęło. Daj mi znać, jeśli nie wyjaśniam się poprawnie – robertoprs

Odpowiedz

4

I zdobione to patrząc na Vim source code odpowiednie bity można znaleźć w os_win32.c w funkcji mch_init, ja „ve kopiowane i wklejane odpowiedni kawałek tutaj

/* Obtain handles for the standard Console I/O devices */ 
    if (read_cmd_fd == 0) 
    g_hConIn = GetStdHandle(STD_INPUT_HANDLE); 
    else 
    create_conin(); 
    g_hConOut = GetStdHandle(STD_OUTPUT_HANDLE); 

#ifdef FEAT_RESTORE_ORIG_SCREEN 
    /* Save the initial console buffer for later restoration */ 
    SaveConsoleBuffer(&g_cbOrig); 
    g_attrCurrent = g_attrDefault = g_cbOrig.Info.wAttributes; 
#else 
    /* Get current text attributes */ 
    GetConsoleScreenBufferInfo(g_hConOut, &csbi); 
    g_attrCurrent = g_attrDefault = csbi.wAttributes; 
#endif 
    if (cterm_normal_fg_color == 0) 
    cterm_normal_fg_color = (g_attrCurrent & 0xf) + 1; 
    if (cterm_normal_bg_color == 0) 
    cterm_normal_bg_color = ((g_attrCurrent >> 4) & 0xf) + 1; 

    /* set termcap codes to current text attributes */ 
    update_tcap(g_attrCurrent); 

    GetConsoleCursorInfo(g_hConOut, &g_cci); 
    GetConsoleMode(g_hConIn, &g_cmodein); 
    GetConsoleMode(g_hConOut, &g_cmodeout); 

#ifdef FEAT_TITLE 
    SaveConsoleTitleAndIcon(); 
    /* 
    * Set both the small and big icons of the console window to Vim's icon. 
    * Note that Vim presently only has one size of icon (32x32), but it 
    * automatically gets scaled down to 16x16 when setting the small icon. 
    */ 
    if (g_fCanChangeIcon) 
    SetConsoleIcon(g_hWnd, g_hVimIcon, g_hVimIcon); 
#endif 

Więc to po prostu zapisuje informacje konsoli (w tym tytuł i ikony), a następnie przywraca go ponownie na wyjeździe.

Niestety klasa nie zapewnia dostępu do zawartości bufora ekranowego, więc w tym celu będziesz potrzebował P/Invoke do odpowiednich funkcji Win32.

Alternatywnie konsoli Win32 faktycznie obsługuje multiple screen buffers który może być łatwiejszy sposób zaimplementować to - zamiast skopiować istniejący bufor ekranu po prostu stworzyć nową z CreateConsoleScreenBuffer i ustawić ten bufor, aby być jedną aktualnie wyświetlane przy użyciu SetConsoleActiveScreenBuffer. Znowu klasa Console nie obsługuje wielu buforów ekranowych, więc do tego celu będzie potrzebne P/Invoke. Również klasa Console zawsze zapisuje do bufora ekranu, który był aktywny w momencie uruchomienia aplikacji, więc jeśli wymienisz aktywny bufor ekranu, klasa Console nadal będzie zapisywać do starego bufora ekranu (który nie jest już widoczny) - aby obejść ten problem, musisz P/wywołać cały dostęp do konsoli, patrz Working with Console Screen Buffers in .NET.

+0

Dzięki! Masz rację, powinienem spojrzeć na kod. Zapominam, że niektóre projekty są nadal otwarte, nawet w świecie Windows. Wpadłem na CreateConsoleScreenBuffer dzięki odpowiedzi jgauffina, ale zapisanie stanu poprzedniego bufora to świetny pomysł! – robertoprs

+1

Wyłącza zapisywanie oryginalnej zawartości bufora, ponieważ jest ona czyszczona, gdy bufor nie jest aktywny. – robertoprs

-3

Wierzę, że Vim rejestruje swoją historię otwartych plików i prawdopodobnie buforuje je również, jak kopię zapasową. Pomysł, aby zrobić to samo w języku C#, to zaimplementowanie bufora plików, pewien rodzaj pamięci, który rejestrowałby i śledziłby wybrane elementy - parametry wejściowe, itp.

Kolejny problem polega na tym, że Vim (podobnie jak Vi) ma tryb poleceń, który trzeba by zaimplementować również w języku C#. Teraz to zależy od tego, co dokładnie chcesz osiągnąć za pomocą programu C#, czy to jest edytor, to dobrze, w każdym razie musisz rozróżnić tryb poleceń od innych.

+1

Ma to niewiele wspólnego z pytaniem. – hvd

+0

Sądzę, że pytanie OP było trochę uderzone w ciemność - wcale nie było łatwe do zrozumienia. Odpowiedziałem na to, co uważałem za poprawne. –

+1

Pytanie ma dla mnie sens. Otwórz wiersz polecenia. Zacznij vim. Zauważ, jak vim pojawia się w tym samym oknie. Wyjdź z vim. Zwróć uwagę, że żadne kawałki vima nie są widoczne. Teraz pytanie brzmi: jak to zrobić, pracując z C#. – hvd

0

Można to zrobić pisząc starą zawartość do bufora konsoli, jak opisano tutaj: How can I write fast colored output to Console?

+0

.. jak zamierzasz uzyskać starą zawartość? –

+0

Przegłosowałem to, ponieważ uznałem, że jest ono przydatne. Nie wiedziałem o PInvoke, więc nie wiedziałem, że mogę wywoływać interfejsy API Win32 z kodu C#. Dzięki temu znalazłem CreateConsoleScreenBuffer. Odpowiedź Justina jest bardziej szczegółowa, ale to wystarczyło, by mnie odblokować. – robertoprs

Powiązane problemy