Text-Scrollen ohne Sprites und Gadgets in Windows

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Pollux
Beiträge: 23
Registriert: 23.09.2010 18:46
Computerausstattung: Eigenbau: CPU Intel i7-960 Windows 7 64-Bit 12 GB RAM
Toshiba Notebook Windows XP 32-Bit
weitere
Wohnort: Gilching bei München

Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von Pollux »

Soweit ich sehen konnte wird das Scrollen von Text in einem Fenster hier im Forum im Wesendlichen mit Sprites oder Gadgets gelöst. Daher möchte ich als Anregung einmal eine etwas andere Lösung vorschlagen, die auf dem PureBasic-Befehl 'GrabDrawingImage' beruht. Wie das genau funktioniert steht in den Kommentaren.

Da der Scroll-Bereich rahmenlos ist, wird das Programm durch einen Tastendruck auf der Tastatur beendet. Dazu muß das rahmenlose Fenster allerdings den Fokus haben.

Das Programm wurde unter Win7 als 64- und 32-Bit-Version getestet.

Hier die Include-Datei 'ScrollingUpTextWindow.pbi':

Code: Alles auswählen

;***********************************************************************************************************************
;* Diese hier in einer Include-Datei zusammengefaßten Prozeduren erzeugen einen randlosen Ausgabebereich, in den Text- *
;* zeilen ausgegeben werden könne. Bei jeder neuen Text-Zeile scrollen die schon vorhandenen Zeilen nach oben und die  *
;* neue Text-Zeile wird als unterste Zeile angezeigt.Die oben aus dem Bereich heraus-scrollenden Zeilen gehen verloren.*
;* Der Bereich verfügt über einen eigenen Buffer, so daß er bei Auftreten des Events #PB_Event_Repaint ohne Probleme   *
;* neu gezeichnet werden kann.                                                                                         *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Für PureBasic 4.50 unter Windows programmiert von: Jürgen Priess (09.2010)                                          *
;***********************************************************************************************************************
EnableExplicit

Structure  SUTW_STRUK ;Von dem ScrollingUpTextWindwo benötigte Struktur mit den zu verwendenden Parametern
  WindowIdNr.l   ;Wird von SUTW_Open zur Speicherung der Windows-Nummer intern verwendet
  ImageIdNr.l    ;Wird von SUTW_Open zur Speicherung der Image-Nummer intern verwendet
  FontIdNr.l     ;PureBasic Font-Nummer für den auszugebenden Text
  TopLeftX.l     ;X-Bildschirm-Koordinate der linken oberen Ecke
  TopLeftY.l     ;Y-Bildschirm-Koordinate der linken oberen Ecke
  ClientWidth.l  ;Breite des Client-Bereichs in Pixel
  ClientHeight.l ;Höhe des Client-Bereichs in Pixel
  FontHeight.l   ;Font-Größe in Pixel
  FontColor.l    ;Font-Farbe
  WinBackColor.l ;Hintergrund-Farbe
  SpacingY.l     ;Zeilen-Abstand in Pixel
  SpacingX.l     ;Abstand des Textes vom linken RAnd in Pixel
EndStructure

Procedure.l SUTW_Open(*SUTW.SUTW_STRUK)
;***********************************************************************************************************************
;* Es wird ein rahmenloses Fenster gemäß den den der übergebenen Struktur angegeben Werte  angelegt und ein um eine    *
;* Ausgabezeile längeres Image. Das Image wird mit der in der Struktur übergebenen Hintergrund-Farbe gefüllt.          *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Parameter: *SUTW.SUTW_STRUK: Ein Pointer auf einen SUTW_STRUK Bereich, der die benötigten Parameter enthält.        *
;*                              Die Bedeutung der verschiedenen Werte geht aus der obigen Struktur-Beschreibung hervor.*
;*                              Die Werte werden ungeprüft verwendet.                                                  *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Return: 1 bei erfolg; 0 sonst.                                                                                      *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Die Parameterübergabe ist in dieser Form gewählt worden, um eine ellenlange Parameter-Liste zu vermeiden.           *
;* Die Prozedur zeigt außerdem, daß man trotz Pointer-Übergabe durch angabe der Struktur auf die zugrunde liegenden    *
;* Struktur-Elemente zugreifen kann.                                                                                   *
;***********************************************************************************************************************

