An animation control is a window that displays an Audio-Video Interleaved (AVI) clip. An AVI clip is a series of bitmap frames like a movie. Animation controls can only display AVI clips that do not contain audio.
One common use for an animation control is to indicate system activity during a lengthy operation. This is possible because the operation thread continues executing while the AVI clip is displayed. For example, the Find dialog box of Microsoft Windows Explorer displays a moving magnifying glass as the system searches for a file.
Note If you are using ComCtl32.dll version 6 the thread is not supported; make sure that your application does not block the UI, or else the animation will not occur.
Animation Control Creation
An animation control belongs to the ANIMATE_CLASS window class. You create an animation control by using the CreateWindow or CreateWindowEx functions or the Animate_Create function or macro. Animate_Create positions the animation control in the upper-left corner of the parent window and, if the ACS_CENTER style is not specified, sets the width and height of the control based on the dimensions of a frame in the AVI clip. If ACS_CENTER is specified, Animate_Create sets the width and height of the control to zero. You can use the SetWindowPos function to set the position and size of the control.
If you create an animation control within a dialog box or from a dialog box resource, the control is automatically destroyed when the user closes the dialog box. If you create an animation control within a window, you must explicitly destroy the control.
The following code creates an animation control using CreateWindowEx:
hWndChild = CreateWindowEx(
%NULL, _ ' extended styles
"SysAnimate32", _ ' class name
"", _ ' caption
%WS_CHILD OR %WS_VISIBLE OR _ ' window styles
%ACS_CENTER OR %ACS_TRANSPARENT OR _ ' class styles
%ACS_AUTOPLAY, _
250, 120, _ ' left, top
100, 100, _ ' width, height
hWnd, %IDC_ANIMATION1, _ ' handle of parent, control ID
GetModuleHandle(""), BYVAL %NULL)
The following code creates an animation control using the Animate_Create function:
Animate_Create hWnd, _ ' handle of the parent window
%IDC_ANIMATION, _ ' child window identifier of the animation control.
%WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR _ ' window styles
%ACS_TRANSPARENT OR %ACS_AUTOPLAY, _ ' class styles
GetModuleHandle("") ' instanc handle
' Get the handle of the animation control
hAnim = GetDlgItem(hWnd, %IDC_ANIMATION)
' Change the position of the window
SetWindowPos hAnim, %NULL, 250, 120, 0, 0, %SWP_NOSIZE OR %SWP_NOZORDER
Animation Control Messages
After creating an animation control, an application sends the ACM_OPEN message to open an AVI clip and load it into memory. The message specifies either the path of an AVI file or the name of an AVI resource. The system loads the AVI resource from the module that created the animation control.
' Open the AVI clip
szPath = "DRILLRLE.AVI"
' You can use the Animate_Open function or macro...
Animate_Open(hWndChild, szPath)
' ... or send the ACM_OPEN message explicitly.
'SendMessage hWndChild, %ACM_OPEN, 0, VARPTR(szPath)
If the animation control has the ACS_AUTOPLAY style, the control begins playing the AVI clip immediately after the AVI file or AVI resource is opened. Otherwise, an application can use the ACM_PLAY message to start the AVI clip. An application can stop the clip at any time by sending the ACM_STOP message. The last frame played remains displayed when the control finishes playing the AVI clip or when ACM_STOP is sent.
CASE %WM_COMMAND
SELECT CASE LO(DWORD, wParam)
CASE %IDC_PLAY
IF HIWRD(wParam) = %BN_CLICKED THEN
' Play the AVI clips
' You can use the Animate_Play function or macro...
Animate_Play(GetDlgItem(hWnd, %IDC_ANIMATION), 0, -1, -1)
' ... or send the ACM_PLAY message explicitly.
' SendMessage GetDlgItem(hWnd, %IDC_ANIMATION), %ACM_PLAY, -1, MAK(LONG, 0, -1)
EXIT FUNCTION
END IF
CASE %IDC_STOP
IF HIWRD(wParam) = %BN_CLICKED THEN
' Stop playing the AVI clips
' You can use the Animate_Stop function or macro...
Animate_Stop(GetDlgItem(hWnd, %IDC_ANIMATION))
' ... or send the ACM_STOP message explicitly.
' SendMessage GetDlgItem(hWnd, %IDC_ANIMATION), %ACM_STOP, 0, 0
EXIT FUNCTION
END IF
An animation control can send two notification messages to its parent window: ACN_START and ACN_STOP. Most applications do not handle either notification.
CASE %WM_COMMAND
SELECT CASE lParam
CASE GetDlgItem(hWnd, %IDC_ANIMATION)
SELECT CASE HI(WORD, wParam)
CASE %ACN_START
OutputDebugString "Start"
EXIT FUNCTION
CASE %ACN_STOP
OutputDebugString "Stop"
EXIT FUNCTION
END SELECT
To close the AVI file or AVI resource and remove it from memory, an application can use the Animate_Close macro, which sends ACM_OPEN with the file name or resource name set to NULL.
The following example creates a transparent, autoplaying animation control.
' ########################################################################################
' Animate Control example
' Copyright (c) 2011 José Roca
' Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#COMPILE EXE
#DIM ALL
'/* header files for imported files */
%UNICODE = 1
#INCLUDE ONCE "CWindow.inc"
#INCLUDE ONCE "AnimateCtrl.inc"
'/* resource file */
#RESOURCE RES, "EX_CW_ANIMATE_01.res"
'/* control identifier */
%IDC_ANIMATION = 101
' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Create an instance of the class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
pWindow.CreateWindow(%NULL, "AVI Example", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
' // Set the client size
pWindow.SetClientSize 500, 320
' // Center the window
pWindow.CenterWindow
' // Create a transparent AVI control
LOCAL hAnim AS DWORD
hAnim = pWindow.AddAnimation(pWindow.hwnd, %IDC_ANIMATION, "", 190, 90, 130, 130, _
%WS_CHILD OR %WS_VISIBLE OR %ACS_CENTER OR %ACS_TRANSPARENT OR %ACS_AUTOPLAY)
' // Open the AVI clip
Animate_Open(hAnim, "DRILLRLE.AVI")
' // Add a close button
pWindow.AddButton(pWindow.hwnd, %IDCANCEL, "&Close", 0, 0, 0, 0, -1, -1)
' // Force the resizing of the controls
pWindow.Resize
' // Default message pump (you can replace it with your own)
pWindow.DoEvents(nCmdShow)
' // Close the animation file
Animate_Close hAnim
END FUNCTION
' ########################################################################################
' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
STATIC pWindow AS IWindow ' // Reference to the IWindow interface
SELECT CASE uMsg
CASE %WM_CREATE
' // Get a reference to the IWindow interface from the CREATESTRUCT structure
pWindow = CWindow_GetObjectFromCreateStruct(lParam)
EXIT FUNCTION
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
' // Send message to close the application
IF HI(WORD, wParam) = %BN_CLICKED THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_SIZE
' // Resize the close button
IF wParam <> %SIZE_MINIMIZED THEN
LOCAL hButton AS DWORD
LOCAL rc AS RECT
GetClientRect hwnd, rc
hButton = GetDlgItem(hwnd, %IDCANCEL)
pWindow.MoveWindow hButton, pWindow.ClientWidth - 95, pWindow.ClientHeight - 35, 75, 23, %TRUE
END IF
CASE %WM_DESTROY
' // Close the application
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
The following example creates three autoplaying animation controls. The first and the third ones are transparent, and the second not. The background color of the third control is changed during the processing of the WM_CTLCOLORSTATIC message.
' ########################################################################################
' Animate Control example
' Copyright (c) 2011 José Roca
' Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#COMPILE EXE
#DIM ALL
'/* header files for imported files */
%UNICODE = 1
#INCLUDE ONCE "CWindow.inc"
#INCLUDE ONCE "AnimateCtrl.inc"
'/* resource file */
#RESOURCE RES, "EX_CW_ANIMATE_02.res"
'/* control identifiers */
%IDC_ANIMATION1 = 101
%IDC_ANIMATION2 = 102
%IDC_ANIMATION3 = 103
' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Create an instance of the class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
pWindow.CreateWindow(%NULL, "AVI Example", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
' // Set the client size
pWindow.SetClientSize 550, 320
' // Center the window
pWindow.CenterWindow
' // Create a transparent AVI control
LOCAL hAnim1 AS DWORD
hAnim1 = pWindow.AddAnimation(pWindow.hwnd, %IDC_ANIMATION1, "", 50, 90, 130, 130, _
%WS_CHILD OR %WS_VISIBLE OR %ACS_CENTER OR %ACS_TRANSPARENT OR %ACS_AUTOPLAY)
' // Open the AVI clip
Animate_Open(hAnim1, "DRILLRLE.AVI")
' // Create a 2nd AVI control (not transparet)
LOCAL hAnim2 AS DWORD
hAnim2 = pWindow.AddAnimation(pWindow.hwnd, %IDC_ANIMATION2, "", 200, 90, 130, 130, _
%WS_CHILD OR %WS_VISIBLE OR %ACS_CENTER OR %ACS_AUTOPLAY)
' // Open the AVI clip
Animate_Open(hAnim2, "DRILLRLE.AVI")
' // Create a 3rd transparent AVI control
LOCAL hAnim3 AS DWORD
hAnim3 = pWindow.AddAnimation(pWindow.hwnd, %IDC_ANIMATION3, "", 350, 90, 130, 130, _
%WS_CHILD OR %WS_VISIBLE OR %ACS_CENTER OR %ACS_TRANSPARENT OR %ACS_AUTOPLAY)
' // Open the AVI clip
Animate_Open(hAnim3, "DRILLRLE.AVI")
' // Add a close button
pWindow.AddButton(pWindow.hwnd, %IDCANCEL, "&Close", 0, 0, 0, 0, -1, -1)
' // Force the resizing of the controls
pWindow.Resize
' // Default message pump (you can replace it with your own)
pWindow.DoEvents(nCmdShow)
' // Close the animation file
Animate_Close hAnim1
Animate_Close hAnim2
Animate_Close hAnim3
END FUNCTION
' ########################################################################################
' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
STATIC pWindow AS IWindow ' // Reference to the IWindow interface
SELECT CASE uMsg
CASE %WM_CREATE
' // Get a reference to the IWindow interface from the CREATESTRUCT structure
pWindow = CWindow_GetObjectFromCreateStruct(lParam)
EXIT FUNCTION
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
' // Send message to close the application
IF HI(WORD, wParam) = %BN_CLICKED THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_SIZE
' // Resize the close button
IF wParam <> %SIZE_MINIMIZED THEN
LOCAL hButton AS DWORD
LOCAL rc AS RECT
GetClientRect hwnd, rc
hButton = GetDlgItem(hwnd, %IDCANCEL)
pWindow.MoveWindow hButton, pWindow.ClientWidth - 95, pWindow.ClientHeight - 35, 75, 23, %TRUE
END IF
' // Change the background color of the third animation control
CASE %WM_CTLCOLORSTATIC
IF lParam = GetDlgItem(hwnd, %IDC_ANIMATION3) THEN
SetBkColor wParam, GetSysColor(%COLOR_INFOBK)
EXIT FUNCTION
END IF
CASE %WM_DESTROY
' // Close the application
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
The following example creates three animation controls. The first and the third ones are transparent, and the second not. The background color of the third control is changed during the processing of the WM_CTLCOLORSTATIC message. Playing is performed when the Play button is clicked, and stopped when the Stop button is clicked. It also includes code showing how to process the ACN_START and ACN_STOP messages.
' ########################################################################################
' Animate Control example
' Copyright (c) 2011 José Roca
' Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#COMPILE EXE
#DIM ALL
'/* header files for imported files */
%UNICODE = 1
#INCLUDE ONCE "CWindow.inc"
#INCLUDE ONCE "AnimateCtrl.inc"
'/* resource file */
#RESOURCE RES, "EX_CW_ANIMATE_03.res"
'/* control identifiers */
%IDC_ANIMATION1 = 101
%IDC_ANIMATION2 = 102
%IDC_ANIMATION3 = 103
%IDC_PLAY = 104
%IDC_STOP = 105
' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Create an instance of the class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
pWindow.CreateWindow(%NULL, "AVI Example", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
' // Set the client size
pWindow.SetClientSize 550, 320
' // Center the window
pWindow.CenterWindow
' // Create a transparent AVI control
LOCAL hAnim1 AS DWORD
hAnim1 = pWindow.AddAnimation(pWindow.hwnd, %IDC_ANIMATION1, "", 50, 90, 130, 130, _
%WS_CHILD OR %WS_VISIBLE OR %ACS_CENTER OR %ACS_TRANSPARENT)
' // Open the AVI clip
Animate_Open(hAnim1, "DRILLRLE.AVI")
' // Create a 2nd AVI control (not transparet)
LOCAL hAnim2 AS DWORD
hAnim2 = pWindow.AddAnimation(pWindow.hwnd, %IDC_ANIMATION2, "", 200, 90, 130, 130, _
%WS_CHILD OR %WS_VISIBLE OR %ACS_CENTER)
' // Open the AVI clip
Animate_Open(hAnim2, "DRILLRLE.AVI")
' // Create a 3rd transparent AVI control
LOCAL hAnim3 AS DWORD
hAnim3 = pWindow.AddAnimation(pWindow.hwnd, %IDC_ANIMATION3, "", 350, 90, 130, 130, _
%WS_CHILD OR %WS_VISIBLE OR %ACS_CENTER OR %ACS_TRANSPARENT)
' // Open the AVI clip
Animate_Open(hAnim3, "DRILLRLE.AVI")
' // Add the buttons
pWindow.AddButton(pWindow.hwnd, %IDC_PLAY, "&Play", 0, 0, 0, 0, -1, -1)
pWindow.AddButton(pWindow.hwnd, %IDC_STOP, "&Stop", 0, 0, 0, 0, -1, -1)
pWindow.AddButton(pWindow.hwnd, %IDCANCEL, "&Close", 0, 0, 0, 0, -1, -1)
' // Force the resizing of the controls
pWindow.Resize
' // Default message pump (you can replace it with your own)
pWindow.DoEvents(nCmdShow)
' // Close the animation file
Animate_Close hAnim1
Animate_Close hAnim2
Animate_Close hAnim3
END FUNCTION
' ########################################################################################
' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
STATIC pWindow AS IWindow ' // Reference to the IWindow interface
SELECT CASE uMsg
CASE %WM_CREATE
' // Get a reference to the IWindow interface from the CREATESTRUCT structure
pWindow = CWindow_GetObjectFromCreateStruct(lParam)
EXIT FUNCTION
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
' // Send message to close the application
IF HI(WORD, wParam) = %BN_CLICKED THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %IDC_PLAY
IF HI(WORD, wParam) = %BN_CLICKED THEN
' // Play the AVI clips
' // You can use the Animate_Play function or macro...
Animate_Play(GetDlgItem(hwnd, %IDC_ANIMATION1), 0, -1, -1)
Animate_Play(GetDlgItem(hwnd, %IDC_ANIMATION2), 0, -1, -1)
Animate_Play(GetDlgItem(hwnd, %IDC_ANIMATION3), 0, -1, -1)
' // ... or send the ACM_PLAY message explicitly.
' SendMessage GetDlgItem(hwnd, %IDC_ANIMATION1), %ACM_PLAY, -1, MAK(LONG, 0, -1)
' SendMessage GetDlgItem(hwnd, %IDC_ANIMATION2), %ACM_PLAY, -1, MAK(LONG, 0, -1)
' SendMessage GetDlgItem(hwnd, %IDC_ANIMATION3), %ACM_PLAY, -1, MAK(LONG, 0, -1)
EXIT FUNCTION
END IF
CASE %IDC_STOP
IF HI(WORD, wParam) = %BN_CLICKED THEN
' // Stop playing the AVI clips
' // You can use the Animate_Stop function or macro...
Animate_Stop(GetDlgItem(hwnd, %IDC_ANIMATION1))
Animate_Stop(GetDlgItem(hwnd, %IDC_ANIMATION2))
Animate_Stop(GetDlgItem(hwnd, %IDC_ANIMATION3))
' // ... or send the ACM_STOP message explicitly.
' SendMessage GetDlgItem(hwnd, %IDC_ANIMATION1), %ACM_STOP, 0, 0
' SendMessage GetDlgItem(hwnd, %IDC_ANIMATION2), %ACM_STOP, 0, 0
' SendMessage GetDlgItem(hwnd, %IDC_ANIMATION3), %ACM_STOP, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_SIZE
' // Resize the buttons
IF wParam <> %SIZE_MINIMIZED THEN
pWindow.MoveWindow GetDlgItem(hwnd, %IDC_PLAY), pWindow.ClientWidth - 275, pWindow.ClientHeight - 35, 75, 23, %TRUE
pWindow.MoveWindow GetDlgItem(hwnd, %IDC_STOP), pWindow.ClientWidth - 185, pWindow.ClientHeight - 35, 75, 23, %TRUE
pWindow.MoveWindow GetDlgItem(hwnd, %IDCANCEL), pWindow.ClientWidth - 95, pWindow.ClientHeight - 35, 75, 23, %TRUE
END IF
' // Change the background color of the third animation control
CASE %WM_CTLCOLORSTATIC
IF lParam = GetDlgItem(hwnd, %IDC_ANIMATION3) THEN
SetBkColor wParam, GetSysColor(%COLOR_INFOBK)
EXIT FUNCTION
END IF
CASE %WM_DESTROY
' // Close the application
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
The Animation Controls API doesn't provide a way to retrieve the width and height of an AVI file, but this information can be retrieved using some functions of the Video for Windows API:
' ########################################################################################
' Retrieves the width and height of an AVI file.
' ########################################################################################
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "Vfw.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN () AS LONG
LOCAL hAvi AS DWORD
LOCAL afi AS AVIFILEINFO_STRUCT
IF AVIFileOpen(hAvi, "DRILLRLE.AVI", %OF_SHARE_DENY_WRITE, BYVAL %NULL) = %ERROR_SUCCESS THEN
IF AVIFileInfo(hAvi, afi, SIZEOF(afi)) = %ERROR_SUCCESS THEN
MSGBOX "Width = " & STR$(afi.dwWidth) & $CRLF & "Height = " & STR$(afi.dwHeight)
END IF
AVIFileRelease hAvi
END IF
END FUNCTION
' ========================================================================================