It was easy for me to translate the interfaces because i was writing a tool to import the typelib so it has been done automatically.
The files:
WMPlayer.OCX.pbi : The interface definitions, big file 104Kb.
wmp.pb : Small include of helper functions.
wmpTest.pb : A small working player.
captions.pb : Closed captions example using webgadget
ccsample.smi : Closed captions sample
I did not write any interface method wrapper, you will need to refer to the documentation:
https://docs.microsoft.com/en-us/window ... ence-for-c
Look at wmpTest.pb for an easy example.
If i have time i will post how to handle events.
WMPlayer.OCX.pbi (104kb):
https://github.com/omegakode/WMPlayer
Click on Clone or Download to get the file.
UPDATE:
04/23 Added closed captions example
wmp.pb helper:
Code: Select all
IncludeFile "WMPlayer.OCX.pbi"
;Windows Media Player Functions
;Justin 06/2020
;https://docs.microsoft.com/en-us/windows/win32/wmp/windows-media-player-sdk
EnableExplicit
;- WINDOWS
;- VECTOR_VARIANT
Structure VECTOR_VARIANT
var.VARIANT[0]
EndStructure
;- DISPPARAMS_
Structure DISPPARAMS_ Align #PB_Structure_AlignC
*rgvarg.VECTOR_VARIANT
rgdispidNamedArgs.i
cArgs.l
cNamedArgs.l
EndStructure
;- IUnknownVtbl
Structure IUnknownVtbl
QueryInterface.i
AddRef.i
Release.i
EndStructure
;- IDispatchVtbl
Structure IDispatchVtbl Extends IUnknownVtbl
GetIDsOfNames.i
GetTypeInfo.i
GetTypeInfoCount.i
Invoke.i
EndStructure
;- IID_IDispatch
DataSection
IID_IDispatch:
Data.l $00020400
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection
;- IID_IConnectionPointContainer
DataSection
IID_IConnectionPointContainer:
Data.l $B196B284
Data.w $BAB4, $101A
Data.b $B6, $9C, $00, $AA, $00, $34, $1D, $07
EndDataSection
;-wmp_EventCallback
;wmp: pointer to WMP_OBJECT.
;dispid : #_WMPOCXEvents_dispid enum
;*params : event params in reversed order
Prototype wmp_EventCallback(wmp.i, dispid.l, *params.DISPPARAMS_)
;- WMP_EVENTS_OBJECT
Structure WMP_EVENTS_OBJ
vt.i
refCount.l
*wmp.WMP_OBJECT
evCallBack.wmp_EventCallback
EndStructure
Structure WMP_EVENTS_VT_TAG Extends IDispatchVtbl
EndStructure
Global.WMP_EVENTS_VT_TAG WMP_EVENTS_VT
;- WMP_OBJECT
Structure WMP_OBJECT
container.i
wmpPlayer.IWMPPlayer2
wmpCore.IWMPCore
wmpControls.IWMPControls
oldContWndProc.i
*events.WMP_EVENTS_OBJ
EndStructure
Procedure wmp_EvtNew(*wmp.WMP_OBJECT, evCallback.wmp_EventCallback)
Protected.WMP_EVENTS_OBJ *this
*this = AllocateMemory(SizeOf(WMP_EVENTS_OBJ))
*this\vt = WMP_EVENTS_VT
*this\wmp = *wmp
*this\evCallBack = evCallback
*this\refCount = 1
ProcedureReturn *this
EndProcedure
Procedure wmp_EvtFree(*this.WMP_EVENTS_OBJ)
FreeMemory(*this)
EndProcedure
Procedure wmp_EvtQueryInterface(*this.WMP_EVENTS_OBJ, *iid.IID, *obj.INTEGER)
If CompareMemory(*iid, ?IID__WMPOCXEvents, SizeOf(IID)) Or CompareMemory(*iid, ?IID_IDispatch, SizeOf(IID))
*obj\i = *this
*this\refCount = *this\refCount + 1
ProcedureReturn #S_OK
Else
*obj\i = #Null
ProcedureReturn #E_NOINTERFACE
EndIf
EndProcedure
Procedure wmp_EvtAddRef(*this.WMP_EVENTS_OBJ)
*this\refCount = *this\refCount + 1
ProcedureReturn *this\refCount
EndProcedure
Procedure wmp_EvtRelease(*this.WMP_EVENTS_OBJ)
*this\refCount = *this\refCount - 1
If *this\refCount = 0
wmp_EvtFree(*this)
EndIf
EndProcedure
Procedure wmp_EvtGetIDsOfNames(*this.WMP_EVENTS_OBJ, *iid.IID, rgszNames.i, cNames.l, lcid.l, rgDispId.i)
ProcedureReturn #E_NOTIMPL
EndProcedure
Procedure wmp_EvtGetTypeInfo(*this.WMP_EVENTS_OBJ, iTInfo.i, lcid.l, ppTInfo.i)
ProcedureReturn #E_NOTIMPL
EndProcedure
Procedure wmp_EvtGetTypeInfoCount(*this.WMP_EVENTS_OBJ, pctinfo.i)
ProcedureReturn #E_NOTIMPL
EndProcedure
Procedure wmp_EvtInvoke(*this.WMP_EVENTS_OBJ, dispIdMember.l, *iid.IID, lcid.l, wFlags.w, pDispParams.i, *pVarResult.VARIANT, pExcepInfo.i, puArgErr.i)
If *this\evCallBack
*this\evCallBack(*this\wmp\container, dispIdMember, pDispParams)
EndIf
EndProcedure
;- WMP_EVENTS_VT
WMP_EVENTS_VT\QueryInterface = @wmp_EvtQueryInterface()
WMP_EVENTS_VT\AddRef = @wmp_EvtAddRef()
WMP_EVENTS_VT\Release = @wmp_EvtRelease()
WMP_EVENTS_VT\GetIDsOfNames = @wmp_EvtGetIDsOfNames()
WMP_EVENTS_VT\GetTypeInfo = @wmp_EvtGetTypeInfo()
WMP_EVENTS_VT\GetTypeInfoCount = @wmp_EvtGetTypeInfoCount()
WMP_EVENTS_VT\Invoke = @wmp_EvtInvoke()
Macro wmp_GetObject(wmpId)
GetWindowLongPtr_(GadgetID(wmpId), #GWLP_USERDATA)
EndMacro
Procedure wmp_ContOnDestroy(hwnd.i, msg.l, wparam.i, lparam.i)
Protected.WMP_OBJECT *wmp = GetWindowLongPtr_(hwnd, #GWLP_USERDATA)
If *wmp
If *wmp\wmpControls : *wmp\wmpControls\Release() : EndIf
If *wmp\wmpPlayer : *wmp\wmpPlayer\Release() : EndIf
If *wmp\wmpCore : *wmp\wmpCore\Release() : EndIf
If *wmp\events : wmp_EvtRelease(*wmp\events) : EndIf
SetWindowLongPtr_(hwnd, #GWLP_WNDPROC, *wmp\oldContWndProc)
FreeMemory(*wmp)
EndIf
EndProcedure
Procedure wmp_ContOnDefault(hwnd.i, msg.l, wparam.i, lparam.i)
Protected.WMP_OBJECT *wmp = GetWindowLongPtr_(hwnd, #GWLP_USERDATA)
If *wmp
ProcedureReturn CallWindowProc_(*wmp\oldContWndProc, hwnd, msg, wparam, lparam)
Else
ProcedureReturn DefWindowProc_(hwnd, msg, wparam, lparam)
EndIf
EndProcedure
Procedure wmp_ContWndProc(hwnd.i, msg.l, wparam.i, lparam.i)
Select msg
Case #WM_DESTROY : ProcedureReturn wmp_ContOnDestroy(hwnd, msg, wparam, lparam)
Default : ProcedureReturn wmp_ContOnDefault(hwnd.i, msg.l, wparam.i, lparam.i)
EndSelect
EndProcedure
Procedure wmp_Create(id.i, x.i, y.i, width.i, height.i, evCallback.wmp_EventCallback = #Null)
Protected.WMP_OBJECT *wmp
Protected.IUnknown unkCont
Protected.IConnectionPointContainer cpc
Protected.IConnectionPoint cp
Protected.l cookie
*wmp = AllocateMemory(SizeOf(WMP_OBJECT))
*wmp\container = ContainerGadget(id, x, y, width, height)
If *wmp\container
If AtlAxCreateControl_("WMPlayer.OCX", GadgetID(*wmp\container), #Null, #Null) = #S_OK
If AtlAxGetControl_(GadgetID(*wmp\container), @unkCont) = #S_OK
If unkCont
unkCont\QueryInterface(?IID_IWMPPlayer2, @*wmp\wmpPlayer)
unkCont\QueryInterface(?IID_IWMPCore, @*wmp\wmpCore)
unkCont\QueryInterface(?IID_IWMPControls, @*wmp\wmpControls)
unkCont\Release()
EndIf
EndIf
EndIf
If *wmp\wmpCore And *wmp\wmpPlayer And *wmp\wmpControls
SetWindowLongPtr_(GadgetID(*wmp\container), #GWLP_USERDATA, *wmp)
*wmp\oldContWndProc = SetWindowLongPtr_(GadgetID(*wmp\container), #GWLP_WNDPROC, @wmp_ContWndProc())
*wmp\wmpPlayer\put_enableContextMenu(#VARIANT_FALSE)
*wmp\wmpPlayer\put_enableContextMenu(#VARIANT_FALSE)
*wmp\wmpPlayer\put_stretchToFit(#VARIANT_TRUE)
;Events
If evCallback
If *wmp\wmpPlayer\QueryInterface(?IID_IConnectionPointContainer, @cpc) = #S_OK
If cpc\FindConnectionPoint(?IID__WMPOCXEvents, @cp) = #S_OK
*wmp\events = wmp_EvtNew(*wmp, evCallback)
cp\Advise(*wmp\events, @cookie)
cp\Release()
EndIf
cpc\Release()
EndIf
EndIf
ProcedureReturn *wmp\container
Else
FreeMemory(*wmp)
ProcedureReturn 0
EndIf
EndIf
EndProcedure
Procedure wmp_GetPlayer(wmpid.i)
Protected.WMP_OBJECT *wmp = wmp_GetObject(wmpid)
ProcedureReturn *wmp\wmpPlayer
EndProcedure
Procedure wmp_GetCore(wmpid.i)
Protected.WMP_OBJECT *wmp = wmp_GetObject(wmpid)
ProcedureReturn *wmp\wmpCore
EndProcedure
Procedure wmp_GetControls(wmpid.i)
Protected.WMP_OBJECT *wmp = wmp_GetObject(wmpid)
ProcedureReturn *wmp\wmpControls
EndProcedure
Procedure wmp_GetUnknown(wmpid.i)
Protected.IUnknown unk
If AtlAxGetControl_(GadgetID(wmpid), @unk) = #S_OK
ProcedureReturn unk
EndIf
EndProcedure
Procedure wmp_GetInterface(wmpid.i, *iid.IID)
Protected.IUnknown unk
Protected.i ifce
If AtlAxGetControl_(GadgetID(wmpid), @unk) = #S_OK
unk\QueryInterface(*iid, @ifce)
unk\Release()
EndIf
ProcedureReturn ifce
EndProcedure
Code: Select all
;Windows Media Player Example
;Justin 06/2020
XIncludeFile "wmp.pb"
EnableExplicit
Define.i ev
Global.i g_wmp, g_lastUIMode
;- Enum MENU_ID
Enumeration
#MENU_ID_OPEN
#MENU_ID_UI_NONE
#MENU_ID_UI_MINI
#MENU_ID_UI_FULL
#MENU_ID_PLAY_PAUSE
#MENU_ID_STOP
#MENU_ID_GET_CURRENT_TIME
#MENU_ID_FORWARD
#MENU_ID_INCREASE_SPEED
#MENU_ID_DECREASE_SPEED
#MENU_ID_RESET_SPEED
EndEnumeration
Procedure fileOpen()
Protected.s file
Protected.IWMPCore core = wmp_GetCore(g_wmp)
Protected.WMP_OBJECT *wmp = wmp_GetObject(g_wmp)
file = OpenFileRequester("Open", "", "", 0)
If file
core\put_URL(file)
;----------------- PB BUG ------------------------
;Calling a method with a bstr from inside a structure produces an IMA.
;*wmp\wmpCore\put_URL(file) ; IMA
;-------------------------------------------------
EndIf
EndProcedure
Procedure onResize()
ResizeGadget(g_wmp, 0, 0, WindowWidth(0), WindowHeight(0) - MenuHeight())
EndProcedure
Procedure setUIMode(menId.l)
Protected.IWMPPlayer2 player = wmp_GetPlayer(g_wmp)
SetMenuItemState(0, g_lastUIMode, #False)
Select menid
Case #MENU_ID_UI_FULL
player\put_uiMode("full")
Case #MENU_ID_UI_MINI
player\put_uiMode("mini")
Case #MENU_ID_UI_NONE
player\put_uiMode("none")
EndSelect
SetMenuItemState(0, menId, #True)
g_lastUIMode = menId
EndProcedure
Procedure playPause()
Protected.IWMPCore core = wmp_GetCore(g_wmp)
Protected.IWMPControls controls = wmp_GetControls(g_wmp)
Protected.l state
core\get_playState(@state)
If state = #wmppsPaused
controls\play()
ElseIf state = #wmppsPlaying
controls\pause()
EndIf
EndProcedure
Procedure stop()
Protected.IWMPControls controls = wmp_GetControls(g_wmp)
controls\stop()
EndProcedure
Procedure getCurrentTime()
Protected.IWMPControls controls
Protected.d dPosition
Protected.i bPosition
controls = wmp_GetControls(g_wmp)
If controls
If controls\get_currentPosition(@dPosition) = #S_OK
Debug dPosition
EndIf
If controls\get_currentPositionString(@bPosition) = #S_OK
Debug PeekS(bPosition)
SysFreeString_(bPosition)
EndIf
Debug controls\put_currentPosition(dPosition + 10)
EndIf
EndProcedure
;Advances 10 seconds
Procedure forward()
Protected.IWMPControls controls
Protected.d currPos, inCrement
inCrement = 10
controls = wmp_GetControls(g_wmp)
If controls
controls\get_currentPosition(@currPos)
controls\put_currentPosition(currPos + inCrement)
EndIf
EndProcedure
Procedure increaseSpeed()
Protected.IWMPSettings sett
Protected.d rate, incStep
incStep = 0.1
If g_wmp
sett = wmp_GetInterface(g_wmp, ?IID_IWMPSettings)
If sett
sett\get_rate(@rate)
sett\put_rate(rate + incStep)
sett\Release()
EndIf
EndIf
EndProcedure
Procedure decreaseSpeed()
Protected.IWMPSettings sett
Protected.d rate, incStep
incStep = 0.1
If g_wmp
sett = wmp_GetInterface(g_wmp, ?IID_IWMPSettings)
If sett
sett\get_rate(@rate)
sett\put_rate(rate - incStep)
sett\Release()
EndIf
EndIf
EndProcedure
Procedure resetSpeed()
Protected.IWMPSettings sett
If g_wmp
sett = wmp_GetInterface(g_wmp, ?IID_IWMPSettings)
If sett
sett\put_rate(1.0)
sett\Release()
EndIf
EndIf
EndProcedure
;*params are in reversed order.
Procedure eventCallback(wmp.i, dispid.l, *params.DISPPARAMS_)
Select dispid
Case #_WMPOCXEvents_dispid_PlayStateChange
Debug "PlayStateChange " + Str(*params\rgvarg\var[0]\lVal)
Case #_WMPOCXEvents_dispid_PositionChange
Debug "PositionChange " + "old: " + StrD(*params\rgvarg\var[1]\dblVal) + " new: " + StrD(*params\rgvarg\var[0]\dblVal)
Case #_WMPOCXEvents_dispid_Click
Select *params\rgvarg\var[3]\iVal
Case 1
Debug "Left Click"
Case 2
Debug "Right Click"
Case 4
Debug "Middle Click"
EndSelect
EndSelect
EndProcedure
OpenWindow(0, 100, 150, 600, 400, "WMP", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
CreateMenu(0, WindowID(0))
MenuTitle("File")
MenuItem(#MENU_ID_OPEN, "Open...")
MenuTitle("Playback")
MenuItem(#MENU_ID_PLAY_PAUSE, "Play / Pause")
MenuItem(#MENU_ID_STOP, "Stop")
MenuItem(#MENU_ID_GET_CURRENT_TIME, "Get current time")
MenuItem(#MENU_ID_FORWARD, "Forward")
MenuTitle("View")
OpenSubMenu("UI Mode")
MenuItem(#MENU_ID_UI_NONE, "None")
MenuItem(#MENU_ID_UI_MINI, "Mini")
MenuItem(#MENU_ID_UI_FULL, "Full")
CloseSubMenu()
MenuTitle("Speed")
MenuItem(#MENU_ID_INCREASE_SPEED, "Increase")
MenuItem(#MENU_ID_DECREASE_SPEED, "Decrease")
MenuItem(#MENU_ID_RESET_SPEED, "Reset")
CloseSubMenu()
AddKeyboardShortcut(0, #PB_Shortcut_Up, #MENU_ID_INCREASE_SPEED)
AddKeyboardShortcut(0, #PB_Shortcut_Down, #MENU_ID_DECREASE_SPEED)
BindEvent(#PB_Event_SizeWindow, @onResize())
g_wmp = wmp_Create(#PB_Any, 0, 0, WindowWidth(0), WindowHeight(0) - MenuHeight(), @eventCallback())
If g_wmp = 0
MessageRequester("Fatal error", "WMP could not be created, is WMP installed?")
End
EndIf
setUIMode(#MENU_ID_UI_NONE)
Repeat
ev = WaitWindowEvent()
Select ev
Case #PB_Event_Menu
Select EventMenu()
Case #MENU_ID_OPEN : fileOpen()
Case #MENU_ID_UI_NONE, #MENU_ID_UI_MINI, #MENU_ID_UI_FULL : setUIMode(EventMenu())
Case #MENU_ID_PLAY_PAUSE : playPause()
Case #MENU_ID_STOP : stop()
Case #MENU_ID_GET_CURRENT_TIME : getCurrentTime()
Case #MENU_ID_FORWARD : forward()
Case #MENU_ID_INCREASE_SPEED : increaseSpeed()
Case #MENU_ID_DECREASE_SPEED : decreaseSpeed()
Case #MENU_ID_RESET_SPEED : resetSpeed()
EndSelect
EndSelect
Until ev = #PB_Event_CloseWindow
;First load a caption file then load a movie
Code: Select all
;captions.pb
;Closed captions example.
;First load a closed captions file .smi, .sami, then load a movie.
;Justin 04/23
EnableExplicit
XIncludeFile "WMPlayer.OCX.pbi"
;- _APP
Structure _APP
win.i
webView.i ;WebGadget
wb2.IWebBrowser2
menu.i
EndStructure
Global._APP app
;- DATA
DataSection
;"{3050f485-98b5-11cf-bb82-00aa00bdce0b}"
IID_IHTMLDocument3:
Data.l $3050f485
Data.w $98b5, $11cf
Data.b $bb, $82, $00, $aa, $00, $bd, $ce, $0b
EndDataSection
#PLAYER_ID = "player"
#CAPTIONS_ID = "captions"
;- HTML
#HTML = "<html><head>" +
"<style>" +
"body {" +
"padding: 0 0 0 0;" +
"margin: 0 0 0 0;" +
"}" +
"" +
"#" + #PLAYER_ID + "{" +
"width: 100%;" +
"height: 100%;" +
"margin: 0 0 0 0;" +
"}" +
"" +
"#" + #CAPTIONS_ID + "{" +
"position: fixed;" +
"left: 50%;" +
"transform: translateX(-50%);" +
"bottom: 0px;" +
"}" +
"</style></head>" +
"<body>" +
~"<OBJECT ID=\"" + #PLAYER_ID + ~"\" CLASSID=\"clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6\">" +
~"<param name=\"UIMode\" value=\"none\">" +
~"<param name=\"autoStart\" value=\"true\">" +
~"<param name=\"stretchToFit\" value=\"true\">" +
~"<param name=\"windowlessVideo\" value=\"true\">" +
"</OBJECT>" +
~"<div id=\"" + #CAPTIONS_ID + ~"\"></div>" +
"</body>" + "</html>"
;- Enum CMD
Enumeration
#CMD_OPEN
#CMD_SET_CAPTION
EndEnumeration
Procedure win_on_size()
ResizeGadget(app\webView, 0, 0, WindowWidth(app\win), WindowHeight(app\win) - MenuHeight())
EndProcedure
;Gets IWebBrowser2 from WebGadget
Procedure webView_getWebBrowser(webView.i)
ProcedureReturn GetWindowLongPtr_(GadgetID(app\webView), #GWLP_USERDATA)
EndProcedure
;Gets IHTMLDocument3 from IWebBrowser2
Procedure webBrowser_getDocument3(wb.IWebBrowser2)
Protected.IDispatch docDisp
Protected.IHTMLDocument3 doc3
Protected.l hr
If wb = 0 : ProcedureReturn 0 : EndIf
;Get document IDispatch
hr = wb\get_Document(@docDisp)
If hr <> #S_OK : ProcedureReturn 0 : EndIf
;Get IHTMLDocument3
hr = docDisp\QueryInterface(?IID_IHTMLDocument3, @doc3)
If hr <> #S_OK : ProcedureReturn 0 : EndIf
docDisp\Release()
ProcedureReturn doc3
EndProcedure
;Gets IWMPPlayer from IWebBrowser2
Procedure webBrowser_getPlayer(wb.IWebBrowser2)
Protected.IHTMLDocument3 doc3
Protected.IHTMLElement el
Protected.IWMPPlayer player
Protected.l hr
If wb = 0 : ProcedureReturn 0 : EndIf
doc3 = webBrowser_getDocument3(wb)
If doc3 = 0 : ProcedureReturn 0 : EndIf
hr = doc3\getElementById(#PLAYER_ID, @el)
If hr <> #S_OK : Goto cleanup : EndIf
hr = el\QueryInterface(?IID_IWMPPlayer, @player)
If hr <> #S_OK : Goto cleanup : EndIf
cleanup:
If doc3 : doc3\Release() : EndIf
If el : el\Release() : EndIf
ProcedureReturn player
EndProcedure
Procedure cmd_open()
Protected.s file
Protected.IWMPPlayer player
player = webBrowser_getPlayer(app\wb2)
If player = 0
Debug "Error failed to get player"
ProcedureReturn 0
EndIf
file = OpenFileRequester("Choose video", "", "", 0)
If file
player\put_URL(file)
EndIf
cleanup:
If player : player\Release() : EndIf
EndProcedure
Procedure cmd_setCaption()
Protected.s captionFile
Protected.IWMPPlayer player
Protected.IWMPClosedCaption cc
Protected.l hr
player = webBrowser_getPlayer(app\wb2)
If player = 0
Debug "Error failed to get player"
ProcedureReturn 0
EndIf
hr = player\get_closedCaption(@cc)
If hr <> #S_OK : Goto cleanup : EndIf
captionFile = OpenFileRequester("Choose caption", "", "Captions file | *smi;*.sami | All files | *.*", 0)
If captionFile
cc\put_captioningId(#CAPTIONS_ID)
cc\put_SAMIFileName(captionFile)
EndIf
cleanup:
If player : player\Release() : EndIf
If cc : cc\Release() : EndIf
EndProcedure
Procedure main()
Protected.l ev, ww, wh
Protected.b quit
ww = 600
wh = 400
app\win = OpenWindow(#PB_Any, 10, 10, ww, wh, "WMP Captions", #PB_Window_Invisible | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
SmartWindowRefresh(app\win, #True)
app\menu = CreateMenu(#PB_Any, WindowID(app\win))
MenuTitle("File")
MenuItem(#CMD_OPEN, "Open")
MenuTitle("Captions")
MenuItem(#CMD_SET_CAPTION, "Set caption")
app\webView = WebGadget(#PB_Any, 0, 0, ww, wh, "")
app\wb2 = webView_getWebBrowser(app\webView)
If app\wb2 = 0
Debug "Error failed to get webbrowser"
End
EndIf
SetGadgetItemText(app\webView, #PB_Web_HtmlCode, #HTML)
BindEvent(#PB_Event_SizeWindow, @win_on_size(), app\win)
HideWindow(app\win, #False)
quit = #False
Repeat
ev = WaitWindowEvent()
Select ev
Case #PB_Event_Menu
Select EventMenu()
Case #CMD_OPEN : cmd_open()
Case #CMD_SET_CAPTION : cmd_setCaption()
EndSelect
Case #PB_Event_CloseWindow
quit = #True
EndSelect
Until quit
EndProcedure
main()
Code: Select all
<SAMI>
<HEAD>
<Title>Close Captioning Sample</Title>
<STYLE TYPE="text/css">
<!--
P {margin-top:3pt; margin-left:5pt; font-size: 4vh;
font-family: tahoma, sans-serif; font-weight: normal;
color: white;}
.ENUSCC {Name:'English Captions'; lang: en-US; SAMIType:CC;}
-->
</Style>
</HEAD>
<BODY>
<SYNC Start=1000>
<P Class=ENUSCC>Great reason to visit Seattle, brought to you by two out-of-staters.
<SYNC Start=4000>
<P Class=ENUSCC>So you know, there's lots of great reasons to come visit Seattle.
<SYNC Start=7000>
<P Class=ENUSCC>That's right, I came here because of the coffee.
<SYNC Start=9000>
<P Class=ENUSCC>Yah, everyone knows the coffee.
<SYNC Start=12000>
<P Class=ENUSCC>And I heard about the drivers.
<SYNC Start=14000>
<P Class=ENUSCC>Well, you know, but then it rains...and it's bad, it's bad.
<SYNC Start=19000>
<P Class=ENUSCC>But the traffic in general is...
<SYNC Start=21000>
<P Class=ENUSCC>Terrible.
<SYNC Start=23000>
<P Class=ENUSCC>OK, yah, yah. But, the weather!
<SYNC Start=26500>
<P Class=ENUSCC>It doesn't rain all the time...yes, it does.
<SYNC Start=30000>
<P Class=ENUSCC>Yah. Nevermind.
<SYNC Start=34000>
<P Class=ENUSCC>End of Stream.
</BODY>
</SAMI>