c # - Hvordan skal jeg oprette en brugerdefineret grafisk konsol/terminal på Windows?

Indlæg af Hanne Mølgaard Plasc

Problem



Windows-konsolgrænsefladen (tænk cmd vinduet er til brugeren en ret simpel GUI. Effektivitetsniveauet med hvilket det håndterer gengivelse, brugerindgang og scrolling er imidlertid meget højt. De metoder, der bruges til at oprette denne grænseflade, er utvivlsomt helt anderledes end dem, der findes i en traditionel desktop GUI.


Jeg er interesseret i at oprette min egen brugerdefinerede konsol/terminal til Windows, helst ved hjælp af C # og .NET-baserede teknologier (fx administreret GDI + eller WPF). Som udgangspunkt vil jeg være ganske opsat på at genskabe den standard simple Windows shell, så jeg kan udvide tingene og tilføje funktioner derfra.


Jeg leder efter generel vejledning om, hvordan man skal lave en sådan konsol-brugergrænseflade, men nogle specifikke punkter omfatter:



  • Hvilken slags model skal jeg bruge? En renderingsløkke? Delvis opdateringer (som WPF)? WinForms-modellen (ikke sikker på, hvordan dette virker)?

  • Hvilken slags caching bruges i renderingsmodellen?

  • Hvordan hentes skrifttyper og hvordan bliver de gengivet? Er de standard TrueType-skrifttyper, bitmap-skrifttyper eller noget andet?

  • Hvordan bliver rullet udført så effektivt?

  • Noget andet du mener er relevant!



Enhver forklaring på, hvordan det indbyggede Windows-konsol-brugergrænseflade (eller endda den overlegne Linux-terminalbruger) gør disse ting - og hvordan jeg kunne efterligne dem - ville være ideel.


Rediger: Jeg vil virkelig gøre det helt fra bunden for at være klar. Baseret på en grafisk ramme som GDI + eller WPF, men ikke mere.

Bedste reference


Jeg har en gang implementeret et tekstudskriftsvindue fra bunden - jeg ønskede en, der fungerer som Output-vinduet i Visual Studio. Det viste sig at være mere kompliceret end forventet, og det var uden input muligheder.


Desværre er koden i C ++ og tilhører en tidligere arbejdsgiver, så jeg kan ikke dele den med dig. Men jeg kan give dig en ide om hvad man kan forvente.


Du har brug for en måde at gemme produktionslinjerne på, som du kan indeksere hurtigt. Hvis du vil sætte en grænse for antallet af linjer, der vises, skal det også være nemt at slette linjer fra toppen. I C ++ a deque<string> var perfekt, ved jeg ikke, hvad ækvivalenten er ( hvis nogen) i C #.


Du skal bruge håndtere til følgende Windows-meddelelser, uden nogen særlig rækkefølge.



  • WM\_LBUTTONDOWN - for at starte et valg. Brug SetCapture til at spore musen, mens knappen er nede.

  • WM\_LBUTTONUP - for at afslutte et valg.

  • WM\_RBUTTONUP - oversæt til WM\_CONTEXTMENU.

  • WM\_CONTEXTMENU - for at få vist en menu med Copy/Cut/Paste og alt andet, du vil have.

  • WM\_KEYDOWN - for at svare på de 4 markørtaster, Home/End, PageUp/PageDown. Ctrl-A/ctrl-C/Ctrl-X/ctrl-V/ctrl-D.

  • WM\_PAINT - for at male indholdet i vinduet.

  • WM\_SIZE - for at opdatere scrollbarsne, når vinduets størrelse ændres.

  • WM\_VSCROLL - for at opdatere den synlige del af vinduet under lodret rulning.

  • WM\_HSCROLL - for at opdatere den synlige del af vinduet under vandret rulning.

  • WM\_CREATE - til initialisering, når vinduet oprettes.

  • WM\_SETFOCUS - for at oprette en systembilet for at vise den aktuelle position i vinduet.

  • WM\_KILLFOCUS - for at dræbe karmen, da kun det øjeblikkeligt fokuserede vindue skal vise en caret.

  • WM\_MOUSEMOVE - for at spore ændringer i markeringen, mens venstre museknap er nede.

  • WM\_CAPTURECHANGED - for at afslutte et valg.

  • WM\_TIMER - for at rulle automatisk, når markøren forlader vinduet under et valg.

  • WM\_GETDLGCODE - for at tilføje DLGC\_WANTARROWS, så piletasterne kommer igennem.

  • WM\_MOUSEWHEEL - for at reagere på musehjulet for at rulle.



Når linjer tilføjes til tekstbufferen, skal du justere rækkevidden af ​​rullebjælkerne. Det lodrette rullebjælkeområde er det samlede antal linjer, og det horisontale rullebjælkeområde er bredden af ​​den bredeste linje.


Det er bedst at have en enkelt skrifttype, som er monospaced - det gør beregningerne meget lettere. Den specifikke skrifttypeteknologi betyder ikke så meget. Du behøver blot at kunne spore tegnernes positioner.


Hvordan bliver rullet udført så effektivt? Du sporer de øverste og nederste linjer i vinduet, som det ruller, og når en malemeddelelse kommer, maler du kun de linjer, der er synlige. De andre er stadig i bufferen, men de bliver ikke rørt. Det er muligt at blinke vinduets indhold, mens det ruller og kun male de dele, der kommer ind fra toppen eller bunden, men med dagens processorer det 'En spildt indsats - vinduet vil gøre en fuld omsmudning så hurtigt, at du ikke kommer til at mærke.


Rediger: Tilfeldigvis kom jeg på tværs af denne Microsoft-guide til rullebjælker, som skal være afgørende for denne opgave. http://msdn.microsoft.com/en-us/library/windows/desktop/bb787527.aspx[16]

Andre referencer 1


Hvis du vil oprette en smuk. NET-baseret kommandoprompet udskiftning, foreslår jeg at se på http://poshconsole.codeplex.com/Det bruger WPF til grafiske elementer, og det implementerer en PowerShell script host. PowerShell er Microsoft's erstatning for den ærværdige kommandoprompt. PowerShell er som standard installeret med Windows 7, men du kan downloade den til XP og Vista. PowerShell er meget udvidelig, selvom scripting af .NET-objekter direkte. Det kan også indlejres i andre programmer. [17]


WPF + PowerShell ville være et godt udgangspunkt for, hvad du vil gøre. Hvis du ville have, kan du så bytte PowerShell til din egen kommando/scripting engine. Hvis du var virkelig ambitiøs, kunne du tage en klynge ved at implementere dit eget skriptsprog på DLR for at fungere som din kommandotolker.


Held og lykke.

Andre referencer 2


Se på konsolets open source-projekt. Det gør meget, og gør det meget godt. Det giver en samlet konsol til det, der er karakterbaseret. Jeg kører cmd, bash og python hver i deres egen fane. [18]


Det er i C + + og det vil ikke give det sjovt at skrive det selv selv.

Andre referencer 3


Jeg havde stor succes med RichTextBox til output. Faktisk gør det alt hvad du måtte ønske: farve tilpasning, effektiv rendering og scrolling, udklipsholder operationer osv. Indgangen blev organiseret ved at opfange KeyPress begivenheder i vinduet.

Andre referencer 4


Hvis hastigheden er afgørende, er XNA en meget hurtig måde (minimal kodning) for at tegne din tekst med høj hastighed. Den kan håndtere tusindvis af sprites ved 100 's af FPS. Ved hjælp af SpriteBatch :: DrawString () og SpriteFont kan du få en high-speed' konsol 'med meget lidt kodningsindsats. Standard' Game '-klassen kan ændres for at blive -drager kun underområder på skærmen, der kræves på forespørgsel. Advarsler omfatter ufuldstændig kerning, der vil give teksten et sløret udseende (du kan muligvis løse dette ved at slukke for anti-aliasing og være forsigtig med dine fremskrivninger og sprite placering). Hvis dette er et problem, så tilbyder Direct2D måske en bedre løsning (eller nogen af ​​de allerede nævnte løsninger).

Andre referencer 5


Som en første og simpel tilgang ville jeg bruge en TextBox i multi-line mode. Se efter arrangementerne TextChanged eller KeyPressed eller KeyUp og handle i overensstemmelse hermed. Senere kan du oprette din egen kontrol ved at udlede en fra en simpel Panel kontrol. Rendering sker ved at overstyre OnPaint metoden (WinForms). Der kræves ingen sløjfe, kun et opkald til Invalidate eller Refresh.


Brug en streng array eller en List<string> eller en LinkedList<string> som linje buffer eller brug bare den tekst, der er gemt i tekstboksen.


Hvis du opretter din egen kontrol med WinForms, er System.Windows.Forms.TextRenderer et godt valg til gengivelse af tekst. Det vil blive brugt i OnPaint.


Scrolling er en vanskelig ting, hvis du opretter din egen kontrol. System.Windows.Controls.Panel indeholder allerede scrolling support, men du skal stadig fortælle kontrollen, hvordan du placerer og størrelse rulleknappens knapper, når teksten ændres. På den anden side har du flyttet din tekst, når brugeren flytter rullestænger og for at opdatere displayet i overensstemmelse hermed. Ydeevne bør ikke være et problem for en så enkel kontrol.

Andre referencer 6


FastColoredTextBox-projektet på github'en har et eksempel på Konsol . Det er: [19]



  • Effektiv og hurtig

  • Farvet

  • Fås i WPF og WinForm

  • I C # og let at læse



Jeg tror, ​​at læsningen af ​​koden vil hjælpe dig meget.