Protected Flag.l  = #PB_Window_BorderLess

With *SUTW
  
  \WindowIdNr = OpenWindow(#PB_Any,\TopLeftX,\TopLeftY,\ClientWidth,\ClientHeight,"",Flag)
  
  If \WindowIdNr
    
    \ImageIdNr = CreateImage(#PB_Any,\ClientWidth,\ClientHeight+(\FontHeight)+(\SpacingY))
    
    If \ImageIdNr
      If StartDrawing(ImageOutput(\ImageIdNr))
        DrawingMode(#PB_2DDrawing_Default)
        Box(0,0,\ClientWidth,\ClientHeight+(\FontHeight)+(\SpacingY),\WinBackColor)
        StopDrawing()
        ProcedureReturn 1 ;Bei Erfolg
      EndIf
    EndIf
    
  EndIf

  ProcedureReturn 0 ;Im Fehlerfall
  
EndWith

EndProcedure

Procedure.l SUTW_PrintN(*SUTW.SUTW_STRUK,Text.s="")
;***********************************************************************************************************************
;* Dies ist der Text-Ausgabe-Befehl für das ScrollingUpTextWindow. Der schon vorhanden Text wird um eine Zeile nach    *
;* oben geschoben und die frei werdende Zeile wird mit dem angegebenen Text gefüllt.                                   *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Parameter: *SUTW.SUTW_STRUK: Ein Pointer auf einen SUTW_STRUK Bereich, der die benötigten Parameter enthält.        *
;*                              Die Bedeutung der verschiedenen Werte geht aus der obigen Struktur-Beschreibung hervor.*
;*                              Die Werte werden ungeprüft verwendet.                                                  *
;*            Text:             Der auszugebende Text. Wenn er zu lang ist, wird er am rechten Rand abgeschnitten.     *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Return:    1 bei erfolg; 0 sonst.                                                                                   *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Mit GrabDrawingImage wird der schon vorhandene Text ab der 2.Zeile in ein neues Image gespeichert und dann um eine  *
;* Zeile nach oben versetzt von diesem auf das in SUTW_Open angelegte Image kopiert. Danach kann das neue Image        *
;* wieder freigegeben werden. Anschließend wird das in SUTW_Open angelegte Image in das ScrollingUpTextWindow ausge-   *
;* geben.                                                                                                              *
;***********************************************************************************************************************

Protected ImageIdNr2.l = 0

With *SUTW
  
  If StartDrawing(ImageOutput(\ImageIdNr))
    
    ImageIdNr2 = GrabDrawingImage(#PB_Any,0,\FontHeight+(\SpacingY),\ClientWidth,\ClientHeight)
    DrawImage(ImageID(ImageIdNr2),0,0)
    DrawingFont(FontID(\FontIdNr))
    DrawText(\SpacingX,\ClientHeight-(\FontHeight)-(\SpacingY),Text,\FontColor,\WinBackColor)  
    StopDrawing()
    
    FreeImage(ImageIdNr2) ;Hilfs-Image wieder freigeben
    
    If StartDrawing(WindowOutput(\WindowIdNr))
      DrawImage(ImageID(\ImageIdNr),0,0)
      StopDrawing()
      ProcedureReturn 1
    EndIf
    
  EndIf
  
  ProcedureReturn 0
  
EndWith

EndProcedure

Procedure.l SUTW_Repaint(*STUW.SUTW_STRUK)
;***********************************************************************************************************************
;* Mit dieser Prozedure kann der bisherige Inhalt des ScrollingUpTextWindows neu gezeichnet werden.                    *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Parameter: *SUTW.SUTW_STRUK: Ein Pointer auf einen SUTW_STRUK Bereich, der die benötigten Parameter enthält.        *
;*                              Die Bedeutung der verschiedenen Werte geht aus der obigen Struktur-Beschreibung hervor.*
;*                              Die Werte werden ungeprüft verwendet.                                                  *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Return: 1 bei erfolg; 0 sonst.                                                                                      *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Wenn das ScrollingUpTextWindow teilweise von anderen Fenstern verdeckt wird oder zum Teil über den Rand des         *
;* Monitors geschoben wurde, muß es neu gezeichnet werden. In diesem Fall signalisiert es der Event #PB_Event_Repaint  *
;* und man kann diese Prozedure aufrufen.                                                                              *
;***********************************************************************************************************************

If StartDrawing(WindowOutput(*STUW\WindowIdNr))
  DrawImage(ImageID(*STUW\ImageIdNr),0,0)
  StopDrawing()
  ProcedureReturn 1
EndIf

ProcedureReturn 0

EndProcedure

Procedure SUTW_Close(*SUTW.SUTW_STRUK)
;***********************************************************************************************************************
;* Mit dieser Prozedur werden die in SUTW_Open angelegten Resourcen wieder freigegeben und das ScrollingUpTextWindow   *
;* geschlossen.                                                                                                        *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Parameter: *SUTW.SUTW_STRUK: Ein Pointer auf einen SUTW_STRUK Bereich, der die benötigten Parameter enthält.        *
;*                              Die Bedeutung der verschiedenen Werte geht aus der obigen Struktur-Beschreibung hervor.*
;*                              Die Werte werden ungeprüft verwendet.                                                  *
;***********************************************************************************************************************

FreeImage(*SUTW\ImageIdNr)
CloseWindow(*SUTW\WindowIdNr)

EndProcedure
Und hier das Testprogramm dazu:

Code: Alles auswählen

;***********************************************************************************************************************
;* Testprogramm für das ScrollingUpTextWindow.                                                                         *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Das Fenster erscheint oben links und es werden in einer Schleife Text-Zeilen ausgegeben, die nach oben scrollen.    *
;* Das Fenster hat keine Rand und muß über die ESC-Taste beendet werden. Es ist dafür vorgesehen, innerhalb einer      *
;* Haupt-Anwendung als Nachrichten/Status-Fenster zu fungieren. Vom Funktionsprinzip her sollte die Größe nicht        *
;* änderbar sein. Es kann aber von andern Fenster überlappt und theoretisch auch verschoben werden.                    *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Für PureBasic 4.50 unter Windows programmiert von: Jürgen Priess (09.2010)                                          *
;***********************************************************************************************************************
EnableExplicit

IncludeFile "ScrollingUpTextWindow.pbi"

#My_VK_ESCAPE  = $1B ;ESC key

Global MySUTW.SUTW_STRUK
Global Event.l = 0
Global I.l     = 1

MySUTW\FontHeight   = 10
MySUTW\FontColor    = $00000000 ;Schwarz
MySUTW\FontIdNr     = LoadFont(#PB_Any,"Courier",MySUTW\FontHeight,#PB_Font_HighQuality)
MySUTW\WinBackColor = $FFFFFFFF ;Weiß
MySUTW\TopLeftX     = 10
MySUTW\TopLeftY     = 20
MySUTW\ClientWidth  = 300
MySUTW\ClientHeight = 392
MySUTW\SpacingX     = 6
MySUTW\SpacingY     = 5

SUTW_Open(@MySUTW) ;ScrollingUpTextWindwo initialisieren

Repeat 
  
  Event = WindowEvent()
  
  If Event = #PB_Event_Repaint
    SUTW_Repaint(@MySUTW) ;Neuzeichnen des ScrollingUpTextWindows
  EndIf
  
  SUTW_PrintN(@MySUTW,"[" + Str(I) + "] Zum Abbrechen Taste drücken")
  Delay(100) ;Verzögerung, auch wegen WindowEvent
  
  I = I+1
  
Until Event = #WM_KEYDOWN ;GetAsyncKeyState_(#My_VK_ESCAPE) funktioniert nur unter 32 Bit

SUTW_Close(@MySUTW) ;ScrollingUpTextWindow entfernen

End
Nach dem Entfernen der API-Funktion 'GetAsyncKeyState' funktioniert das sowoh in 32- als auch in 64-Bit.
Zuletzt geändert von Pollux am 25.09.2010 01:08, insgesamt 1-mal geändert.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von STARGÅTE »

Ich frag ich immer wieder wieso Leute (nicht gegen dich gerichtet, sonden allgemein) bei diesem Dialog:
---------------------------
Windows Internet Explorer
---------------------------
Die bereits eingegebenen Informationen, müssen erneut gesendet
werden, um die Webseite wieder anzuzeigen.

Sie sollten auf "Abbrechen" klicken, wenn Sie einen Einkauf
durchgeführt haben, um eine doppelte Transaktion zu vermeiden.
Klicken Sie auf "Wiederholen", um die Webseite erneut anzuzeigen.
---------------------------
Wiederholen Abbrechen
---------------------------
Trotzdem auf "Wiederholen" klicken und damit zwei mal das selbe schicken :freak:

Außerdem fehen die CodeTags !

Zum Code:
Zum Anwenden ist ein Delay(100) zusammen mit WindowEvent() ganz schlecht.
Weil das Fenster nicht mehr reagiert.
Nutze dort bitte lieber ein WaitWindowEvent(100)
und für die 100ms einen Timer fürs Window.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Pollux
Beiträge: 23
Registriert: 23.09.2010 18:46
Computerausstattung: Eigenbau: CPU Intel i7-960 Windows 7 64-Bit 12 GB RAM
Toshiba Notebook Windows XP 32-Bit
weitere
Wohnort: Gilching bei München

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von Pollux »

Hallo STARGATE

Da ich schon beim letzten Mal den Beitrag doppelt verschickt habe, habe ich darauf geachtet nur einmal 'Absenden' zu drücken. Also deine erste Vermutung ist nicht zutreffend.

Ich habe hier im Forum nirgends eine Beschreibung gefunden, wid man CodeTags setzt oder das man die setzen mußt. Der Code ist einfach eins zu eins aus PureBasic herüberkopiert. Ich habe schon eine Anfrage an einen Admin gestellt, damit ich das zukünftig abstellen kann.

Das mit dem Delay steht genau so - wie ich es gemacht habe -in der Hilfe zu WindowEvent(). Bei mir läuft das Programm genau so, wie es soll.

Ich bin zwar für Tips dankbar, aber das sind nicht zutreffende Mutmaßungen.
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von TomS »

Über dem Eingabefeld ist ein Button der mit "Code" beschriftet ist.
In der Hilfe steht zwar was von Delay, aber sicher nicht 100.
Ich habe schon eine Anfrage an einen Admin gestellt, damit ich das zukünftig abstellen kann.
Was bitte soll das heißen? Ich verstehe den Sinn von dem Satz nicht, und was ist "das", was du abstellen willst?
Pollux
Beiträge: 23
Registriert: 23.09.2010 18:46
Computerausstattung: Eigenbau: CPU Intel i7-960 Windows 7 64-Bit 12 GB RAM
Toshiba Notebook Windows XP 32-Bit
weitere
Wohnort: Gilching bei München

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von Pollux »

Hallo TomS

Das ist doch mal ein konstruktiver Hinweis! An dem geänderten Erscheinungsbild des Beitrags kann man erkennen, daß der Hinweis geholfen hat. Klasse!

In dem Beispiel zu WindowEvent() (Version 4.50) steht nur Delay(1). Die 100 Millisekunden bei mir müßten also allemal reichen, um andere Fenster nicht zu beeinträchtigen, aber das Fenster wird auf diese Weise langsam vollgeschrieben und demonstriert so das Scrollen. Das ist so gewollt, kann aber zum Test nach belieben abgeändert werden.

Bei Verwendung von WindowEvent() scrollt das Fenster auch, wenn ein anderes Fenster den Fokus hat, weil nicht auf anstehende Events für das Fenster gewartet wird. Bei WaitWindowEvent() - wie von STARGATE vorgeschlagen - würde ich eher vermuten, daß das Scrollen ins stocken gerät, wenn Event-mäßig nichts los ist.

Das 'das', was ich abstellen wollte, ist zum ersten die mir unerklärliche Verdopplung des hochgeladenen Beitrags und zum zweiten die misglückte Formatierung des Codes. Das zweite Problem hat sich inzwischen erledigt.
Zuletzt geändert von Pollux am 25.09.2010 01:56, insgesamt 1-mal geändert.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von STARGÅTE »

Da ich schon beim letzten Mal den Beitrag doppelt verschickt habe, habe ich darauf geachtet nur einmal 'Absenden' zu drücken. Also deine erste Vermutung ist nicht zutreffend.
Es geht nicht um den Absenden-Button, sonden darum das du nicht F5 oder etwas ähnliches drücken sollst, nachdem du den text gesendet hast, weil dann die POST-Daten noch einmal gesendet werden.
Ich habe hier im Forum nirgends eine Beschreibung gefunden, wid man CodeTags setzt oder das man die setzen mußt. Der Code ist einfach eins zu eins aus PureBasic herüberkopiert
Ok, nun weißt du es aber denke ich, denn ohne diese Tags kann man den Code nur schwer lesen (und mein Script funktioniert nicht ^^)
Das mit dem Delay steht genau so - wie ich es gemacht habe -in der Hilfe zu WindowEvent().
Genau so nicht! Dort wird es nur ausgeführt es es kein Event gab!

Außerdem steht wenige Zeilen darunter:
Hinweis: Das 'Delay' sollte nicht nach jedem Ereignis eingefügt werden, denn wenn viele Ereignisse (wie Refresh, Gagdget Updates, etc.) auftreten, wird die Anwendung 20 ms (zumindest unter Windows) zwischen jedem Ereignis warten. Deshalb muss das Delay dann eingefügt werden, wenn keine Ereignisse empfangen werden. Eine weitere Möglichkeit besteht darin, WaitWindowEvent() mit einem niedrigen Timeout-Wert zu verwenden.
Und genau das macht du "leider".
Bei mir läuft das Programm genau so, wie es soll.
Da stimme ich dir zu. Das Programm läuft genau so!
Jedoch wird es für Anfänger (und wird sind hier nun mal bei Tips und Tricks) schwer sein, den Code in ihren Projekten einzubinden.
Außerdem könnten sie solche Fehler (und die falsche benutzung von Delay() ist ein Fehler!) auch machen.


EDIT zum aktuellen Post.
Die 100 Millisekunden bei mir müßten also allemal reichen, um andere Fenster nicht zu beeinträchtigen
Das schon aber die 100 Millisekunden beeinträchtigen dein Fenster, weil nur alle 100ms WindowEvent()
ausgeführt wird.
Kommt jedoch mehr als ein Event in dieser Zeit an, blockiert das Fenster!

Wie schon geschrieben, um ein scrollen zu erzeugen das alle 100ms stattfindet, gibt es AddWindowTimer(#Window, Timer, Timeout) welcher genau solch ein Event sendet, worauf du dann reagieren kannst.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Pollux
Beiträge: 23
Registriert: 23.09.2010 18:46
Computerausstattung: Eigenbau: CPU Intel i7-960 Windows 7 64-Bit 12 GB RAM
Toshiba Notebook Windows XP 32-Bit
weitere
Wohnort: Gilching bei München

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von Pollux »

Vermutlich gibt es unterschiedliche Vorstellungen, was das 'Scrollen' in diesem Zusammenhang aussahgen soll. Ich meine damit nicht das weiche 'scrollen' eines Bildes, das ohne zu ruckeln kontinuierlich erfolgen soll, sondern ein zeilenweises 'scrollen', wie es etwa der Eingabeaufforderung oder dem DOS-Fenster erfolgt, wenn der Text den unteren Fensterrand erreicht. Es soll eine kleine Pause zwischen den einzelnen Zeilenausgaben liegen. Der Text springt nach dem Verfahren sowieso immer um eine Zeile höcher.

Bleibt die Frage, wie man diese Pause realisiert.

Ich verarbeite - wenn überhaupt - nur den Reqaint-Event (bei KeyDown ist gleich Schluß), erzeuge aber bei jedem Schleifen-Durchlauf einen Delay von 100 Millisekunden. Dafür warte ich nicht darauf, daß ein Event vorliegt. Das hat den Effekt, das auch gescrollt wird, wenn das Programm nicht den Fokus hat. Es wird nun vermutet, daß bei Vorliegen vieler Events das Programm blockieren könnte. Da auch ich nichts Genaues weiß, habe ich es ausprobiert und mit einem Delay von 100 Millisekungen blockiert Nichts. Selbst mit einem Delay von 600 Millisekunden läuft die Sache - mir allerdings zu langsam.

Wenn ich den Verbesserungsvorschlag aber richtig verstehe, soll WindowEvent() durch ein WaitWindowEvent(?) ersetzt werden, der Delay()-Befehl gestrichen werden und alle 100 Millisekunden zusätzlich ein Timer-Event erzeugt werden. Das hätte den Vorteil, daß bei Event-Mangel immer noch gescrollt wird, bei Event-Überschuß aber alle Events abgearbeitet werden können. Jetzt habe ich es - glaube ich - auch verstanden. Und gebe zu, daß es die bessere Lösung ist, weil das eigentlich auf allen Window-Rechnern funktionieren müßte.

Inzwischen habe ich übrigens auch bemerkt, das man doppelte eigene Beiträge selbst auch löschen kann...

Geändertes Testprogramm:

Code: Alles auswählen

;***********************************************************************************************************************
;* Testprogramm für das ScrollingUpTextWindow.                                                                         *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Das Fenster erscheint oben links und es werden in einer Schleife Text-Zeilen ausgegeben, die nach oben scrollen.    *
;* Das Fenster hat keine Rand und muß über die ESC-Taste beendet werden. Es ist dafür vorgesehen, innerhalb einer      *
;* Haupt-Anwendung als Nachrichten/Status-Fenster zu fungieren. Vom Funktionsprinzip her sollte die Größe nicht        *
;* änderbar sein. Es kann aber von andern Fenster überlappt und theoretisch auch verschoben werden.                    *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Für PureBasic 4.50 unter Windows programmiert von: Jürgen Priess (09.2010)                                          *
;***********************************************************************************************************************
EnableExplicit

IncludeFile "ScrollingUpTextWindow.pbi"

#My_VK_ESCAPE  = $1B ;ESC key

Global MySUTW.SUTW_STRUK
Global Event.l = 0
Global I.l     = 1

MySUTW\FontHeight   = 10
MySUTW\FontColor    = $00000000 ;Schwarz
MySUTW\FontIdNr     = LoadFont(#PB_Any,"Courier",MySUTW\FontHeight,#PB_Font_HighQuality)
MySUTW\WinBackColor = $FFFFFFFF ;Weiß
MySUTW\TopLeftX     = 10
MySUTW\TopLeftY     = 20
MySUTW\ClientWidth  = 300
MySUTW\ClientHeight = 392
MySUTW\SpacingX     = 6
MySUTW\SpacingY     = 5

SUTW_Open(@MySUTW) ;ScrollingUpTextWindwo initialisieren
AddWindowTimer(MySUTW\WindowIdNr,1,100)

Repeat 
  
  Event = WaitWindowEvent(100)
  
  If Event = #PB_Event_Repaint
    SUTW_Repaint(@MySUTW) ;Neuzeichnen des ScrollingUpTextWindows
  EndIf
  
  SUTW_PrintN(@MySUTW,"[" + Str(I) + "] Zum Abbrechen Taste drücken")
  
  I = I+1
  
Until Event = #WM_KEYDOWN ;GetAsyncKeyState_(#My_VK_ESCAPE) funktioniert nur unter 32 Bit

RemoveWindowTimer(MySUTW\WindowIdNr,1)
SUTW_Close(@MySUTW) ;ScrollingUpTextWindow entfernen

End
Benutzeravatar
HeX0R
Beiträge: 3054
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von HeX0R »

Nett, aber noch nicht ganz richtig.

Wie du in deinem Beispiel siehst, scrollt das ganze sehr viel schneller, wenn du mit der Maus über das Fenster fuchtelst.
Ich habe das mal angepasst, ausserdem das #WM_Keydown entfernt und in eine os-übergreifende PB-Variante geändert.

Und zur besseren Kapselung eine main() erstellt.

Code: Alles auswählen

;***********************************************************************************************************************
;* Testprogramm für das ScrollingUpTextWindow.                                                                         *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Das Fenster erscheint oben links und es werden in einer Schleife Text-Zeilen ausgegeben, die nach oben scrollen.    *
;* Das Fenster hat keine Rand und muß über die ESC-Taste beendet werden. Es ist dafür vorgesehen, innerhalb einer      *
;* Haupt-Anwendung als Nachrichten/Status-Fenster zu fungieren. Vom Funktionsprinzip her sollte die Größe nicht        *
;* änderbar sein. Es kann aber von andern Fenster überlappt und theoretisch auch verschoben werden.                    *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Für PureBasic 4.50 unter Windows programmiert von: Jürgen Priess (09.2010)                                          *
;***********************************************************************************************************************
EnableExplicit

IncludeFile "ScrollingUpTextWindow.pbi"

Procedure main()
	Protected MySUTW.SUTW_STRUK
	Protected Event, i

	With MySUTW
		\FontHeight   = 10
		\FontColor    = $00000000 ;Schwarz
		\FontIdNr     = LoadFont(#PB_Any, "Courier", MySUTW\FontHeight, #PB_Font_HighQuality)
		\WinBackColor = $FFFFFFFF ;Weiß
		\TopLeftX     = 10
		\TopLeftY     = 20
		\ClientWidth  = 300
		\ClientHeight = 392
		\SpacingX     = 6
		\SpacingY     = 5
	EndWith

	SUTW_Open(@MySUTW) ;ScrollingUpTextWindwo initialisieren
	AddWindowTimer(MySUTW\WindowIdNr, 1, 100)
	AddKeyboardShortcut(MySUTW\WindowIdNr, #PB_Shortcut_Escape, 0)

	Repeat

		Event = WaitWindowEvent()
		If Event = #PB_Event_Repaint
			SUTW_Repaint(@MySUTW) ;Neuzeichnen des ScrollingUpTextWindows
		ElseIf Event = #PB_Event_Timer
			i + 1
			SUTW_PrintN(@MySUTW, "[" + Str(i) + "] Zum Abbrechen Taste drücken")
		EndIf

	Until Event = #PB_Event_Menu ;GetAsyncKeyState_(#My_VK_ESCAPE) funktioniert nur unter 32 Bit

	RemoveWindowTimer(MySUTW\WindowIdNr, 1)
	SUTW_Close(@MySUTW) ;ScrollingUpTextWindow entfernen

EndProcedure

main()
Ausserdem:
Nimmst du einen Timer, brauchst du kein Timeout bei Waitwindowevent()
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von STARGÅTE »

:praise: Danke Pollux das du dein Beispiel verbesert hat.

:praise: :praise: Und Danke HeX0R das du noch ein Beispiel zur verwendung eines Times gezeigt hast.

Nun bin ich zufieden :D
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Pollux
Beiträge: 23
Registriert: 23.09.2010 18:46
Computerausstattung: Eigenbau: CPU Intel i7-960 Windows 7 64-Bit 12 GB RAM
Toshiba Notebook Windows XP 32-Bit
weitere
Wohnort: Gilching bei München

Re: Text-Scrollen ohne Sprites und Gadgets in Windows

Beitrag von Pollux »

Danke für die zusätzlichen Tips. Das gefällt mir auch besser und ich habe etliches dazugelernt.

Ich möchte noch einige Anregungen zum vorgestellten Scroll-Bereich geben:

Den Text nur in einer Schriftart und Farbe auszugeben, ist in dem Beispiel nur eine selbstgewählte Beschränkung. Auch der Hintergrund könnte etwa pro Zeile wechseln wie auf den alten EDV-Ausdrucken (grün/weis). Es wäre sicher auch möglich kleine Sysmbole in der Zeile mit nach oben zu scrollen. Auch ließe sich die Scroll-Richtung sicher ändern. Wenn das Image im Hintergrund größer gewählt ist als der Ausschnitt, den man sieht, könnte man sicher - ähnlich wie im DOS-Fenster - schon aus dem Sichtbaren Ausschnit gescrollte Zeilen wieder herholen und trotzdem alles vergessen, was über eine gewisse maximale Zeilenzahl ausgegeben wurde.

Ich lehne mich jetzt weit aus dem Fenster, da ich mit PureBasic Gadgets so gut wie keine Erfahrung habe (ich habe PureBasic erst seit etwa 2 Monaten), aber mit dem ListViewGadget sind wohl keine unterschiedlichen Farben und Schriften in den Zeilen möglich. Sowohl das ListViewGadget als auch das ScrollAreaGadget verwalten wohl eher eine beschränkte Zahl von Zeilen/Elementen - die haben das Vergessen nicht eingebaut.

Die nach den Anregungen von STARGATE gemachten Änderungen haben mich doch sehr erstaunt, weil ja da das Programm bei jedem von WaitWindowEVent() gelieferten Event eine Zeile ausgibt und das geht recht schnell. Das heißt, da ist doch Event-mäßig eine Menge los. Statt nur die Zeilennummer auszugeben, könnte man auch die Events auflisten - und hätte schon eine Anregung für eine 'sinnvolle' Anwendung.
Antworten