TRON is a short GDImage project, animating multiple layers in composited mode.I have also created a new WinLIFT's TRON theme to use with this project.
'+--------------------------------------------------------------------------+
'| TRON |
'| |
'| GDImage animation |
'| |
'+--------------------------------------------------------------------------+
'| |
'| Author Patrice TERRIER |
'| 8 Domaine de Rochagnon. 38800 Champagnier FRANCE |
'| http://www.zapsolution.com |
'| E-mail: pterrier@zapsolution.com |
'| |
'+--------------------------------------------------------------------------+
'| Project started on : 05-30-2011 |
'| Last revised : 05-31-2011 |
'+--------------------------------------------------------------------------+
#COMPILE EXE "Tron.exe"
#INCLUDE "WIN32API.inc"
#INCLUDE "GDImage.inc"
#INCLUDE "WinLIFT.inc"
#RESOURCE "Tron.pbr"
DECLARE FUNCTION zTrace LIB "zTrace.DLL" ALIAS "zTrace" (zMessage AS ASCIIZ) AS LONG
%CLIENT_WIDTH = 750
%CLIENT_HEIGHT = 450
%CTRL_WIDTH = 392
%CTRL_HEIGHT = 392
%IDC_GDImageCTRL = -1
%IDC_TIMER = 1
%ID_FIRST = 1
%ID_Layer1 = %ID_FIRST
%ID_Layer2 = %ID_FIRST + 1
%ID_Layer3 = %ID_FIRST + 2
%ID_Layer4 = %ID_FIRST + 3
%ID_Layer5 = %ID_FIRST + 4
%ID_Layer6 = %ID_FIRST + 5
%ID_LAST = %ID_Layer6
GLOBAL gnSkinActive AS LONG
FUNCTION WinMain (BYVAL hInstance AS LONG, _
BYVAL hPrevInstance AS LONG, _
BYVAL lpCmdLine AS ASCIIZ PTR, _
BYVAL iCmdShow AS LONG) AS LONG
LOCAL rc AS RECT
LOCAL Msg AS tagMsg
LOCAL wc AS WndClassEx
LOCAL zClass AS ASCIIZ * 80
LOCAL IsInitialized, x, y AS LONG, dwStyleEx, dwStyle, hMain AS DWORD
'
zClass = "ZTRON"
'
wc.cbSize = SIZEOF(wc)
IsInitialized = GetClassInfoEx(hInstance, zClass, wc)
IF IsInitialized& = 0 THEN
wc.cbSize = SIZEOF(wc)
wc.style = %CS_HREDRAW OR %CS_VREDRAW
wc.lpfnWndProc = CODEPTR(WndProc)
wc.cbClsExtra = 0
wc.cbWndExtra = 0 '// %EXTEND_EXTRA * 4
wc.hInstance = hInstance
wc.hIcon = LoadIcon(wc.hInstance, "PROGRAM")
wc.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW)
wc.hbrBackground = %NULL ' GetStockObject(%BLACK_BRUSH)
wc.lpszMenuName = %NULL
wc.lpszClassName = VARPTR(zClass)
wc.hIconSm = wc.hIcon
IF RegisterClassEx(wc) THEN IsInitialized = %TRUE
END IF
'
IF IsInitialized THEN
' Window Extended Style
dwStyleEx = %WS_EX_APPWINDOW OR %WS_EX_WINDOWEDGE
' Windows Style
dwStyle = %WS_OVERLAPPEDWINDOW OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
'
CALL SetRect(rc, 0, 0, %CLIENT_WIDTH, %CLIENT_HEIGHT )
CALL AdjustWindowRectEx(rc, dwStyle, %FALSE, dwStyleEx) ' Adjust Window To True Requested Size
'
x = MAX&((GetSystemMetrics(%SM_CXSCREEN) - rc.nRight - rc.nLeft) * 0.5, 0)
y = MAX&((GetSystemMetrics(%SM_CYSCREEN) - rc.nBottom - rc.nTop) * 0.5, 0)
'
' Create The Window
MyTitle$ = "TRON"
hMain = CreateWindowEx(dwStyleEx, _ ' Extended Style For The Window
zClass, _ ' Class Name
(MyTitle$), _ ' Window Title
dwStyle, _ ' Defined Window Style
x, y, _ ' Window Position
rc.nRight - rc.nLeft, _ ' Calculate Window Width
rc.nBottom - rc.nTop, _ ' Calculate Window Height
%NULL, _ ' No Parent Window
%NULL, _ ' No Menu
hInstance, _ ' Instance
BYVAL %NULL) ' Dont Pass Anything To WM_CREATE
'
IF hMain THEN
LOCAL sResPath AS STRING, nID, nW, nH AS LONG, hBitmap, hCtrl AS DWORD
sResPath = EXE.Path$ + "Resource\"
dwStyle = %WS_CHILD OR %WS_VISIBLE
x = (%CLIENT_WIDTH - %CTRL_WIDTH) * 0.5
y = (%CLIENT_HEIGHT - %CTRL_HEIGHT) * 0.5
hCtrl = CreateWindowEx(0, $GDImageClassName, "", dwStyle, x, y, %CTRL_WIDTH, %CTRL_HEIGHT, hMain, %IDC_GDImageCTRL, hInstance, BYVAL 0)
CALL ZI_SetAnchorMode(hCtrl, %ANCHOR_CENTER)
'// Gradiant color to paint the background
CALL ZI_SetProperty(hCtrl, %ZI_GradientTop, 0)
CALL ZI_SetProperty(hCtrl, %ZI_GradientBottom, 0)
FOR nID = %ID_FIRST TO %ID_LAST
hBitmap = ZI_CreateBitmapFromFile(sResPath + "Layer" + LTRIM$(STR$(nID)) + ".png", nW, nH)
ZD_DrawBitmapToCtrl(hCtrl, 0, 0, hBitmap, ZD_ColorARGB(255, 0), nID, %ZS_VISIBLE)
ZD_SetObjectLocked(nID, %TRUE)
NEXT
IF skInitEngine("Tron.sks", "") THEN
skSkinWindow(hMain, "Dock|Undock|Minimize|Maximize|Restore|Close")
gnSkinActive = -1
END IF
' Show the main window
CALL ShowWindow(hMain, %SW_SHOW)
CALL SetForegroundWindow(hMain) ' Slightly Higher Priority
CALL SetTimer(hMain, %IDC_TIMER, 0, %NULL)
WHILE GetMessage(Msg, %NULL, 0, 0)
'IF IsDialogMessage(hMain, Msg) = %FALSE THEN
CALL TranslateMessage(msg) ' Translate The Message
CALL DispatchMessage(msg) ' Dispatch The Message
'END IF
WEND
CALL KillTimer(hMain, %IDC_TIMER)
FUNCTION = msg.wParam
END IF
END IF
END FUNCTION
SUB RenderAnimation(BYVAL hWnd AS DWORD)
LOCAL nX, nY AS LONG
STATIC nFlip, nTempo AS LONG
IF nTempo < GetTickcount() THEN
ZD_GetObjectXY(%ID_Layer2, nX, nY)
IF nFlip = 0 THEN
IF nX > -68 THEN
nX -= 2
ELSE
nFlip = -1
END IF
ELSE
IF nX < 0 THEN
nX += 2
ELSE
nFlip = 0
END IF
END IF
ZD_SetObjectRed(%ID_Layer1, 187 + nX, %FALSE)
ZD_SetObjectBlue(%ID_Layer1, -nX * 2, %FALSE)
ZD_SetObjectXY(%ID_Layer2, nX, nY, %FALSE)
ZD_SetObjectXY(%ID_Layer3, -nX, nY, %FALSE)
ZD_SetObjectAngle(%ID_Layer5, -nX, %FALSE)
ZD_SetObjectAlpha(%ID_Layer6, 255 + nX, %FALSE)
ZD_SetObjectScale(%ID_Layer6, 1 + (-nX * 0.005))
ZI_UpdateWindow(GetDlgItem(hWnd, %IDC_GDImageCTRL), 0)
nTempo = GetTickCount() + 40 '// 25 FPS = 40 ticks
END IF
END SUB
FUNCTION WndProc(BYVAL hWnd AS DWORD, BYVAL Msg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
LOCAL ps AS PAINTSTRUCT
LOCAL rc AS RECT
SELECT CASE LONG Msg
' CASE %WM_CREATE
'
' CASE %WM_COMMAND
' SELECT CASE LONG LOWRD(wParam)
' END SELECT
CASE %WM_GETMINMAXINFO
LOCAL pMM AS MINMAXINFO PTR
pMM = lParam
IF gnSkinActive THEN
@pMM.ptMinTrackSize.x = MinTrackSizeX(0)
@pMM.ptMinTrackSize.y = MinTrackSizeY(0)
ELSE
CALL SetRect(rc, 0, 0, %CLIENT_WIDTH, %CLIENT_HEIGHT)
CALL AdjustWindowRectEx(rc, GetWindowLong(hWnd, %GWL_STYLE), %FALSE, GetWindowLong(hWnd, %GWL_EXSTYLE)) ' Adjust Window To True Requested Size
@pMM.ptMinTrackSize.x = rc.nRight - rc.nLeft
@pMM.ptMinTrackSize.y = rc.nBottom - rc.nTop
END IF
LOCAL hMonitor AS LONG, tmi AS MONITORINFO
hMonitor = MonitorFromWindow(hWnd, %MONITOR_DEFAULTTONEAREST)
tmi.cbSize = SIZEOF(tmi)
IF GetMonitorInfo(hMonitor, tmi) THEN
@pMM.ptMaxSize.x = tmi.rcWork.nRight - tmi.rcWork.nLeft
@pMM.ptMaxSize.y = tmi.rcWork.nBottom - tmi.rcWork.nTop
END IF
CASE %WM_ERASEBKGND
CALL GetClientRect(hWnd, rc)
CALL ZI_GradientPaintDC(wParam, 0, 0, rc.nRight, rc.nBottom, RGB(0,0,0), RGB(0,0,0))
FUNCTION = 1: EXIT FUNCTION
CASE %WM_TIMER
RenderAnimation(hWnd)
FUNCTION = 0: EXIT FUNCTION
' CASE %WM_PAINT
' FUNCTION = 0: EXIT FUNCTION
'
' CASE %WM_CLOSE
CASE %WM_DESTROY
CALL PostQuitMessage(0)
FUNCTION = 0: EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, Msg, wParam, lParam)
END FUNCTION
Added on 06-01-2011:
New 3D version
- With two visual plugins
- and two OGG audio files
...
As usually,
very nice! The CPU usage is about 24% on Core 2 Duo T6600 and Windows 7 64bit.
Petr
Petr,
Thank you!
I have added a new 3D version (i hope you will not encounter problems with the UAC).
The new Tron3D.zip file is attached to the first post of this thread.
Added:
Forget to say that you can use drag and drop to play a specific audio file.
...
Hi Patrice,
no problems with UAC, and same CPU usage as in 2D version.
I think Daft Punk should hire you to create on stage visualisations for their live concerts, especially the visualisation for the second music is very nice :)
Petr
Petr,
Thank you for the feedback :)
Now that you have moved to 7, you can try by yourself the power of VISTA/SEVEN when working in composited mode.
DWM is realy a big step forward when you know how to master the beast.
...
I have updated the 3D version with an extra animation.
(The motorcycle line is now moving from the right to the left side)
Note: Due to UAC you may not see the visual plugin the first time you fire the application.
...
I think i have solved the UAC problem that could be encountered when runing Tron3D for the first time.
Using my own shell replacement as shown here:
FUNCTION MyShell(zCmd AS ASCIIZ, BYVAL ShowWind AS LONG, BYVAL TimeLimit AS LONG) AS DWORD
LOCAL sif AS STARTUPINFO
LOCAL pif AS PROCESS_INFORMATION
LOCAL nRet AS LONG
LOCAL zClass AS ASCIIZ * 16
LOCAL hWndEx AS DWORD
sif.cb = SIZEOF(sif)
sif.dwFlags = %STARTF_USESHOWWINDOW
sif.wShowWindow = ShowWind
nRet = CreateProcess("", zCmd, _
BYVAL 0, BYVAL 0, %FALSE, %NORMAL_PRIORITY_CLASS, _
BYVAL 0, BYVAL 0, sif, pif)
IF nRet THEN
CALL WaitForInputIdle(pif.hProcess, %INFINITE)
IF TimeLimit THEN
zClass = "ZWALLPAPER"
hWndEx = FindWindow(zClass, "")
WHILE hWndEx = 0
CALL WaitForSingleObject(pif.hProcess, TimeLimit)
hWndEx = FindWindow(zClass, "")
WEND
CALL CloseHandle(pif.hProcess)
CALL CloseHandle(pif.hThread)
END IF
END IF
FUNCTION = hWndEx
END FUNCTION
Thus, the Tron3d.zip file attached to the first post of this thread has been updated.
...
The first post of this thread has been updated, to fix the ZIP file corruption caused by the "Server Collapse".
...
Challenging myself i have converted Tron3D to 64-bit.
I took this opportunity to rewrite the PowerBASIC code to match exactly the C++ one.
I also revisited the ZWP.bas bridge to use WM_COPYDATA to perform the intra process communication between 64 and 32-bit (rather than WM_SETTEXT).
Tron3D64.zip is the C++ 64-bit UNICODE version
Tron3D32.zip is the new PB 32-bit ANSI version
...
How exactly doers this UAC Problem happen and why did you need this workaround?
What is exactly different with YOUR MyShell then with a normal "Shell"-Call ?
UAC problem may occure when a shelled EXE is loading the extra DLLs (plugins) that are not used directly by the parent process. Usually this occures only the first time while the initial antivirus checking is performed.
However in the latest version i am not using anymore MyShell, but directly the flat API ShellExecute as a direct replacement for the PowerBASIC SHELL encapsulation statement.
Anyway, the best solution, when you download a ZIP for an external source is to unlock the ZIP file before unziping it.
Or to add the web site (you download from) to your trusted web site list.
...
The other solution to avoid the UAC problem, is to add a manifest like this one
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="www.zapsolution.com"
type="win32" />
<description>Manifest For ZAP</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*" />
</dependentAssembly>
</dependency>
</assembly>
This one must replace the default one used in the Visual Studio linker manifest option.
...