Anfängerprobleme beim ersten Programm

Anfängerfragen zum Programmieren mit PureBasic.
Diogenes
Beiträge: 91
Registriert: 05.06.2014 10:52

Anfängerprobleme beim ersten Programm

Beitrag von Diogenes »

Hallo,
ich bin seit gestern umgestiegen auf PureBasic. Ich habe vorher bereits Jahre lang in
Dark Basic Professional programmiert. Aber was ich bisher gesehen habe, ist PureBasic
schneller und mächtiger. Mit den allgemeinen Strukturen von Basic bin ich also vertraut.
Aber der Einstig in Pure Basic fällt mir doch sehr schwer, weil ich einige Savchen noch nicht
verstehe.
Normalerweise sind meine Programm immer nach einem gleichen Grundgerüst aufgebaut.
Das versuche ich jetzt nach und nach in Pure Basic zu übersetzen.
Für mich ist schon seltsam, das Prozeduren (in DB functions) vor! dem eigentlichen
Programmtext stehen müssen, aber gut, daran kann man sich ja gewöhnen.

Mein Problem beginnt im Prinzip ab AA_Init:
ich lade ein Bild als Hintergrundbild. Dieses Bild hat geanu die Größe des Fensters
hier also 1024 * 768. Dann will ich unten zwei kleine Bilder grabben um die Zeilen mit denen ích das
Programm steuere entsprechend wieder ausblenden zu koennen
Also etwa:
meldunten("Das ist Quatsch <Taste>") => in der zweiten Zeile von unten wird das ausgegeben
wait key =>ich warte auf einen Tastatureingabe
meluloesch() =>die angezeigte Zeile wird mit dem geladenen Bild 2
also einem Teil des Hintergrundbildes übermalt
so habe ich versucht das im unten stehenden Code umzusetzen, aber irgendwie funktionieren
die Imagenummern nicht so wie ich das will ???
Kann mir da bitte jemand auf die Sprünge helfen ?

Der letzte Absatz AZ_Schleife: soll die eigentliche Spielschleife werden, aber auch die funktioniert
noch nicht wie sie soll.
Danke im voraus

Code: Alles auswählen

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDAUTOR(titel$,autor$)

StartDrawing(WindowOutput(0))
fa1=RGB(0,0,0): fa2=RGB(90,100,10): fa3=RGB(255,255,0)
FrontColor(fa1):Box (0,736,1024,32)
FrontColor(fa2):Box (1,737,1023,30)

DrawingFont(FontID(2)):DrawingMode(1)
DrawText(11,739,titel$,fa1):DrawText(809,739,autor$,fa1)
DrawText(10,738,titel$,fa3):DrawText(808,738,autor$,fa3)
StopDrawing()

EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDUNTEN(meldu$)
fa1=RGB(  0,  0,  0)
fa2=RGB(185,015,  0)
fa3=RGB(255,255,  0)
StartDrawing(WindowOutput(0))
FrontColor(fa1):Box (0,704,1024, 32)
FrontColor(fa2):Box (1,705,1022, 30)
DrawingFont(FontID(2)):DrawingMode(1)
DrawText(101,707,meldu$,fa1)
DrawText(100,706,meldu$,fa3)
StopDrawing()
EndProcedure
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDULOESCH()
  fa1=RGB( 120,0,120)
 StartDrawing(WindowOutput(0)) 
;  FrontColor(fa1):Box (0,704,1024, 32)
  DrawImage(ImageID(2),0,0)
 StopDrawing()
 
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure ZE_HIGRU()
StartDrawing(OutputID)
  DrawImage(ImageID(1),0,0)
StopDrawing()
  
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



AA-INIT:
;-------------------------------------------------------------
;testen ob das Fenster ordnungsgemaess geöffnet werden kann
Global outputID
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Error", "Can't open the sprite system", 0)
  End
EndIf

AUTOR$="(c) LOUIS XIV"
TITEL$="Test-PureBAsic"
HBILD$="test-pb.bmp"

OpenWindow(0,300,100,1024,768,titel$)             ;hier wird das Hauptfenster geöffnet
OpenWindowedScreen(WindowID(0),300,100,1024,768)  ;warum das sein muss, weiss ich noch nicht
OutputID = WindowOutput(0)                        ;das nehme ich 'mal so hin (kann ein Programm 
                                                               ;mehrere Fenster gleichzeitig bedienen ?)

;hier werden die Schriften vorgeladen, damit sie im Programm zur Verfügung sthen                                                   
LoadFont(1,"Arial",32)
LoadFont(2,"Bookman Old Style",18,#PB_Font_Bold )


;jetzt soll das Hintergrundbild geladen werden 
bild1=LoadImage(1,HBILD$)
; bis hierher klappt auch alles
;jetzt werden die Teile definiert, die die unteren beiden Zeilen wieder ausblenden
bild2=#PB_Any    ;=> warum kann ich das bild nicht einfach wie oben weiter nummerieren
bild3=#PB-Any
GrabImage(1,bild2,0,704,1024,32) ;fehler:das angegebene #image wurde nicht initialisiert
GrabImage(1,bild3,0,672,1024,32) ;mehrere Fenster gleichzeitig bedienen ?)



