Code: Alles auswählen
;Code by Ligatur
Import "shlwapi.lib"
PathAddExtensionA(Path.s, Extension.s)
EndImport
Structure MPos
x.w
y.w
EndStructure
#Wnd_World = 0
Enumeration
#Str_em11
#Str_em12
#Str_em21
#Str_em22
#Str_eDx
#Str_eDy
#str_Rotate
#str_Shear
#str_Reflect
#str_Move
#str_Reihenfolge
#str_Replay
#btn_Datei
#btn_Use
#btn_Rotate
#btn_Shear
#btn_Reflect
#btn_Move
#btn_Matrix
#btn_Replay
#btn_Load
#btn_Save
#Cnt_Bild
#Text_0
#Text_1
#Text_2
#Text_3
#Text_4
#Text_5
#Text_6
#Text_7
#Text_8
#Text_9
#Text_11
EndEnumeration
#img_Bild = 0
; Messages für das Childfenster zur Grafikanzeige
Enumeration #WM_USER
#cms_SetValues
EndEnumeration
UseJPEGImageDecoder()
UsePNGImageDecoder()
Define Datei.s, ighwnd.l,Austext.s, *OldMSCb, *OldTSCb, *OldRScb, *OldBCb
Procedure.l BCb(hwnd, msg, wParam, lParam)
Shared *OldBCb
If msg = #WM_CHAR
If wParam = #CR Or wParam = #TAB
SetFocus_(GetNextDlgTabItem_(WindowID(#Wnd_World), hwnd, #False))
EndIf
EndIf
ProcedureReturn CallWindowProc_(*OldBCb, hwnd, msg, wParam, lParam)
EndProcedure
Procedure.l Mscb(hwnd, msg, wParam, lParam)
Shared *OldMSCb
If msg = #WM_CHAR
If wParam = 44 Or wParam = 46 ; , -> . . zulassen und Komma zu Punkt umwandeln
wParam = 46 ; .
ElseIf wParam = #CR Or wParam = #TAB
SetFocus_(GetNextDlgTabItem_(WindowID(#Wnd_World), hwnd, #False))
ElseIf (wParam < 48 Or wParam > 57) And wParam <> 45 And wParam <> #BS And wParam <> #DEL ;Zahlen, BS, DEL und Minus zulassen
wParam = 0
EndIf
EndIf
ProcedureReturn CallWindowProc_(*OldMSCb, hwnd, msg, wParam, lParam)
EndProcedure
Procedure.l Tscb(hwnd, msg, wParam, lParam)
Shared *OldTSCb
If msg = #WM_CHAR
If wParam = 44 Or wParam = 46 ; , -> .
wParam = 46 ; .
ElseIf wParam = 42 ; * -> x
wParam = 120
ElseIf wParam = 47 Or wParam = 59 ; / -> ;
wParam = 59
ElseIf wParam = #CR Or wParam = #TAB
SetFocus_(GetNextDlgTabItem_(WindowID(#Wnd_World), hwnd, #False))
ElseIf (wParam < 48 Or wParam > 57) And wParam <> 45 And wParam <> #BS And wParam <> #DEL And wParam <> 32 ;Zahlen, BS, DEL, SPACE und Minus zulassen
wParam = 0
EndIf
EndIf
ProcedureReturn CallWindowProc_(*OldTSCb, hwnd, msg, wParam, lParam)
EndProcedure
Procedure.l Rscb(hwnd, msg, wParam, lParam)
Shared *OldRSCb
If msg = #WM_CHAR
If wParam = #CR Or wParam = #TAB
SetFocus_(GetNextDlgTabItem_(WindowID(#Wnd_World), hwnd, #False))
ElseIf (wParam < 49 Or wParam > 52) And wParam <> #BS And wParam <> #DEL And wParam <> 32
wParam = 0
EndIf
EndIf
ProcedureReturn CallWindowProc_(*OldRSCb, hwnd, msg, wParam, lParam)
EndProcedure
Procedure.l ccb(hwnd, msg, wParam, lParam)
Shared Datei, ighwnd, Austext
Static xfrm.XFORM, eins.XForm, bp.RECT, cw, ch, MPos.MPos, OMPos.MPos, MBState, RBrush, GBrush
Protected OBrush, rc.RECT
Select msg
Case #WM_CREATE
RBrush = CreateSolidBrush_(RGB(255, 0, 0))
GBrush = CreateSolidBrush_(RGB(0, 255, 0))
LoadFont(0, "ArialBlack", 20)
LoadFont(1, "ArialBlack", 10)
eins\eM11 = 1
eins\em12 = 0
eins\eM21 = 0
eins\eM22 = 1
eins\eDx = 0
eins\eDy = 0
ProcedureReturn 0
Case #WM_DESTROY
DeleteObject_(RBrush)
DeleteObject_(GBrush)
ProcedureReturn 0
Case #cms_SetValues
xfrm\eM11 = ValF(GetGadgetText(#Str_em11))
xfrm\eM12 = ValF(GetGadgetText(#Str_em12))
xfrm\eM21 = ValF(GetGadgetText(#Str_em21))
xfrm\eM22 = ValF(GetGadgetText(#Str_em22))
xfrm\eDx = ValF(GetGadgetText(#Str_eDx))
xfrm\eDy = ValF(GetGadgetText(#Str_eDy))
If IsImage(#img_Bild)
iw = ImageWidth(#img_Bild)
ih = ImageHeight(#img_Bild)
If iw > (cw - 50)
wn = cw - 50
ih = ih * wn / iw
iw = wn
EndIf
If ih > (ch - 50)
hn = ch - 50
iw = iw * hn / ih
ih = hn
EndIf
bp\left = (cw - iw) / 2 - cw / 2
bp\top = (ch - ih) / 2 - ch / 2
bp\right = iw
bp\bottom = ih
EndIf
ProcedureReturn 0
Case #WM_PAINT
hdc = BeginPaint_(hwnd, @ps.PAINTSTRUCT)
; Muß gemacht werden damit Setworldtransform funktioniert
SetGraphicsMode_(hdc, #GM_ADVANCED)
SetWindowOrgEx_(hdc, -cw / 2, -ch / 2, 0)
SelectObject_(hdc, GetStockObject_(#HOLLOW_BRUSH))
; *********************************************************
; Transformation setzen
; *********************************************************
SetWorldTransform_(hdc, @xfrm)
SetStretchBltMode_(hdc, #COLORONCOLOR)
SetBkMode_(hdc, #TRANSPARENT)
OldF = SelectObject_(hdc, FontID(0))
If IsImage(0)
hdc1 = CreateCompatibleDC_(hdc)
SelectObject_(hdc1, ImageID(#img_Bild))
StretchBlt_(hdc, bp\left, bp\top, bp\right, bp\bottom, hdc1, 0, 0, ImageWidth(#img_Bild), ImageHeight(#img_Bild), #SRCCOPY)
TextOut_(hdc, bp\left, bp\top - 30, @Datei, Len(Datei))
DeleteDC_(hdc1)
EndIf
Ellipse_(hdc, -5, -5, 5, 5)
TextOut_(hdc, 5, 5, "Mitte", 5)
SelectObject_(hdc, RBrush)
Ellipse_(hdc, MPos\x - cw / 2 - 10, MPos\y - ch / 2 - 10, MPos\x - cw / 2 + 10, MPos\y - ch / 2 + 10)
SelectObject_(hdc, GetStockObject_(#HOLLOW_BRUSH))
Rectangle_(hdc, -cw / 2, - ch / 2, cw / 2, ch / 2)
MoveToEx_(hdc, -cw / 2, -ch / 2, #Null)
LineTo_(hdc, cw / 2, ch / 2)
MoveToEx_(hdc, cw / 2, -ch / 2, #Null)
LineTo_(hdc, -cw / 2, ch / 2)
TextOut_(hdc, -cw / 2 + 2, - ch / 2 + 2, "Oben links", 10)
; ***************************************************************
; Transformation zurücksetzen durch benutzen des Einheitsvektors
; ***************************************************************
SetWorldTransform_(hdc, @eins)
; Dieser Kreis muss im untransformierten Raum gezeichnet werden, da er die tatsächliche Mausposition darstellt
SelectObject_(hdc, GBrush)
Ellipse_(hdc, MPos\x - cw / 2 - 10, MPos\y - ch / 2 - 10, MPos\x - cw / 2 + 10, MPos\y - ch / 2 + 10)
SetBkMode_(hdc, #OPAQUE)
SelectObject_(hdc, FontID(1))
rc\left = -cw / 2 + 5
rc\top = -ch / 2 + 30
rc\right = cw - 10
rc\bottom = ch - 35
DrawText_(hdc, Austext, -1, @rc, 0)
xM = MPos\x - cw / 2
yM = MPos\y - ch / 2
; Endpunkte der Linie "von Hand" mithilfe der Transformationsmatrix umrechnen da ein Ende im normalen und eins im transformierten Raum ist
; und die Linie in keinen der Räume direkt gezeichnet werden könnte
x1 = xM * xFrm\eM11 + ym * xfrm\eM21 + xFrm\eDx
y1 = xM * xFrm\em12 + ym * xfrm\em22 + xFrm\eDy
MoveToEx_(hdc, xM, yM, #Null)
LineTo_(hdc, x1, y1)
SelectObject_(hdc, OldF)
EndPaint_(hwnd, @ps)
ProcedureReturn 0
Case #WM_LBUTTONDOWN
MPos\x = lParam & $FFFF
MPos\y = lParam >> 16
SetCapture_(hwnd)
MBState = #True
OMPos\x = MPos\x
OMPos\y = MPos\y
InvalidateRect_(hwnd, 0, #True)
ProcedureReturn 0
Case #WM_LBUTTONUP
MBState = #False
ReleaseCapture_()
ProcedureReturn 0
Case #WM_MOUSEMOVE
MPos\x = lParam & $FFFF
MPos\y = lParam >> 16
If ((MPos\x <> OMPos\x) Or (MPos\y <> OMPos\y)) And MBState
OMPos\x = MPos\x
OMPos\y = MPos\y
InvalidateRect_(hwnd, 0, #True)
EndIf
Case #WM_SIZE
cw = lParam & $FFFF
ch = lParam >> 16
If IsImage(#img_Bild)
iw = ImageWidth(#img_Bild)
ih = ImageHeight(#img_Bild)
If iw > (cw - 50)
wn = cw - 50
ih = ih * wn / iw
iw = wn
EndIf
If ih > (ch - 50)
hn = ch - 50
iw = iw * hn / ih
ih = hn
EndIf
bp\left = (cw - iw) / 2
bp\top = (ch - ih) / 2
bp\right = iw
bp\bottom = ih
InvalidateRect_(hwnd, 0, #True)
EndIf
ProcedureReturn 0
EndSelect
ProcedureReturn DefWindowProc_(hwnd, msg, wParam, lParam)
EndProcedure
Procedure wcb(hwnd, msg, wParam, lParam)
Protected XFRM1.XFORM, XFRM2.XFORM
Shared Datei.s, ighwnd, Austext
Static Pos1, Pos2, Pos3, Pos4, strTimer.s, AzTimer.l, SDat.s, ODat.s
Dim ModNr(3)
Ergebnis = #PB_ProcessPureBasicEvents
Select msg
Case #WM_COMMAND
If lParam <> 0
; Ein Button wurde gedrückt
Select wParam & $FFFF
Case #btn_Datei
dt.s = OpenFileRequester("Bilddatei wählen", Datei, "Bilder|*.bmp;*.jpg;*.jpeg;*.png|Alles|*.*", 0)
If dt <> ""
If LoadImage(#img_Bild, dt)
Datei = dt
SendMessage_(ighwnd, #cms_SetValues, 0, 0)
InvalidateRect_(ighwnd, 0, #True)
EndIf
Else
FreeImage(#img_Bild)
InvalidateRect_(ighwnd, 0, #True)
EndIf
Case #btn_Use
Austext = "Matrix"
SendMessage_(ighwnd, #cms_SetValues, 0, 0)
InvalidateRect_(ighwnd, 0, #True)
; **************************************************************
; Ab hier wird die Matrix mit den entsprechenden Werten gefüllt
; **************************************************************
Case #btn_Rotate
Pos1 + 1
ttx.s = StringField(GetGadgetText(#str_Rotate), Pos1, ";")
If ttx = ""
Pos1 = 1
ttx.s = StringField(GetGadgetText(#str_Rotate), Pos1, ";")
EndIf
wkl.f = ValF(ttx)
wklBM.f = wkl * #PI / 180.0
SetGadgetText(#Str_em11, StrF(Cos(wklBM)))
SetGadgetText(#Str_em12, StrF(Sin(wklBM)))
SetGadgetText(#Str_em21, StrF(-Sin(wklBM)))
SetGadgetText(#Str_em22, StrF(Cos(wklBM)))
SetGadgetText(#Str_eDx, "0")
SetGadgetText(#Str_eDy, "0")
Austext = "Rotate " + ttx
SendMessage_(ighwnd, #cms_SetValues, 0, 0)
InvalidateRect_(ighwnd, 0, #True)
Case #btn_Shear
Pos2 + 1
ttx = StringField(GetGadgetText(#str_Shear), Pos2, ";")
If ttx = ""
Pos2 = 1
ttx.s = StringField(GetGadgetText(#str_Shear), Pos2, ";")
EndIf
shx.f = ValF(Trim(StringField(ttx, 1, "x")))
shy.f = ValF(Trim(StringField(ttx, 2, "x")))
SetGadgetText(#Str_em11, "1")
SetGadgetText(#Str_em12, StrF(shx))
SetGadgetText(#Str_em21, StrF(shy))
SetGadgetText(#Str_em22, "1")
SetGadgetText(#Str_eDx, "0")
SetGadgetText(#Str_eDy, "0")
Austext = "Shear " + ttx
SendMessage_(ighwnd, #cms_SetValues, 0, 0)
InvalidateRect_(ighwnd, 0, #True)
Case #btn_Reflect
Pos3 + 1
ttx = StringField(GetGadgetText(#str_Reflect), Pos3, ";")
If ttx = ""
Pos3 = 1
ttx.s = StringField(GetGadgetText(#str_Reflect), Pos3, ";")
EndIf
shx.f = ValF(Trim(StringField(ttx, 1, "x")))
shy.f = ValF(Trim(StringField(ttx, 2, "x")))
SetGadgetText(#Str_em11, StrF(shx))
SetGadgetText(#Str_em12, "0")
SetGadgetText(#Str_em21, "0")
SetGadgetText(#Str_em22, StrF(shy))
SetGadgetText(#Str_eDx, "0")
SetGadgetText(#Str_eDy, "0")
Austext = "Scale " + ttx
SendMessage_(ighwnd, #cms_SetValues, 0, 0)
InvalidateRect_(ighwnd, 0, #True)
Case #btn_Move
Pos4 + 1
ttx = StringField(GetGadgetText(#str_Move), Pos4, ";")
If ttx = ""
Pos4 = 1
ttx.s = StringField(GetGadgetText(#str_Move), Pos4, ";")
EndIf
shx.f = ValF(Trim(StringField(ttx, 1, "x")))
shy.f = ValF(Trim(StringField(ttx, 2, "x")))
SetGadgetText(#Str_em11, "1")
SetGadgetText(#Str_em12, "0")
SetGadgetText(#Str_em21, "0")
SetGadgetText(#Str_em22, "1")
SetGadgetText(#Str_eDx, StrF(shx))
SetGadgetText(#Str_eDy, StrF(shy))
Austext = "Move " + ttx
SendMessage_(ighwnd, #cms_SetValues, 0, 0)
InvalidateRect_(ighwnd, 0, #True)
Case #btn_Matrix
reihe.s = GetGadgetText(#str_Reihenfolge)
For i = 0 To 3
ModNr(i) = 0
Next i
;********************************************************************************************
;Gesamtmatrix aus den einzelnen Transformationsmatrizen berechnen mittels CombineTransform_()
;********************************************************************************************
;erste Matrix mit Einheitsmatrix füllen
XFRM1\eM11 = 1
XFrm1\eM12 = 0
XFrm1\eM21 = 0
XFrm1\eM22 = 1
XFrm1\eDx = 0
XFrm1\eDy = 0
If GetGadgetText(#btn_Replay) = "Stop"
Austext = "Zeitlupe:" + #CRLF$
Else
Austext = "Kombiniert:" +#CRLF$
EndIf
For i = 1 To Len(reihe)
aktM = Val(Mid(reihe, i, 1))
If aktM > 0 And aktM < 5
ModNr(AktM - 1) + 1
; XFrm2 ausfüllen
Select aktM
; Zweite Matrix mit entsprechenden Werten befüllen
Case 1 ; Rotate
AktField.s = GetGadgetText(#str_Rotate)
Aktion.s = Trim(StringField(AktField, ModNr(AktM - 1), ";"))
If Aktion = ""
ModNr(AktM - 1) = 1
Aktion.s = Trim(StringField(AktField, ModNr(AktM - 1), ";"))
EndIf
wkl.f = ValF(Aktion)
wklBM.f = wkl * #PI / 180.0
XFrm2\eM11 = Cos(wklBM)
XFrm2\eM12 = Sin(wklBM)
XFrm2\eM21 = -Sin(wklBM)
XFrm2\eM22 = Cos(wklBM)
XFrm2\eDx = 0
XFrm2\eDy = 0
Austext + "Rotate " + Aktion + #CRLF$
Case 2 ; Scheren
AktField = GetGadgetText(#str_Shear)
Aktion = Trim(StringField(AktField, ModNr(AktM - 1), ";"))
If Aktion = ""
ModNr(AktM - 1) = 1
Aktion.s = Trim(StringField(AktField, ModNr(AktM - 1), ";"))
EndIf
shx.f = ValF(Trim(StringField(Aktion, 1, "x")))
shy.f = ValF(Trim(StringField(Aktion, 2, "x")))
XFrm2\eM11 = 1
XFrm2\eM12 = shx
XFrm2\eM21 = shy
XFrm2\eM22 = 1
XFrm2\eDx = 0
XFrm2\eDy = 0
Austext + "Shear " + Aktion + #CRLF$
Case 3 ;Skalieren / Reflektieren
AktField = GetGadgetText(#str_Reflect)
Aktion = Trim(StringField(AktField, ModNr(AktM - 1), ";"))
If Aktion = ""
ModNr(AktM - 1) = 1
Aktion.s = Trim(StringField(AktField, ModNr(AktM - 1), ";"))
EndIf
shx.f = ValF(Trim(StringField(Aktion, 1, "x")))
shy.f = ValF(Trim(StringField(Aktion, 2, "x")))
XFrm2\eM11 = shx
XFrm2\eM12 = 0
XFrm2\eM21 = 0
XFrm2\eM22 = shy
XFrm2\eDx = 0
XFrm2\eDy = 0
Austext + "Scale " + Aktion + #CRLF$
Case 4 ; Verschieben
AktField = GetGadgetText(#str_Move)
Aktion = Trim(StringField(AktField, ModNr(AktM - 1), ";"))
If Aktion = ""
ModNr(AktM - 1) = 1
Aktion.s = Trim(StringField(AktField, ModNr(AktM - 1), ";"))
EndIf
shx.f = ValF(Trim(StringField(Aktion, 1, "x")))
shy.f = ValF(Trim(StringField(Aktion, 2, "x")))
XFrm2\eM11 = 1
XFrm2\eM12 = 0
XFrm2\eM21 = 0
XFrm2\eM22 = 1
XFrm2\eDx = shx
XFrm2\eDy = shy
Austext + "Move " + Aktion + #CRLF$
EndSelect
; Matrix1 = Matrix1 x Matrix2
CombineTransform_(@XFrm1, @XFrm1, @XFrm2)
EndIf
Next i
If GetGadgetText(#btn_Replay) = "Stop" And AzTimer < Len(strTimer)
AusText + "----------------" + #CRLF$
nz = AzTimer + 1
na.s = Mid(strTimer, nz, 1)
While na = " " And nz < Len(strTimer)
nz + 1
na = Mid(strTimer, nz, 1)
Wend
Select Val(na)
Case 1
Aktion = StringField(GetGadgetText(#str_Rotate), ModNr(0) + 1, ";")
If Aktion = ""
Aktion = StringField(GetGadgetText(#str_Rotate), 1, ";")
EndIf
AusText + "Rotate " + Aktion
Case 2
Aktion = StringField(GetGadgetText(#str_Shear), ModNr(1) + 1, ";")
If Aktion = ""
Aktion = StringField(GetGadgetText(#str_Shear), 1, ";")
EndIf
AusText + "Shear " + Aktion
Case 3
Aktion = StringField(GetGadgetText(#str_Reflect), ModNr(2) + 1, ";")
If Aktion = ""
Aktion = StringField(GetGadgetText(#str_Reflect), 1, ";")
EndIf
AusText + "Scale " + Aktion
Case 4
Aktion = StringField(GetGadgetText(#str_Move), ModNr(3) + 1, ";")
If Aktion = ""
Aktion = StringField(GetGadgetText(#str_Move), 1, ";")
EndIf
AusText + "Move " + Aktion
EndSelect
EndIf
SetGadgetText(#Str_em11, StrF(XFrm1\eM11))
SetGadgetText(#Str_em12, StrF(XFrm1\eM12))
SetGadgetText(#Str_em21, StrF(XFrm1\eM21))
SetGadgetText(#Str_em22, StrF(XFrm1\eM22))
SetGadgetText(#Str_eDx, StrF(XFrm1\eDx))
SetGadgetText(#Str_eDy, StrF(XFrm1\eDy))
SendMessage_(ighwnd, #cms_SetValues, 0, 0)
InvalidateRect_(ighwnd, 0, #True)
Case #btn_Replay
If GetGadgetText(#btn_Replay) = "Stop"
KillTimer_(hwnd, 0)
For i = #Str_em11 To #btn_Save
DisableGadget(i, #False)
Next i
SetGadgetText(#str_Reihenfolge, strTimer)
SendMessage_(hwnd, #WM_COMMAND, #btn_Matrix, GadgetID(#btn_Matrix))
SetGadgetText(#btn_Replay, "Zeitlupe")
Else
For i = #Str_em11 To #btn_Save
DisableGadget(i, #True)
Next i
DisableGadget(#btn_Replay, #False)
AzTimer = 0
strTimer = GetGadgetText(#str_Reihenfolge)
SetGadgetText(#str_Reihenfolge, "")
SendMessage_(hwnd, #WM_COMMAND, #btn_Matrix, GadgetID(#btn_Matrix))
SetGadgetText(#btn_Replay, "Stop")
SetTimer_(hwnd, 0, Val(GetGadgetText(#str_Replay)), #Null)
EndIf
Case #btn_Save
SDat.s = SaveFileRequester("Transformieren Werte sichern", SDat, "WorldDat|*.wdt", 0)
If SDat <> ""
PathAddExtensionA(SDat, ".wdt")
aw = #PB_MessageRequester_Yes
If PathFileExists_(SDat)
aw = MessageRequester("WorldTransform", "Datei existiert schon," + #CRLF$ + "Überschreiben?", #PB_MessageRequester_YesNo | #MB_ICONQUESTION)
EndIf
If aw = #PB_MessageRequester_Yes
If CreateFile(0, SDat)
WriteStringN(0, Datei, #PB_Ascii)
For i = #Str_em11 To #str_Replay
WriteStringN(0, GetGadgetText(i))
Next i
CloseFile(0)
Else
MessageRequester("WorldTransform", "Datei konnte nicht geschrieben werden", #MB_ICONERROR)
EndIf
EndIf
EndIf
Case #btn_Load
ODat = OpenFileRequester("Transformieren Werte laden", ODat, "WorldDat|*.wdt", 0)
If ODat <> ""
If OpenFile(0, ODat) <> 0
Datei = ReadString(0, #PB_Ascii)
If Datei <> ""
LoadImage(#img_Bild, Datei)
If IsImage(0) = #False
MessageRequester("WorldTransform", "Bild konnte nicht geladen werden", #MB_ICONINFORMATION)
Datei = ""
EndIf
For i = #Str_em11 To #str_Replay
SetGadgetText(i, ReadString(0, #PB_Ascii))
Next i
EndIf
CloseFile(0)
SendMessage_(ighwnd, #cms_SetValues, 0, 0)
InvalidateRect_(ighwnd, 0, #True)
EndIf
EndIf
EndSelect
EndIf
ProcedureReturn 0
Case #WM_TIMER
azTimer + 1
While Mid(strTimer, azTimer, 1) = " " And azTimer < Len(strTimer)
azTimer + 1
Wend
SetGadgetText(#str_Reihenfolge, Left(strTimer, AzTimer))
SendMessage_(hwnd, #WM_COMMAND, #btn_Matrix, GadgetID(#btn_Matrix))
If AzTimer >= Len(strTimer)
KillTimer_(hwnd, 0)
For i = #Str_em11 To #btn_Save
DisableGadget(i, #False)
Next i
SetGadgetText(#btn_Replay, "Zeitlupe")
EndIf
ProcedureReturn 0
Case #WM_SIZE
ww = lParam & $FFFF
wh = lParam >> 16
hDWP = BeginDeferWindowPos_(34)
DeferWindowPos_(hDWP, ighwnd, 0, 0, 0, ww - 160, wh, #SWP_NOMOVE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Datei), 0, ww - 150, 10, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_0), 0, ww - 150, 50, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Str_em11), 0, ww - 150, 70, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_1), 0, ww - 150, 95, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Str_em12), 0, ww - 150, 115, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_2), 0, ww - 150, 140, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Str_em21), 0, ww - 150, 160, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_3), 0, ww - 150, 185, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Str_em22), 0, ww - 150, 205, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_4), 0, ww - 150, 230, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Str_eDx), 0, ww - 150, 250, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_5), 0, ww - 150, 275, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Str_eDy), 0, ww - 150, 295, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Use), 0, ww - 150, 325, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_6), 0, ww - 150, 360, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#str_Rotate), 0, ww - 150, 380, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Rotate), 0, ww - 30, 380, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_7), 0, ww - 150, 405, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#str_Shear), 0, ww - 150, 425, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Shear), 0, ww - 30, 425, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_8), 0, ww - 150, 450, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#str_Reflect), 0, ww - 150, 470, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Reflect), 0, ww - 30, 470, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_9), 0, ww - 150, 495, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#str_Move), 0, ww - 150, 515, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Move), 0, ww - 30, 515, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#Text_11), 0, ww - 150, 540, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#str_Reihenfolge), 0, ww - 150, 560, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Matrix), 0, ww - 150, 585, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Replay), 0, ww - 150, 615, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#str_Replay), 0, ww - 150, 645, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Save), 0, ww - 150, 670, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
DeferWindowPos_(hDWP, GadgetID(#btn_Load), 0, ww - 150, 700, 0, 0, #SWP_NOSIZE | #SWP_NOZORDER)
EndDeferWindowPos_(hDWP)
ProcedureReturn 0
Case #WM_GETMINMAXINFO
*mima.MINMAXINFO = lParam
*mima\ptMinTrackSize\x = 400
*mima\ptMinTrackSize\y = 200
ProcedureReturn 0
EndSelect
ProcedureReturn Ergebnis
EndProcedure
hwnd = OpenWindow(#Wnd_World, 216, 0, 1024, 768, "WorldTransform", #WS_OVERLAPPEDWINDOW )
If hwnd
If CreateGadgetList(WindowID(#Wnd_World))
ButtonGadget(#btn_Datei, 874, 10, 140, 30, "Bild laden")
TextGadget(#Text_0, 874, 50, 90, 20, "em11")
StringGadget(#Str_em11, 874, 70, 140, 20, "")
TextGadget(#Text_1, 874, 95, 80, 20, "em12")
StringGadget(#Str_em12, 874, 115, 140, 20, "")
TextGadget(#Text_2, 874, 140, 80, 20, "em21")
StringGadget(#Str_em21, 874, 160, 140, 20, "")
TextGadget(#Text_3, 874, 185, 80, 20, "em22")
StringGadget(#Str_em22, 874, 205, 140, 20, "")
TextGadget(#Text_4, 874, 230, 70, 20, "eDx")
StringGadget(#Str_eDx, 874, 250, 140, 20, "")
TextGadget(#Text_5, 874, 275, 80, 20, "eDy")
StringGadget(#Str_eDy, 874, 295, 140, 20, "")
ButtonGadget(#btn_Use, 874, 325, 140, 30, "Use")
TextGadget(#Text_6, 874, 360, 80, 20, "1.Rotation")
StringGadget(#str_Rotate, 874, 380, 120, 20, "0")
ButtonGadget(#btn_Rotate, 994, 380, 20, 20, ">")
TextGadget(#Text_7, 874, 405, 80, 20, "2.Scheren")
StringGadget(#str_Shear, 874, 425, 120, 20, "0 x 0")
ButtonGadget(#btn_Shear, 994, 425, 20, 20, ">")
TextGadget(#Text_8, 874, 450, 140, 20, "3.Skalieren / Spiegeln")
StringGadget(#str_Reflect, 874, 470, 120, 20, "1 x 1")
ButtonGadget(#btn_Reflect, 994, 470, 20, 20, ">")
TextGadget(#Text_9, 874, 495, 80, 20, "4.Verschieben")
StringGadget(#str_Move, 874, 515, 120, 20, "0 x 0")
ButtonGadget(#btn_Move, 994, 515, 20, 20, ">")
TextGadget(#Text_11, 874, 540, 80, 20, "Reihenfolge")
StringGadget(#str_Reihenfolge, 874, 560, 140, 20, "1234")
ButtonGadget(#btn_Matrix, 874, 585, 140, 30, "Zu Matrix")
ButtonGadget(#btn_Replay, 874, 615, 140, 30, "Zeitlupe")
StringGadget(#str_Replay, 874, 645, 140, 20, "1000", #PB_String_Numeric)
ButtonGadget(#btn_Save, 874, 670, 140, 30, "Speichern")
ButtonGadget(#btn_Load, 874, 700, 140, 30, "Daten laden")
*OldMSCb = SetWindowLong_(GadgetID(#Str_em11), #GWL_WNDPROC, @Mscb())
SetWindowLong_(GadgetID(#Str_em12), #GWL_WNDPROC, @Mscb())
SetWindowLong_(GadgetID(#Str_em21), #GWL_WNDPROC, @Mscb())
SetWindowLong_(GadgetID(#Str_em22), #GWL_WNDPROC, @Mscb())
SetWindowLong_(GadgetID(#Str_eDx), #GWL_WNDPROC, @Mscb())
SetWindowLong_(GadgetID(#Str_eDy), #GWL_WNDPROC, @Mscb())
*OldTSCb = SetWindowLong_(GadgetID(#str_Rotate), #GWL_WNDPROC, @Tscb())
SetWindowLong_(GadgetID(#str_Shear), #GWL_WNDPROC, @Tscb())
SetWindowLong_(GadgetID(#str_Reflect), #GWL_WNDPROC, @Tscb())
SetWindowLong_(GadgetID(#str_Move), #GWL_WNDPROC, @Tscb())
*OldRSCb = SetWindowLong_(GadgetID(#str_Reihenfolge), #GWL_WNDPROC, @Rscb())
*OldBCb = SetWindowLong_(GadgetID(#btn_Datei), #GWL_WNDPROC, @Bcb())
SetWindowLong_(GadgetID(#btn_Use), #GWL_WNDPROC, @Bcb())
SetWindowLong_(GadgetID(#btn_Matrix), #GWL_WNDPROC, @Bcb())
SetWindowLong_(GadgetID(#btn_Move), #GWL_WNDPROC, @Bcb())
SetWindowLong_(GadgetID(#btn_Reflect), #GWL_WNDPROC, @Bcb())
SetWindowLong_(GadgetID(#btn_Rotate), #GWL_WNDPROC, @Bcb())
SetWindowLong_(GadgetID(#btn_Shear), #GWL_WNDPROC, @Bcb())
SetWindowLong_(GadgetID(#btn_Replay), #GWL_WNDPROC, @Bcb())
SetWindowLong_(GadgetID(#str_em11), #GWL_STYLE, GetWindowLong_(GadgetID(#str_em11), #GWL_STYLE) | #WS_TABSTOP)
SetWindowLong_(GadgetID(#str_em12), #GWL_STYLE, GetWindowLong_(GadgetID(#str_em12), #GWL_STYLE) | #WS_TABSTOP)
SetWindowLong_(GadgetID(#str_em21), #GWL_STYLE, GetWindowLong_(GadgetID(#str_em21), #GWL_STYLE) | #WS_TABSTOP)
SetWindowLong_(GadgetID(#str_em22), #GWL_STYLE, GetWindowLong_(GadgetID(#str_em22), #GWL_STYLE) | #WS_TABSTOP)
SetWindowLong_(GadgetID(#str_Rotate), #GWL_STYLE, GetWindowLong_(GadgetID(#str_Rotate), #GWL_STYLE) | #WS_TABSTOP)
SetWindowLong_(GadgetID(#str_Shear), #GWL_STYLE, GetWindowLong_(GadgetID(#str_Shear), #GWL_STYLE) | #WS_TABSTOP)
SetWindowLong_(GadgetID(#str_Reflect), #GWL_STYLE, GetWindowLong_(GadgetID(#str_Reflect), #GWL_STYLE) | #WS_TABSTOP)
SetWindowLong_(GadgetID(#str_Move), #GWL_STYLE, GetWindowLong_(GadgetID(#str_Move), #GWL_STYLE) | #WS_TABSTOP)
bcl.s = "WorldBildCtrl"
With wcl.WNDCLASS
\Style = #CS_HREDRAW | #CS_VREDRAW
\lpfnWndProc = @ccb()
\cbClsExtra = 0
\cbWndExtra = 0
\hInstance = GetModuleHandle_(0)
\hIcon = LoadIcon_(0,#IDI_APPLICATION)
\hCursor = LoadCursor_(0, #IDC_CROSS)
\hbrBackground = GetStockObject_(#WHITE_BRUSH)
\lpszClassName = @bcl
\lpszMenuName = #Null
EndWith
If RegisterClass_(@wcl) = 0
End
EndIf
ighwnd = CreateWindowEx_(0, bcl, "", #WS_CHILD | #WS_VISIBLE, 0, 0, 864, 768, hwnd, #Cnt_Bild, GetModuleHandle_(0), 0)
SetWindowCallback(@wcb())
Repeat
event = WaitWindowEvent()
Until event = #PB_Event_CloseWindow
EndIf
EndIf
Mit Laden lässt sich ein Bild laden welches in der Mitte des Ausgabebereichs dargestellt wird.
Die 6 Stringgadgets darunter stellen die Transformationsmatrix dar:
|em11 em12 0|
|em21 em22 0|
|eDx eDy 1|
Mit Use werden diese Werte in die Transformationsmatrix des Devicekontext übernommen.
Im Stringgadget Rotation kann ein Wert oder mehrere Werte eingegeben werden die den /die Winkel angeben, um den der Inhalt des DCs gedreht werden soll (in °), mehrere Werte können durch ein Semikolon getrennt werden.
Bei Scheren wird ein Wert oder mehrere Werte erwartet, der angibt, wie weit der Inhalt des DCs gestaucht werden soll. Die Werte für Horizontaler und vertikaler Skalierung müssen mit einem x voneinander getrent werden, mehrere Wertepaare durch ein Semikolon (dies gilt genauso für die folgenden Werte). Das Format ist dabei:
ScherenHor x ScherenVertikal [; ScherenHor x ScherenVertikal]
(Angaben in eckiger Klammer optional)
Unter Skalieren / Spiegeln wird eingestellt, um welchen Wert der Inhalt vergrößert (>1) / verkleinert (<1) wird, bei negativen Werten wird der Inhalt gespiegelt. Format:
SkalierenHor x SkalierenVertikal [; SkalierenHor x SkalierenVertikal]
Die Werte in Verschieben legen fest, um wieviel Pixel der Inhalt des DCs vertikal bzw. horizontal verschoben werden soll. Positive Werte verschieben nach rechts / unten, negative nach links / oben. Format:
VerschiebenHor x VerschiebenVert [; VerschiebenHor x VerschiebenVert]
Die mit ">" beschrifteten Schaltflächen, welche sich rechts neben den Stringgadget befinden übertragen das jeweils erste Wertepaar / den ersten Wert des zugehörigen Stringgadgets in die Transformationsmatrix und wenden diese an.
Die Schaltfläche Zu Matrix kombiniert die Transformationen zu einer einzelnen Transformationsmatrix, trägt die Werte in die Transformationsmatrix ein und wendet diese an.
Die Reihenfolge, in der dabei vorgegangen wird, hängt davon ab, was im gleichnamigen Stringgadget steht. 1234 Rotiert zuerst, Schert dann, anschließend wird Skaliert und zum Schluss Verschoben.
3241: Skalieren -> Scheren -> Verschieben -> Rotieren.
Es werden also nacheinander zur jeweiligen Nummer gehörigen Aktionen durchgeführt. Nummern können sich auch wiederholen, im zugehörigen Stringgadget müssen sich dann aber soviele Werte / Wertepaare befinden wie die Nummer vorkommt.
312143: Skalieren -> Rotieren -> Scheren -> Rotieren -> Verschieben -> Skalieren
Skalieren und Rotieren müssten dabei 2 Werte / Wertepaare enthalten.
Ich hoffe mal, das ist jetzt entweder nützlich oder cool.

Edit: Ich habe den code noch mal ein wenig verbessert. Mehrfaches klicken auf die > - Schaltfläche schaltet nun zum nächsten Wert / Wertepaar um, das im entsprechenden Stringgadget eingegeben wurde. Außerdem wird jetzt die jeweilige Aktion / Aktionen im Fenster dargestellt.
Nochmal Edit: Nochmal etwas verbessert und Fehler beseitigt
Letztes Edit: Nun läuft alles. Es gibt jetzt auch eine Zeitlupen - Funktion bei der alle Transformationen wie bei Reihenfolge angegeben hintereinander stattfinden, aber mit einem einstellbaren Zeitintervall dazwischen.
In den Stringgadgets können statt Punkten Kommas eingegeben werden, diese werden in Punkte umgewandelt. Die * - Taste kann statt x benutzt werden und wird ebenso automatisch in ein x umgewandelt. Ähnlich ist es mit der / - Taste, die in ein Semikolon umgewandelt wird. Auf diese Weise reicht die Zehnertastatur zum Eingeben aus.
Wie unten schon angegeben muß nicht mehr für jede in der Reihenfolge angegebene Zahl ein Wert in dem entsprechenden Stringgadget vorhanden sein, ist kein durch ein Semikolon abgetrennter Wert mhr vorhanden wird einfach wieder mit dem ersten Wert/Wertepaar weitergemacht.
Allerletztes Edit
