This demo is a just a basic proof of concept, a close-as-possible port of the Microsoft DirectComposition Effects SDK example. Since the demo is ported as close as possible, you'll find something additional of interest in this project: Instead of using a Form, it creates it's own window from scratch using API and handles the entire message pump (error handlers omitted):
Code:
Private Function CreateApplicationWindow() As Long
Dim hr As Long = S_OK
Dim wcex As WNDCLASSEX
wcex.cbSize = LenB(wcex)
wcex.style = CS_HREDRAW Or CS_VREDRAW
wcex.lpfnWndProc = AddressOf WindowProc
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = App.hInstance
wcex.hIcon = 0
wcex.hCursor = LoadCursor(0, IDC_ARROW)
wcex.hbrBackground = GetStockObject(WHITE_BRUSH)
wcex.lpszMenuName = 0
wcex.lpszClassName = StrPtr(wndClass)
wcex.hIconSm = 0
hr = IIf(RegisterClassEx(wcex), S_OK, E_FAIL)
If SUCCEEDED(hr) Then
PostLog "RegisterClassEx succeeded"
Dim RECT As RECT
RECT.Right = windowWidth: RECT.Bottom = windowHeight
AdjustWindowRect RECT, WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_MINIMIZEBOX, 0
m_hWnd = CreateWindowExW(0, StrPtr(wndClass), StrPtr(wndName), _
WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_MINIMIZEBOX, _
CW_USEDEFAULT, CW_USEDEFAULT, RECT.Right - RECT.Left, RECT.Bottom - RECT.Top, _
0, 0, App.hInstance, ByVal 0)
End If
Code:
Private Function EnterMessageLoop() As Long
Dim result As Long
If ShowApplicationWindow() Then
Dim tMSG As MSG
Dim hr As Long
PostLog "Entering message loop"
hr = GetMessage(tMSG, 0, 0, 0)
Do While hr <> 0
If hr = -1 Then
PostLog "Error: 0x" & Hex$(Err.LastDllError)
Else
TranslateMessage tMSG
DispatchMessage tMSG
End If
hr = GetMessage(tMSG, 0, 0, 0)
Loop
PostLog "Exited message loop"
result = CLng(tMSG.wParam)
End If
EnterMessageLoop = result
End Function
After that, we get into all the DirectComposition/Direct2D code, which is too complex to go into much detail here; but the basic steps are to start with the D3D11CreateDevice and D2D1CreateFactory APIs to create the root DirectX objects, get a DXGI interface from the former, then use the DCompositionCreateDevice to create the rendering object. After that, we create surfaces, make those into DirectComposition visuals, and apply various transform effects and animations.
I recommend following the code starting from BeforeEnteringMessageLoop to see all the object creation, then following from OnKeyDown and OnLeftButton to see how it responds to the two actions.
There's two versions of this project included in the zip:
VB6:
Module that runs from Sub Main
Requires oleexp.tlb v6.3 or newer (only for the IDE, not required once compiled to exe)
(Note: If you saw my thread about this, I mapped the differences in matrix layout so it could use the existing oleexp version.)
twinBASIC:
Runs from Form provisioned for multiple demos in it's own thread with log sync'd in critical section. Can also be configured to run from Sub Main without the form by changing the startup object.
Supports both 32bit and 64bit
Uses tbShellLib, which is included within the project file but will have to be added if you make a new project using this code or these interfaces.
You'll see the module code is nearly identical, except where I took advantage of some modern twinBASIC language additions like inline initialization of variables and Err.LastHResult, and that the VB6 version has it's APIs declared in the module since oleexp.tlb doesn't include them like tbShellLib does.
Required for both:
DirectX 11, which is preinstalled on Windows 7 and newer.