Global gg()               ; als global definieren muss sein 
Dim gg(40)                ; in DarkBasic gelten arrays immer global
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; so sieht normalerweise mein Programmablauf aus
;
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Vorbereiten des Spieles und des Spielfeldes
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AF_VORSPIEL:
; 
;paste image 1,0,0                              rem Hintergrundbild darstellen
;MELDAUTOR(titel$,autor$)                   rem letzte Bildzeile anzeigen
;MELDUNTEN("Information gewuenscht (j/n)")  rem Abfrage

; uebersetzung nach PureBasic
ZE_HIGRU()
StartDrawing(ouputID)
  DrawingFont(FontID(1))
  DrawingMode(1)
  FrontColor(RGB(255,255,200)):
  DrawText(10,10,"Das ist ein tolles fenster  "+Str(bild1)+".."+Str(ImageID(1) ))
  StopDrawing()               
MELDAUTOR(titel$,autor$)
Meldunten("Informationen gewünscht <j> / <n>")
delay 2000 
;ant$="":wait key:ant$=inkey$()
MELDULOESCH()
;If ant$="j" then Gosub CB_INFO
;If ant$="J" then Gosub CB_INFO
rem ------------------------------------------------------------
AG_ANFANG:
;paste image 1,0,0
;MELDAUTOR(titel$,autor$)

;rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;rem hier beginnt die eigentliche Spielschleife
;rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AH_HAUPTSPIEL:
;do
;     If mouseclick() then MAUSWAHL_1(mouseclick(),MouseX(),MouseY())
;     If escapekey()  then gg(1)=9
;     If spacekey()   then dummy=1
;     If returnkey()  then dummy=1     
;     If rightkey()   then dummy=1   
;     If upkey()      then dummy=1      
;     If leftkey()    then dummy=1   
;     If downkey()    then dummy=1   
;     If inkey$()<>"" then TASTWAHL(inkey$())
;     If gg(1)>0      then exit
;loop
;rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;rem Nachspiel = Beendigung des Spieles
;rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AI_NACHSPIEL:
; If gg(1)=9 then MELDUNTEN("Abbruch - <Taste druecken>")
; If gg(1)=3 then MELDUNTEN("Geschafft - Glueckwunsch <Taste druecken>")
; If gg(1)=4 then MELDUNTEN("Du hast gewonnen - Glueckwunsch <Taste druecken>")
; If gg(1)=5 then MELDUNTEN("Ich habe gewonnen <Taste druecken>")
;wait key
;MELDUNTEN("Neustart ? (J/N)")
;ant$="":wait key:ant$=inkey$()
;gg(1)=0
;If ant$="j" then gg(1)=8
;If ant$="J" then gg(1)=8
;MELDULOESCH()
;If gg(1)=8 then Goto AF_VORSPIEL
;paste image 1,0,0
;wait 1000
;cls
End

AZ_Schleife:

;Delay (2000)
;tas=0
;InitKeyboard()
;Repeat
  ;FlipBuffers()
