Forum | | | | Nico Madysa | Hallo miteinander!
Ich habe mein Programm mal auf das Minimum reduziert, bei dem es immer noch zwei merkwürdige Erscheinungen gibt: KompilierenMarkierenSeparieren $H Messages.ph
proc Zeige_Kugeln
declare ly% , gueltig%
alle Buttons durchgehen
whileloop 0,9
ly% = &loop
whileloop 0,9
if xor(not(&loop mod 9),not(ly% mod 9)) or (not(&loop) and (ly% = 9))
Rand deaktivieren
EnableWindow But&[&loop,ly%],0
elseif (&loop mod 9) and (ly% mod 9)
Mittelfeld aufdecken
ShowWindow(But&[&loop,ly%],0)
endif
Die Kullern anzeigen
if between(&loop,1,8,ly%,1,8)
SetTimer 0 : waitinput : KillTimer
if feld%[&loop - 1,ly% - 1]
DrawPic PTrue&,&loop * 48,ly% * 48;-1
endif
endif
EndWhile
EndWhile
Das gemalte ans Hintergrundbild klatschen
PLsg& = Create("hPic",0,"&SCRBMP")
SendMessage(hBack&,~STM_SETIMAGE,0,PLsg&)
SavePic "D:\Dat1.bmp",PLsg&
SavePic "D:\Dat2.bmp",SendMessage(hBack&,~STM_GETIMAGE,0,0)
Zu guter Letzt den deaktivierten Rand wegmachen
whileloop 0,9
ly% = &loop
whileloop 0,9
case xor(not(&loop mod 9),not(ly% mod 9)) : ShowWindow(But&[&loop,ly%],0)
EndWhile
EndWhile
endproc
proc Button
parameters px% , py%
Rand: Bilder, Mitte: normal
ifnot (px% mod 9) and (py% mod 9)
But&[px%,py%] = Create("PicButton",%hWnd,PTrue&,px% * 48,py% * 48,48,48)
else
But&[px%,py%] = Create("Button",%hWnd,"",px% * 48,py% * 48,48,48)
endif
endproc
proc Button_2
parameters px% , py%
nur ein Button am Rande ist kein Bild
if (px% = 0) and (py% = 9)
But&[px%,py%] = Create("Button",%hWnd,"",px% * 48,py% * 48,48,48)
elseif not((px% mod 9) and (py% mod 9))
But&[px%,py%] = Create("PicButton",%hWnd,PTrue&,px% * 48,py% * 48,48,48)
else
But&[px%,py%] = Create("Button",%hWnd,"",px% * 48,py% * 48,48,48)
endif
endproc
proc Bereite_Bilder
Hintergrundbild
PBack& = Create("hNewPic",481,481,$FFFFFF)
StartPaint PBack&
UsePen 0,1,0
whileloop 2,8
Rectangle (48*&loop-1),0 - (48*&loop+1),480
EndWhile
whileloop 2,8
Rectangle 0,(48*&loop-1) - 480,(48*&loop+1)
EndWhile
EndPaint
Bild für die Kullern
PTrue& = Create("hNewPic",48,48,$FFFFFF)
StartPaint PTrue&
UsePen 0,1,0
UseBrush 1,0
Ellipse 2,2,45,45
EndPaint
endproc
proc BuildUp
declare y%
WindowStyle 26
Window 100,50 - 500,520
Hintergrund
hBack& = Create("Bitmap",%hWnd,PBack&,0,0)
alle Buttons
whileloop 0,9
y% = &loop
whileloop 0,9
Button(&loop,y%)
Button_2(&loop,y%)
EndWhile
EndWhile
endproc
proc Platziere_Kugeln
declare rx% , ry%
clear feld%[]
whileloop 4
repeat
rx% = Rnd(8)
ry% = Rnd(8)
until not(feld%[rx%,ry%])
feld%[rx%,ry%] = 1
EndWhile
endproc
declare But&[9,9], feld%[7,7]
declare hBack&,PBack&,PLsg& , PTrue&
Randomize
Bereite_Bilder
BuildUp
Platziere_Kugeln
var e% = 0
whilenot e%
waitinput
if Clicked(But&[9,9])
e% = 1
elseif Clicked(But&[0,9])
Zeige_Kugeln
endif
wend
DeleteObject PBack&
DeleteObject PLsg&
DeleteObject PTrue&
end
Es wird folgendes gemacht: Zu Beginn werden in der Matrix feld% vier zufällig gewählte Werte auf 1 gesetzt (Meine Murmeln, siehe weiter unten ). Das Staticcontrol, das im Hintergrund liegt, wird von Buttons überdeckt. Klickt man nun auf den Button unten links (mit dem Handle But&[0,9]), so werden die Randbuttons deaktiviert und die mittleren versteckt. Damit wird der essenzielle Teil der Hintergrundbitmap sichtbar. Darauf werden vier Kullern aus feld% hingemalt. Das ganze Fenster wird in einer Bitmap abgesichert und der Hintergrundbitmap übergeben, der Status quo wird also fixiert. Zum Schluss werden die deaktivierten Randbuttons unsichtbar gemacht, nur die Ecken und das Hintergrundbild verbleiben. (Der untere rechte Button beendet das Programm.)
Problem 1: Im Kompilat fehlen von den vier Murmeln meist einige. Im Interpreter werden stets alle vier angezeigt. Wenn die Zeile SetTimer 1 : waitinput : KillTimer (Dulcoif) aktiviert wird, werden auch im Kompilat alle Kullern angezeigt. Sleep zeitigt keine Wirkung. Findet es in getrennten Schleifen statt, dass die Buttons entfernt und die Kreise gemalt werden, so werden ebenso alle vier Kreise angezeigt. Doch warum funktioniert die obere Variante nicht? Ein Zeitproblem kann es nicht sein, da Sleep nichts bringt.
Problem 2: Man ersetze den Aufruf Button(&loop,y%) durch Button_2(&loop,y%). Dadurch ist ein einziger der Randbuttons bildlos, sondern ein Standard-Button. Dies hat den unerklärlichen Effekt, dass die Hintergrundbitmap nur noch aus einer schwarzen Fläche und dem Button besteht. Wers nicht glaubt, kann sich die Bilder absichern lassen. Das Fensterfoto &SCRBMP ist noch ordentlich, doch die Bitmap des Static-Controls ist mehr als fraglich. Doch warum? |
| | | | |
| | | Weil Windowss UI passiv (asynchon) zeichnet.
Machs doch wie in Bomb 3¾ : [...] |
| | | | |
| | Jörg Sellmeyer | Hast Du schon mal ein Repaint zwischendurch ausprobiert? Bei mir kommt auch gleich die Meldung, daß STM_SETIMAGE in der Header-Datei fehlt. |
| | | Windows XP SP2 XProfan X4... und hier mal was ganz anderes als Profan ... | 15.07.2009 ▲ |
| |
| | | Wobei ich persönlich bei so kleinem Spielfeld rein auf einem hPic (oder membmp) arbeiten würde, bzw. auf 2 (oder mehr...) wobei das Zweite z.B. eine Klickmaske wäre. |
| | | | |
| | Nico Madysa | @Jörg: Das ist gut möglich, ich habe meine Messages.ph einige Male erweitert (und vergesse das immer wieder. ) STM_SETIMAGE hat die Nummer $0172, STM_GETIMAGE hat die Nummer $0173. Die Parameter, etc. sind wie bei BM_SETIMAGE bzw. BM_GETIMAGE. Repaint in der Schleife hat nur ein elendes Flackern bereitet, doch dein Tipp hat mich auf die richtige Fährte gelockt. Hiermit klappts: KompilierenMarkierenSeparieren
proc Zeige_Kugeln
declare ly% , gueltig%
alle Buttons durchgehen
whileloop 0,9
ly% = &loop
whileloop 0,9
if xor(not(&loop mod 9),not(ly% mod 9)) or (not(&loop) and (ly% = 9))
Rand deaktivieren
EnableWindow But&[&loop,ly%],0
elseif (&loop mod 9) and (ly% mod 9)
Mittelfeld aufdecken
ShowWindow(But&[&loop,ly%],0)
endif
Die Kullern anzeigen
if between(&loop,1,8,ly%,1,8)
SetTimer 0 : waitinput : KillTimer
if feld%[&loop - 1,ly% - 1]
StartPaint SendMessage(hBack&,~STM_GETIMAGE,0,0)
DrawPic PTrue&,&loop * 48,ly% * 48;-1
EndPaint
endif
endif
EndWhile
EndWhile
Repaint
Das gemalte ans Hintergrundbild klatschen
(damit werden auch die jetzt deaktivierten, dann verschwunden seienden
Randbuttons übernommen)
PLsg& = Create("hPic",0,"&SCRBMP")
SendMessage(hBack&,~STM_SETIMAGE,0,PLsg&)
SavePic "D:\Dat1.bmp",PLsg&
SavePic "D:\Dat2.bmp",SendMessage(hBack&,~STM_GETIMAGE,0,0)
Zu guter Letzt den deaktivierten Rand wegmachen
whileloop 0,9
ly% = &loop
whileloop 0,9
case xor(not(&loop mod 9),not(ly% mod 9)) : ShowWindow(But&[&loop,ly%],0)
EndWhile
EndWhile
endproc
Anstatt obenauf zu krakeln gehe ich direkt in die Bitmap des Statics und fordere es nach der Doppelschleife auf, dies zur Kenntnis zu nehmen.
@iF: "Asynchron, schreib das jetzt hundertmal an die Tafel! Ich gehe einfach mal davon aus, dass mit deinem Rätselwort gemeint ist, dass DrawPic meine Murmeln nicht sofort bei Befehl hinmalt, sondern sich erst einmal "anstellen" muss (wo auch immer) -- und das Bild dann manchmal überzeichnet wird, wenn es endlich dran ist. Richtig?
Damit bleibt nur noch das seltsame Verhalten des Statics übrig, wenn einer der Buttons kein Picbutton ist. Hat wer eine Idee? Eine Adressen-Schutzverletzung sollte diesmal nicht (schon wieder) vorliegen. |
| | | | |
| | | | | | | |
| | Nico Madysa | Dann mache doch mal folgendes: Enkommentiere die beiden Zeilen KompilierenMarkierenSeparieren und passe eventuell die Pfade an. Dann kommentierst du die Zeile Button(&loop,y%) aus und aktivierst dafür die darunter liegende Zeile Button_2(&loop,y%). Dann lässt du das Programm wie schon zuvor durchlaufen und du wirst feststellen, dass Dat1.bmp und Dat2.bmp sich unterscheiden werden, obwohl sie das theoretisch nicht sollten. Es wäre natürlich noch schöner, wenn dieser Fehler nur bei mir aufträte. |
| | | | |
| | | Könntest Du das einmal mit einem 3 Zeiler demonstrieren? |
| | | | |
| | Nico Madysa | Nein, leider nicht. Randomize, Window, end: schon sind drei Zeilen weg. Aber da die Sache mit den Murmeln geklärt ist, schaue ich mal, ob sich das Ding noch weiter kürzen lässt ... |
| | | | |
| | Nico Madysa | Bitteschön, ich hoffe, dass dreiunzwanzig Zeilen nicht zuviel sind. KompilierenMarkierenSeparierencls 16777215
P& ist das Bild des Buttons
var P& = Create("hNewPic",48,48,$22DD22)
Die Buttons sind h& und g&. Jeder kann ein Text- oder ein Bildbutton sein.
var h& = Create("Button",%hWnd,"Text",0,0,48,48)
var h& = Create("PicButton",%hWnd,p&,0,0,48,48)
var g& = Create("PicButton",%hWnd,p&,48,0,48,48)
var g& = Create("Button",%hWnd,"Text",48,0,48,48)
Der Fensterinhalt wird fotografiert und nach unten versetzt angezeigt.
var Q& = Create("hPic",0,"&SCRBMP")
cls 0 Damit man Bild und Bildschirm unterscheiden kann.
Create("Bitmap",%hWnd,Q&,0,48)
Rest
whilenot IsKey(27)
waitinput
wend
DeleteObject P&
DeleteObject Q&
end
Der Fehler tritt auf, sobald auch nur ein einziger normaler Button auf dem Bildschirm sichtbar ist. Sind zwei Picbuttons da, so läuft alles normal. Wenn der Textbutton vorher versteckt wird, funktioniert ebenfalls alles wunderbar. |
| | | | |
| | | Achso jetzt verstehe ich Dein Problem, ja das ist "normal".
Windows weiss nicht welche Pixel hinter* einem Control liegen, ich hatte mal mit Frank darüber debattiert aber finde den Thread nicht mehr.
Im Fazit ist scrbmp (natürlich) "unzuverlässig". ^^
Ziehe mal calc.exe über Dein hWnd und kopiere das hWnd ab, calc ist mit bei!
DCs sind nunmal keine Pixelspeicher.
Vlt. ist dies mit "AERO" jetzt (etwas) anders... |
| | | | |
| | | Nachtrag: Ähnlich: [...] . |
| | | | |
|
AntwortenThemenoptionen | 2.309 Betrachtungen |
ThemeninformationenDieses Thema hat 3 Teilnehmer: |