;  tas=0
;  ExamineKeyboard()
;  If KeyboardPushed(#PB_Key_All)
;    tas=1 
;    MELDUNTEN("Taste gedrueckt")  
;  EndIf 
;Until tas>0
;Delay(1000)
;MELDULOESCH()
;Delay (1500)
;End


Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Re: Anfängerprobleme beim ersten Programm

Beitrag von Bisonte »

Ersteinmal Willkommen im Forum.

Alle Achtung. Da gibt es eine Menge zu erklären.

Folgendes zur ersten Einführung : F1 ist eine sehr nützliche Taste. Sie ruft die Hilfe auf, wenn der Cursor auf einem Befehl oder einer Funktion steht.
Desweiteren ziehst du dir hier verdammt viele Schuhe an, die du auch noch vermischst.

Fenster, Screen, Objektverwaltung usw.

Fange ich mal beim ersten an.

Prozeduren müssen nicht am Anfang eines Codes stehen. Sie müssen VOR DEM ERSTEN AUFRUFEN deklariert sein.
Man kann also

Code: Alles auswählen

Declare TuEtwas(Parameter)  ; <-- Deklaration

Debug TuEtwas(5) ; <-- der erste Aufruf

Procedure TuEtwas(Parameter) ; Hier die Prozedur
  ProcedureReturn Parameter * 5  
EndProcedure
soetwas machen, wenn man es möchte oder es einem logischer erscheint. Nur dann ist halt das Declare wichtig, da
es sich bei PB um einen Single-Pass Compiler handelt (Alles in einem Rutsch).

Kommen wir zum nächsten wichtigen Punkt : PB-Objekte
Es gibt die PB Nummer und die OS-ID...
Als Beispiel nehme ich mal ein Image. Mit CreateImage(1, ... erstelle ich ein Bild mit der PB Nummer 1.
Das ist die PB Objektverwaltung. Bei einigen Funktionen wird aber die ImageID benötigt. z.B. beim DrawImage(...
Da muss man immer schön aufpassen, das man die richtige Nummer erwischt, da sonst der Compiler mit einer Fehlermeldung
daherkommt.
Die Sache mit dem #PB_Any.... ist einfach erklärt. Es nimmt eine zufällige freie PB Nummer. Bei Windows, Fonts, Images... eigentlich
überall wo man so eine PB Nummer benötigt.
In der Hilfe bei der Syntax der einzelnen Funktionen steht dann auch #Image oder #Window oder eben ImageID, WindowID ...

Bei deinem :

Code: Alles auswählen

;jetzt soll das Hintergrundbild geladen werden
bild1=LoadImage(1,HBILD$)
; bis hierher klappt auch alles
;jetzt werden die Teile definiert, die die unteren beiden Zeilen wieder ausblenden
bild2=#PB_Any    ;=> warum kann ich das bild nicht einfach wie oben weiter nummerieren
bild3=#PB_Any
GrabImage(1,bild2,0,704,1024,32) ;fehler:das angegebene #image wurde nicht initialisiert
GrabImage(1,bild3,0,672,1024,32) ;mehrere Fenster gleichzeitig bedienen ?)
Ist eigentlich nichts verkehrtes. Mit dem Wissen, das PB bei einem #PB_Any eine freie zufällige Nummer rausrückt, kann man nun nicht
davon ausgehen, das Bild2 auch 2 ist. Daher ist in deiner Prozedur MELDULOESCH() die Fehlermeldung bei DrawImage(ImageID(2).... völlig
normal. Es gibt ja kein Bild 2.
Eigentlich geben alle Funktionen mit denen man #PB_Any nutzen kann, die tatsächliche Nummer zurück.
Sollte nun das Bild aus irgendeinem Grund nicht geladen werden, wird eine 0 zurückgegeben. Also ein Fehler, den man abfangen sollte !
z.B.

Code: Alles auswählen

Bild1 = LoadImage(#PB_Any, HBild$)

If Bild1 ; Wenn also das Ergebnis von LoadImage < > als 0 ist
  Bild2 = GrabImage(Bild1, #PB_Any, 0, 704, 1024, 32)
  Bild3 = GrabImage(Bild1, #PB_Any, 0, 672, 1024, 32) 
EndIf
Man muss diese PB Nummern nun auch weiter verwenden.
Also wenn man sie in Prozeduren nutzen möchte, global machen ( Global Bild1 ) oder als Parameter der Prozedure übergeben.

Code: Alles auswählen

Procedure MeldungLoeschen(Image)
  If IsImage(Image)
    DrawImage(ImageID(Image), 0, 0)
  EndIf
EndProcedure
(Wobei man hier auch mit IsImage() abfragen kann, ob das Bild korrekt initialisiert ist !)

Nun aber zum Hauptteil... Du vermischt hier Window und Screen zu einem.
Ein Window wird vom Betriebssystem und von PB anders gehandhabt als ein Screen !
Z.B. muss man einen Screen selbst löschen und neuzeichnen, wenn man z.B. ein Sprite darstellt das sich bewegen soll.
Bei einem Window wird das vom OS selbst erledigt.
Allerdings muss man die Events abhandeln.

Wenn man ankommende Events (z.B. Maus bewegt sich oder Fenster wird maximiert) nicht abholt, "hängt" das ganze.
Eine Standard Eventloop sieht ungefähr so aus :

Code: Alles auswählen

OpenWindow(0, 0, 0, 640, 480, "Titel", #PB_Window_SystemMenu) ; Fenster erstellen

; Die Schleife

Repeat
  
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_CloseWindow ; < Window wird geschlossen
      Quit = 1
  EndSelect
  
Until Quit > 0
Bei Screens ist das schon wieder ganz was anderes. Man sollte sich ersteinmal klar werden...
Brauche ich überhaupt einen Screen ?
Einiges lässt sich auch einfach mit Gadgets realisieren und ausserdem bietet PB einem auch noch das
CanvasGadget an, das beinahe Screen Funktionalität besitzt, mit der Ausnahme, dass keine Sprites benutzt werden können.

Momentan sehe ich bei dir keine Sprites, daher wäre wohl auch eine Canvaslösung passabel...

Zum Schluss gebe ich noch den Rat: Lesen ! Die Hilfe (per F1) hat auch eine Einsteigersektion, die einem das ganze näherbringen kann.
Irgendwo hier im Forum ist auch der Link zu einem PB Buch, das BI2 (ich hoffe der Name war richtig) ins deutsche übersetzt hat.

Bei weiteren Fragen... Dazu ist das Forum da ;)

P.S.: Sollte das ganze Oberlehrermäßig klingen.... tschulligung ;)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Diogenes
Beiträge: 91
Registriert: 05.06.2014 10:52

Re: Anfängerprobleme beim ersten Programm

Beitrag von Diogenes »

@Bisonte

Danke für Deine schnelle Antwort, an Deinen Erklärungen ist nichts oberlehrerhaftes. Ich habe ja
gefragt und Deine Antworten und die Code-Schnipsel haben mir schon einiges klarer gemacht.
Die Hilfe im Programm habe ich permanent offen, daher habe ich ja auch schon ein wenig Code hin-
bekommen. Ich werde das ganze jetzt 'mal weiterspinnen und mich dann wieder melden.
Das wird garantiert nicht meine letzte Frage gewesen sein. Wie gesagt mit Basic an sich kenne
ich mich ganz gut aus. Prozeduren, Schleifen, logische Operationen usw sollten mir keine größeren Probleme
bereiten. Nicht gekannt habe ich bisher das Zusammenspiel zwischen Windows und PB, das gibt es
bei DarkBasicProf nicht. Da läuft alles innerhalb des Programms.
Aber ich bin ja lernwillig und hoffentlich -fähig.

vielen Dank erst 'mal
Diogenes
Beiträge: 91
Registriert: 05.06.2014 10:52

Re: Anfängerprobleme beim ersten Programm

Beitrag von Diogenes »

Hallo,
mit Hilfe der Anleitungen von Bisonte habe ich mein Programm modifiziert.

Code: Alles auswählen

;-------------------------------------------------------------
AA-INIT:
;-------------------------------------------------------------
UseJPEGImageDecoder()
UseJPEGImageEncoder()

;Prozeduren anmelden
Declare MELDAUTOR(titel$,autor$)
Declare MELDUNTEN(meldu$)  
Declare MELDULOESCH(Bild2)
Declare ZE_HIGRU(bild1) 
Declare WAITKEY()
; ----
;testen ob das Fenster ordnungsgemaess geöffnet werden kann
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Error", "Can't open the sprite system", 0)
  End
EndIf

; ----
Global canvasNr
Global Dim gg(40)    
;-----

AUTOR$="(c) LOUIS XIV"
TITEL$="Test-PureBAsic"
HBILD$="test-pb.jpg"

;hier wird das Hauptfenster geöffnet
  OpenWindow(0,300,100,1024,768,titel$, #PB_Window_SystemMenu)            
  canvasNr=CanvasGadget(#PB_Any,0,0,1024,768,#PB_Canvas_ClipMouse|#PB_Canvas_Keyboard)

;hier werden die Schriften vorgeladen, damit sie im Programm zur Verfügung stehen                                                   
LoadFont(1,"Arial",32)
LoadFont(2,"Bookman Old Style",18,#PB_Font_Bold )
; -------------------------------------------------------------
;jetzt soll das Hintergrundbild geladen werden 
bild1=LoadImage(#PB_Any,HBILD$)
If Bild1 
  bild2=GrabImage(Bild1,#PB_Any, 0, 704, 1024, 32)
  bild3=GrabImage(Bild1,#PB_Any, 0, 672, 1024, 32)
EndIf
; -------------------------------------------------------------
InitKeyboard()
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Vorbereiten des Spieles und des Spielfeldes
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AF_VORSPIEL:
; 
ZE_HIGRU(Bild1)

StartDrawing(CanvasOutput(canvasNr))
;StartDrawing(WindowOutput(0))
    DrawingFont(FontID(1))
    DrawingMode(1)
    FrontColor(RGB(255,255,200)):
    DrawText(10,10,"Das ist ein tolles fenster  ")
StopDrawing()               
MELDAUTOR(titel$,autor$)
MELDUNTEN("Bild1 "+Str(bild1)+"  "+Str(bild2)+"  "+Str(bild3)+" <LeerTaste>" )  
Delay(2000)
WAITKEY() 
MELDULOESCH(Bild2)
Delay (5000)
End


; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AK_Procedures:
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDAUTOR(titel$,autor$)
StartDrawing(CanvasOutput(canvasNr))
;StartDrawing(WindowOutput(0))
    fa1=RGB(0,0,0):fa2=RGB(90,100,10):fa3=RGB(255,255,0)
    FrontColor(fa1):Box (0,736,1024,32)
    FrontColor(fa2):Box (1,737,1023,30)
    DrawingFont(FontID(2)):DrawingMode(1)
    DrawText(11,739,titel$,fa1):DrawText(809,739,autor$,fa1)
    DrawText(10,738,titel$,fa3):DrawText(808,738,autor$,fa3)
StopDrawing()
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDUNTEN(meldu$)
fa1=RGB(  0,  0,  0)
fa2=RGB(185,015,  0)
fa3=RGB(255,255,  0)
StartDrawing(CanvasOutput(canvasNr))
;StartDrawing(WindowOutput(0))
FrontColor(fa1):Box (0,704,1024, 32)
FrontColor(fa2):Box (1,705,1022, 30)
DrawingFont(FontID(2)):DrawingMode(1)
DrawText(101,707,meldu$,fa1)
DrawText(100,706,meldu$,fa3)
StopDrawing()
EndProcedure
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDULOESCH(Bild2)
 StartDrawing(CanvasOutput(canvasNr))
;StartDrawing(WindowOutput(0)) 
    DrawImage(ImageID(bild2),0,704)
 StopDrawing()
 EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure ZE_HIGRU(Bild1)
StartDrawing(CanvasOutput(canvasNr))
;StartDrawing(WindowOutput(0))
  DrawImage(ImageID(bild1),0,0)
StopDrawing()
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure WAITKEY()
quit=0  
Repeat
  Event = WaitWindowEvent()
  If event=#PB_Event_Gadget 
    If EventGadget()=canvasnr
      If EventType()=#PB_EventType_Input
        quit=1 
      EndIf
    EndIf
  EndIf
  If event=#PB_Event_CloseWindow
    quit=1
  EndIf  
Until quit>0
  
; Repeat  
;   Event = WaitWindowEvent()
;   If #PB_Event_CloseWindow
;     quit=1
;   ElseIf #PB_EventType_Input
;     quit=1
;   EndIf
;   
; Until quit>0  
;   
;   
  
;   quit=0
;   Repeat
;     Event = WaitWindowEvent()
;     If Event = #PB_Event_Gadget
;       Select EventGadget()
;         Case #PB_Event_CloseWindow ; < Window wird geschlossen
;           Quit=1
;         Case #PB_EventType_Input         
;           quit=1
;       EndSelect
;     EndIf   
;   Until Quit > 0
  
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Ich habe jetzt das Canvas-Gadget benutzt. Es funktioniert auch alles, aber jetzt habe ich Probleme
bei der Waitkey() -Prozedur. Die Keyboradabfrage funktioniert schlicht gar nicht.
Ich habe alle Möglichkeiten aus dem referenzhandbuch ausprobiert. Ich kann auf der Tastatur rumhämmern
wie ich will. Compi reagiert einfach nicht. Wenn ich das Fenster mit der Maus über den Schließen-Knopf
schließe funktioniert es, wie es soll.
Wie bekomme ich die Tastatur ordentlich abgefragt ?
vielen Dank im voraus
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Anfängerprobleme beim ersten Programm

Beitrag von Regenduft »

Die Tastaturabfrage funktioniert doch einwandfrei... :?
Hatte beim Testen das CanvasGasget vielleicht keinen Tastaturfokus? Du musst erst mit der Maus einmal reinklicken oder den Fokus mit SetActiveGadget() setzen.
PureBasic-Hilfe (CanvasGadget) hat geschrieben:Das #PB_Canvas_Keyboard Flag wird benötigt, um jegliche Tastatur-Ereignisse im Gadget zu empfangen. Wenn Sie dieses Flag verwenden, sollten Sie die #PB_EventType_Focus und #PB_EventType_LostFocus Ereignisse überprüfen, und einen sichtbaren Hinweis (Rahmen etc.) auf das Gadget zeichnen, wenn es den Fokus hat, damit dem Anwender klar ist, welches Gadget aktuell den Fokus hat. Alternativ kann das #PB_Canvas_DrawFocus Flag angegeben werden, damit das Gadget ein standardmäßiges Fokus-Rechteck zeichnet, wann immer es den Fokus hat.
Kleiner Tipp noch: Nutze EnableExplicit! Dann musst Du zwar alle Variablen mit Define oder Protected definieren und hast mehr Schreibarbeit, allerdings ersparst Du Dir die Suche nach Bugs, welche lediglich auf kleinen Tippfehlern wie Buchstabenverdrehern basieren.
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Diogenes
Beiträge: 91
Registriert: 05.06.2014 10:52

Re: Anfängerprobleme beim ersten Programm

Beitrag von Diogenes »

@Regenduft

Hallo,

das war`s.
Kaum macht man's richtig schon funktioniert's
Das Gadget hatte einfach noch keinen Focus.
Danke für die schnelle Hilfe.

Ich werde weiterbasteln.

Bis bald
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Re: Anfängerprobleme beim ersten Programm

Beitrag von Bisonte »

Code: Alles auswählen

;testen ob das Fenster ordnungsgemaess geöffnet werden kann
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Error", "Can't open the sprite system", 0)
  End
EndIf
Das ist nicht notwendig. Es wird nur im Zusammenhang mit Screens benötigt. Bei Windows wird sozusagen alles "frei Haus" mitgegeben.
Und bei der Gelegenheit : Du hast im Code noch einmal InitKeyboard() stehen. Einmal würde reichen. Es wurde ja schon initialisiert.

Code: Alles auswählen

UseJPEGImageEncoder()
Den braucht man nur, wenn man vorhat, Bilder im JPEG Format zu speichern.

Das sprang mir gerade so ins Gesicht ;)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Diogenes
Beiträge: 91
Registriert: 05.06.2014 10:52

Re: Anfängerprobleme beim ersten Programm

Beitrag von Diogenes »

Hallo,
zuerst möchte ich noch 'mal allen Beteiligten danken.
Dafür daß ich PB erst seit Mittwoch-Abend habe geht das ja wirklich gut voran.
Ohne Eure Hilfe wäre das nicht möglich gewesen.
Mein nächstes Problem:

Ich habe ja jetzt eine funktionierende WAITKEY() -prozedur
Jetzt möchte ich aber nicht irgendeinen, sondern bestimmte
keys abfangen und darauf reagieren.
Im Netz habe ich die undokumentierten Funktion eventwparam()
und eventlparam() gefunden.
Das ist eigentlich genau das, was ich gesucht habe, die Scancodes
der Tastatur abfangen und auswerten.
Daraus habe ich die Funktion Waitstring() gebastelt. Leider funktioniert
sie bei mir nicht. Kann einer von Euch Cracks, da 'mal drüberschauen,
wo mein Fehler ist.
Danke im voraus.
p.s. die ersten Probleme mit den verschiedenen Nummern habe ich jetzt
mit Enumeration gelöst. das funktioniert jetz gut.

Code: Alles auswählen

;-------------------------------------------------------------
AA-INIT:
;-------------------------------------------------------------
;zusätzliche Bibliothek laden
UseJPEGImageDecoder()
;UseJPEGImageEncoder()
; -------------------------------------------------------------
;Prozeduren anmelden
Declare MELDAUTOR(titel$,autor$)
Declare MELDUNTEN(meldu$)  
Declare MELDULOESCH()
Declare ZE_HIGRU() 
Declare WAITKEY()
Declare WAITSTRING()
; -------------------------------------------------------------
;testen ob das Fenster ordnungsgemaess geöffnet werden kann
;wird nur bei screen benötigt; screen benutzt man wenn man sprites nutzt
;If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
;  MessageRequester("Error", "Can't open the sprite system", 0)
;  End
;EndIf
; -------------------------------------------------------------
;Variablendeklarationen
Enumeration 100
  #cv001
  #bld01
  #bld02
  #bld03
  #kb001
EndEnumeration


Global Dim gg(40)    
;-----
AUTOR$="(c) Diogenes"
TITEL$="Test-PureBAsic"
HBILD$="test-pb.jpg"

; -------------------------------------------------------------
;hier wird das Hauptfenster geöffnet
  OpenWindow(0,300,100,1024,768,titel$, #PB_Window_SystemMenu)            
  CanvasGadget(#cv001,0,0,1024,768,#PB_Canvas_ClipMouse|#PB_Canvas_Keyboard)
AddKeyboardShortcut(0,#PB_Shortcut_All,#kb001)
SetActiveGadget(#cv001)         ;wichtig: Tastatur funktioniert sonst nicht
; -------------------------------------------------------------
;hier werden die Schriften vorgeladen, damit sie im Programm zur Verfügung stehen                                                   
LoadFont(1,"Arial",32)
LoadFont(2,"Bookman Old Style",18,#PB_Font_Bold )
; -------------------------------------------------------------
;jetzt soll das Hintergrundbild geladen werden 
;hier wird das Bild aus der EXE ausgelesen, in die es integriert ist
CatchImage(#bld01,?zz_Higru)
;hier wird das Bild von der HDD geladen
;#bld01=LoadImage(#PB_Any,HBILD$)
;----
;bilder erstellen für meldunten und meldtast
If #bld01 
  GrabImage(#bld01,#bld02, 0, 704, 1024, 32)
  GrabImage(#bld01,#bld03, 0, 672, 1024, 32)
EndIf
; -------------------------------------------------------------
;InitKeyboard()
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Vorbereiten des Spieles und des Spielfeldes
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AF_VORSPIEL:
; 
ZE_HIGRU()
StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0))
    DrawingFont(FontID(1))
    DrawingMode(1)
    FrontColor(RGB(255,255,200)):
    DrawText(10,10,"Das ist ein tolles fenster  ")
StopDrawing()               
MELDAUTOR(titel$,autor$)
MELDUNTEN("Information gewuenscht ? <j> / <n>")  
WAITSTRING()
;WAITKEY() 
MELDULOESCH()
Delay (2000)

End
; =============================================================
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BA_Procedures:
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDAUTOR(titel$,autor$)
StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0))
    fa1=RGB(0,0,0):fa2=RGB(90,100,10):fa3=RGB(255,255,0)
    FrontColor(fa1):Box (0,736,1024,32)
    FrontColor(fa2):Box (1,737,1023,30)
    DrawingFont(FontID(2)):DrawingMode(1)
    DrawText(11,739,titel$,fa1):DrawText(809,739,autor$,fa1)
    DrawText(10,738,titel$,fa3):DrawText(808,738,autor$,fa3)
StopDrawing()
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDUNTEN(meldu$)
fa1=RGB(  0,  0,  0)
fa2=RGB(185,015,  0)
fa3=RGB(255,255,  0)
StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0))
FrontColor(fa1):Box (0,704,1024, 32)
FrontColor(fa2):Box (1,705,1022, 30)
DrawingFont(FontID(2)):DrawingMode(1)
DrawText(101,707,meldu$,fa1)
DrawText(100,706,meldu$,fa3)
StopDrawing()
EndProcedure
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDULOESCH()
 StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0)) 
    DrawImage(ImageID(#bld02),0,704)
 StopDrawing()
 EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure ZE_HIGRU()
StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0))
  DrawImage(ImageID(#bld01),0,0)
StopDrawing()
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure WAITKEY()
quit=0  
Repeat
  Event = WaitWindowEvent()
  If event=#PB_Event_Gadget
    If EventGadget()=#cv001
      If EventType()=#PB_EventType_Input
        quit=1
      EndIf
    EndIf
  EndIf
  If event=#PB_Event_CloseWindow
    quit=1
  EndIf 
Until quit>0
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure WAITSTRING()
quit=0  
Repeat
  Event = WaitWindowEvent()
  tast=EventwParam() & $FFFF
  If event=#PB_Event_Gadget
    Select tast
      Case 1
        Meldunten("<Escape>")
        Delay(2000)
        quit=1
      Case 13
        Meldunten("<Enter>")
      Case 34
        Meldunten("<g>")
      Case 36
        Meldunten("<j>")
      Case 49
        MELDUNTEN("<n>")
     EndSelect
    EndIf
  
  If event=#PB_Event_CloseWindow
    quit=1
  EndIf 
Until quit>0
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; -------------------------------------------------------------
;das Hintergrundbild wird in die exe integriert
DataSection
  zz_HIGRU:
  IncludeBinary "test-pb.jpg"
EndDataSection
; -------------------------------------------------------------

End
; =============================================================

Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Anfängerprobleme beim ersten Programm

Beitrag von Regenduft »

Bin gerade mit eigener Recherche beschäftigt, daher keine "Code-Analyse" aber kleine Wegweiser:
Diogenes hat geschrieben:Im Netz habe ich die undokumentierten Funktion eventwparam()
und eventlparam() gefunden.
Solltest Du die Finger davon lassen, denn laut Hilfe der aktuellen PureBasic Beta werden die nicht mehr unterstützt. Du kannst höchstens SetWindowCallback() nutzen, denn da werden lparam und wparam an Deine Callback-Prozedur übergeben. Fände es allerdings mutig beim Einstieg gleich mit so etwas herumzujonglieren... :wink:

Andere Möglichkeiten wären AddKeyboardShortcut()...

...oder per WinApi "GetAsyncKeyState_() & $8000". Das "& $8000" ist wichtig! Bei betätigter Taste ist die Rückgabe ungleich Null, ansonsten Null.

Die #VK_*-Konstanten und die #PB_Shortcut_*-Konstanten sind übrigens identisch.
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Diogenes
Beiträge: 91
Registriert: 05.06.2014 10:52

Re: Anfängerprobleme beim ersten Programm

Beitrag von Diogenes »

Hallo,
aufgrund des Hinweises von Regenduft habe ich das Programm noch `mal
abgeändert und benutze jetz addshortcut_XXX.
Jetzt reagirt das Programm aber extrem seltsam in der Prozedur WaitString()

Jede !!!nicht!!! per add-shortcut definierte Taste liefert den Wert 9 zurück.
jede definierte Taste liefert gar nichts zurück.

#PB_Canvas_Input
Gibt das eingegebene Zeichen (Character) zurück, welches durch ein oder mehrere Tastendrücke generiert wurde. Dieses Attribut ist nur verfügbar nach einem #PB_EventType_Input Ereignis.

Code: Alles auswählen

;-------------------------------------------------------------
AA-INIT:
;-------------------------------------------------------------
;zusätzliche Bibliothek laden
UseJPEGImageDecoder()
;UseJPEGImageEncoder()
; -------------------------------------------------------------
;Prozeduren anmelden
Declare MELDAUTOR(titel$,autor$)
Declare MELDUNTEN(meldu$)  
Declare MELDULOESCH()
Declare ZE_HIGRU() 
Declare WAITKEY()
Declare WAITSTRING()
; -------------------------------------------------------------
;testen ob das Fenster ordnungsgemaess geöffnet werden kann
;wird nur bei screen benötigt; screen benutzt man wenn man sprites nutzt
;If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
;  MessageRequester("Error", "Can't open the sprite system", 0)
;  End
;EndIf
; -------------------------------------------------------------
;Variablendeklarationen
Enumeration 100
  #cv001
  #bld01
  #bld02
  #bld03
  #kb001
  #kb002
  #kb003
  #kb004
  #kb005
  #kb006
  #kb007
  #kb008
  #kb009
  #kb010  
EndEnumeration


Global Dim gg(40)    
;-----
AUTOR$="(c) Diogenes"
TITEL$="Test-PureBAsic"
HBILD$="test-pb.jpg"

; -------------------------------------------------------------
;hier wird das Hauptfenster geöffnet
  OpenWindow(0,300,100,1024,768,titel$, #PB_Window_SystemMenu)            
  CanvasGadget(#cv001,0,0,1024,768,#PB_Canvas_ClipMouse|#PB_Canvas_Keyboard)
AddKeyboardShortcut(0,#PB_Shortcut_All,#kb001)
AddKeyboardShortcut(0,#PB_Shortcut_Escape,#kb002)
AddKeyboardShortcut(0,#PB_Shortcut_Left  ,#kb003)
AddKeyboardShortcut(0,#PB_Shortcut_Up    ,#kb004)
AddKeyboardShortcut(0,#PB_Shortcut_Right ,#kb005)
AddKeyboardShortcut(0,#PB_Shortcut_Down  ,#kb006)
AddKeyboardShortcut(0,#PB_Shortcut_J     ,#kb007)
AddKeyboardShortcut(0,#PB_Shortcut_N     ,#kb008)
AddKeyboardShortcut(0,#PB_Shortcut_Return,#kb009)
AddKeyboardShortcut(0,#PB_Shortcut_Z     ,#kb010)






SetActiveGadget(#cv001)         ;wichtig: Tastatur funktioniert sonst nicht
; -------------------------------------------------------------
;hier werden die Schriften vorgeladen, damit sie im Programm zur Verfügung stehen                                                   
LoadFont(1,"Arial",32)
LoadFont(2,"Bookman Old Style",18,#PB_Font_Bold )
; -------------------------------------------------------------
;jetzt soll das Hintergrundbild geladen werden 
;hier wird das Bild aus der EXE ausgelesen, in die es integriert ist
CatchImage(#bld01,?zz_Higru)
;hier wird das Bild von der HDD geladen
;#bld01=LoadImage(#PB_Any,HBILD$)
;----
;bilder erstellen für meldunten und meldtast
If #bld01 
  GrabImage(#bld01,#bld02, 0, 704, 1024, 32)
  GrabImage(#bld01,#bld03, 0, 672, 1024, 32)
EndIf
; -------------------------------------------------------------
;InitKeyboard()
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Vorbereiten des Spieles und des Spielfeldes
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AF_VORSPIEL:
; 
ZE_HIGRU()
StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0))
    DrawingFont(FontID(1))
    DrawingMode(1)
    FrontColor(RGB(255,255,200)):
    DrawText(10,10,"Das ist ein tolles fenster  ")
StopDrawing()               
MELDAUTOR(titel$,autor$)
MELDUNTEN("Information gewuenscht ? <j> / <n>")  

WAITSTRING()
;WAITKEY() 
MELDULOESCH()
Delay (1200)

End
; =============================================================
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BA_Procedures:
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDAUTOR(titel$,autor$)
StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0))
    fa1=RGB(0,0,0):fa2=RGB(90,100,10):fa3=RGB(255,255,0)
    FrontColor(fa1):Box (0,736,1024,32)
    FrontColor(fa2):Box (1,737,1023,30)
    DrawingFont(FontID(2)):DrawingMode(1)
    DrawText(11,739,titel$,fa1):DrawText(809,739,autor$,fa1)
    DrawText(10,738,titel$,fa3):DrawText(808,738,autor$,fa3)
StopDrawing()
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDUNTEN(meldu$)
fa1=RGB(  0,  0,  0)
fa2=RGB(185,015,  0)
fa3=RGB(255,255,  0)
StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0))
FrontColor(fa1):Box (0,704,1024, 32)
FrontColor(fa2):Box (1,705,1022, 30)
DrawingFont(FontID(2)):DrawingMode(1)
DrawText(101,707,meldu$,fa1)
DrawText(100,706,meldu$,fa3)
StopDrawing()
EndProcedure
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure MELDULOESCH()
 StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0)) 
    DrawImage(ImageID(#bld02),0,704)
 StopDrawing()
 EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure ZE_HIGRU()
StartDrawing(CanvasOutput(#cv001))
;StartDrawing(WindowOutput(0))
  DrawImage(ImageID(#bld01),0,0)
StopDrawing()
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure WAITKEY()
quit=0  
Repeat
  Event = WaitWindowEvent()
  If event=#PB_Event_Gadget
    If EventGadget()=#cv001
      If EventType()=#PB_EventType_Input
        quit=1
      EndIf
    EndIf
  EndIf
  If event=#PB_Event_CloseWindow
    quit=1
  EndIf 
Until quit>0
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure WAITSTRING()
quit=0  
Repeat
  Event = WaitWindowEvent()
    If event=#PB_Event_Gadget And EventGadget()=#cv001
      If EventType()=#PB_EventType_Input       
        Meldunten(Str(#PB_Canvas_Input)  )    
        Delay(500)
        meldunten(".")
      EndIf  
   EndIf
  
  If event=#PB_Event_CloseWindow
    quit=1
  EndIf 
Until quit=1
EndProcedure
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; -------------------------------------------------------------
;das Hintergrundbild wird in die exe integriert
DataSection
  zz_HIGRU:
  IncludeBinary "test-pb.jpg"
EndDataSection
; -------------------------------------------------------------


End
; =============================================================
Antworten