New scripting features in MM 2.5.2

Download and get help for different MediaMonkey for Windows 4 Addons.

Moderators: Peke, Gurus

jiri
Posts: 5433
Joined: Tue Aug 14, 2001 7:00 pm
Location: Czech Republic
Contact:

New scripting features in MM 2.5.2

Post by jiri »

Hello all script developers,

I'd like to announce some new scripting features that will appear in MM 2.5.2 so that you can prepare for them, comment, etc.

First of all, handling of COM events will be much simplified, you'll no longer have to use tricks with WScript, all will be possible in a single script file. You'll only use Script.RegisterEvent command with 3 parameters: Object, it's event name (string) and script procedure name that handles the event (string). In the following script you can see several examples of usage. You can for example see a timer there or feedback to start of playback or paused playback:

Code: Select all

Sub OnStartup 
  Script.RegisterEvent SDB, "OnShutdown", "SDBShutdown"
  Script.RegisterEvent SDB, "OnTrackProperties", "SDBTrackProperties"
  Script.RegisterEvent SDB, "OnPlay", "SDBPlay"
  Script.RegisterEvent SDB, "OnPause", "SDBPause"
  Set Tmr = SDB.CreateTimer( 10000)   ' Pop up a message in 10 seconds
'  Script.RegisterEvent Tmr, "OnTimer", "TestTimer"
End Sub

Sub SDBTrackProperties( tracks)
  SDB.MessageBox "Wow, track properties were modified for "&tracks.count&" track(s)!", mtInformation, Array(mbOk)
'  Script.UnregisterEvents SDB
End Sub

Sub SDBShutdown
  SDB.MessageBox "MediaMonkey is finishing... :(", mtInformation, Array(mbOk)
End Sub

Sub SDBPlay
  SDB.MessageBox "Started playback of "&SDB.Player.CurrentSong.ArtistName&_
    " - "&SDB.Player.CurrentSong.Title, mtInformation, Array(mbOk)
End Sub

Sub SDBPause
  If SDB.Player.isPaused Then
    SDB.MessageBox "Playback paused", mtInformation, Array(mbOk)
  End If
End Sub

Sub TestTimer( Timer)
  SDB.MessageBox "10 seconds elapsed!", mtInformation, Array(mbOk)
  Script.UnregisterEvents Timer  ' Terminate usage of this timer
End Sub
Another, more complex example shows how this event support can be used to create dialogs that better react to user actions. Not that the button there is enabled only if checkbox is checked, etc.:

Code: Select all

Sub OnStartup
  Set UI = SDB.UI

  ' Create the window to be shown
  Set Form = UI.NewForm
  Form.Common.SetRect 100, 100, 500, 400
  Form.FormPosition = 4   ' Screen Center
  Form.Caption = "Test"
  Script.RegisterEvent Form.Common, "OnResize", "FormResize"

  Set Lbl = UI.NewLabel( Form)
  Lbl.Common.ControlName = "Lbl"
  Lbl.Common.SetRect 10, 10, 100, 16

  Set ChB = UI.NewCheckBox( Form)
  ChB.Common.ControlName = "ChB"
  ChB.Common.SetRect 10, 50, 100, 20
  ChB.Caption = "Enabled"
  Script.RegisterEvent ChB.Common, "OnClick", "ChBClick"

  Set Btn = UI.NewButton( Form)
  Btn.Common.ControlName = "Btn"
  Btn.Common.SetRect 140, 48, 80, 25
  Btn.Caption = "Test"
  Script.RegisterEvent Btn, "OnClick", "BtnClick"

  ChBClick( Form)

  Form.ShowModal
  Script.UnregisterAllEvents
End Sub

Sub FormResize( Form)
  Set FC = Form.Common
  Set Lbl = FC.ChildControl("Lbl")
  Lbl.Caption = "("&FC.Left&","&FC.Top&")-("&FC.Width&","&FC.Height&")"
End Sub

Sub BtnClick
  SDB.MessageBox "Wow, button clicked!", mtInformation, Array(mbOk)
End Sub

Sub ChBClick( ChB)
  Set FC = ChB.Common.TopParent.Common
  Set Btn = FC.ChildControl("Btn")
  Set ChB = FC.ChildControl("ChB")
  Btn.Common.Enabled = ChB.Checked
End Sub
And the last example shows another new feature, dockable panels. You can create new panels on the main window, put any content in it, react to currently selected and played tracks, etc. The panel even persists its position after restart:

Code: Select all

Dim Mnu, Pnl, Lbl, Lbl2

Sub OnStartup
  Set UI = SDB.UI

  Set Pnl = UI.NewDockablePersistentPanel("TestingPanel")
  if Pnl.IsNew then
    Pnl.DockedTo = 2
    Pnl.Common.Width = 250
  end if
  Pnl.Caption = "My test"
  Script.RegisterEvent Pnl, "OnClose", "PnlClose"

  Set Lbl = UI.NewLabel(Pnl)
  Lbl.Autosize = false
  Lbl.Multiline = true
  Lbl.Common.SetRect 10, 10, Pnl.Common.Width-20, Pnl.Common.Height-20
  Lbl.Common.Anchors = 15  '1+2+4+8

  ' Add menu item that shows panel after it is closed
  Set Sep = SDB.UI.AddMenuItemSep(SDB.UI.Menu_View,0,0)
  Set Mnu = SDB.UI.AddMenuItem(SDB.UI.Menu_View,0,0)
  Mnu.Caption = "My testing panel"
  Mnu.Checked = Pnl.Common.Visible
  Script.RegisterEvent Mnu, "OnClick", "ShowPanel"

  Script.RegisterEvent SDB, "OnChangedSelection", "OnSelection"
End Sub

Sub ShowPanel(Item)
  Pnl.Common.Visible = not Pnl.Common.Visible
  Mnu.Checked = Pnl.Common.Visible
End Sub

Sub PnlClose( Item)
  Mnu.Checked = false
End Sub

Sub OnSelection
  Lbl.Caption = "Selected tracks: " & SDB.CurrentSongList.Count
End Sub
Hope you like it. I repeat, it's only a preview, don't try to run these scripts until MM 2.5.2 is released, it wouldn't work. When 2.5.2 is out, you can put these scripts to Scrips\Auto folder and check out all the features. Let me know if you find any problems or have any suggestions.

Jiri
Last edited by mockturtle on Sat Jan 28, 2006 5:54 am, edited 1 time in total.
confused

Post by confused »

will the old scripts still work?
jiri
Posts: 5433
Joined: Tue Aug 14, 2001 7:00 pm
Location: Czech Republic
Contact:

Post by jiri »

Sure.
Teknojnky
Posts: 5537
Joined: Tue Sep 06, 2005 11:01 pm
Contact:

Post by Teknojnky »

OoOoOOoooO

New panel and scripting, can't wait for someone to emplement lyric support!

Also, wonder if these panel's can be used as browser type windows, both for input and output (ie show cddb/musicbrainz track listing for current album etc) and other cool features.
Steegy
Posts: 3452
Joined: Sat Nov 05, 2005 7:17 pm

Post by Steegy »

This looks GREAT!
Extensions: ExternalTools, ExtractFields, SongPreviewer, LinkedTracks, CleanImport, and some other scripts (Need Help with Addons > List of All Scripts).
psyXonova
Posts: 785
Joined: Fri May 20, 2005 3:57 am
Location: Nicosia, Cyprus
Contact:

Post by psyXonova »

All those looks great...
I love the shutdown event, but i even more love the dockable panel, which was my wish a long time now...

Thanks man

I will be ready for them!!!
trixmoto
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Hull, UK
Contact:

Post by trixmoto »

I think I will definitely redo my Lyric Timer script as a dockable window. Excellent work Jiri! :)
Download my scripts at my own MediaMonkey fansite.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
psyXonova
Posts: 785
Joined: Fri May 20, 2005 3:57 am
Location: Nicosia, Cyprus
Contact:

Post by psyXonova »

And ofcourse i will redo my panel script to make it compatible with the dockable panel...
Bex
Posts: 6316
Joined: Fri May 21, 2004 5:44 am
Location: Sweden

Post by Bex »

:D
I just tested these script and I must say that I'm really looking forward to see these new cool features in various scripts!

So Trixmoto, onkel_enno, psyxonova, Peke, steegy, risser, pablo plus all other script gurus. Check it out and update your script-babies since this is cool! 8)

/Bex
Steegy
Posts: 3452
Joined: Sat Nov 05, 2005 7:17 pm

Post by Steegy »

@devs

I have a problem using the event mechanism:

Code: Select all

Dim xmlDoc

sub CheckState()

  dim state
  state = xmldoc.readyState
  SDB.MessageBox state & " - " & xmldoc.parseError.errorCode & " - " & xmldoc.parseError.reason, mtError, Array(mbOK)

  if state = 4 then
    SDB.MessageBox "Download complete!", mtError, Array(mbOK)
  end if

end sub



Sub SwitchFields

  Set xmlDoc = CreateObject("Msxml2.DOMDocument.3.0") 

  xmlDoc.async = true
  xmldoc.onreadystatechange = GetRef("CheckState")
  'Script.RegisterEvent xmldoc, "onreadystatechange", "CheckState" 
  xmlDoc.load("http://ws.audioscrobbler.com/1.0/artist/" & "TLC" & "/similar.xml")

'...

End Sub
The above "code" works, because I'm using

Code: Select all

xmldoc.onreadystatechange = GetRef("CheckState")
(only works vor vbscript v5 or higher).

Using the new event mechanism

Code: Select all

Script.RegisterEvent xmldoc, "onreadystatechange", "CheckState"
, the event handler sub also executes, but with at the end of the sub each time an error


I have no problem using the above "byref" method, but I don't know if everyone has version 5 or above, and I just wanted to let you guys know.


ADDITION:
Ok, that solution went good when the sub wasn't done before the event rose. When it was exited to early, it would "cancel" the event by the ByRef event assigning statement and the event would never be called.

So this workaround (with a timer) should always work:

Code: Select all

Dim xmlDoc
Dim Tmr

sub CheckState()

  if xmldoc.readyState = 4 then
    SDB.MessageBox "Download complete!", mtError, Array(mbOK)
  end if

end sub

Sub ProgTimer(Timer) 
  If xmldoc.readyState = 4 Then 
    Script.UnregisterEvents Tmr 
    SDB.MessageBox "Download complete!", mtError, Array(mbOK)
  End If  
End Sub 


Sub SwitchFields

   Set Tmr = SDB.CreateTimer( 500)   ' Pop up a message in 10 seconds 
     Script.RegisterEvent Tmr, "OnTimer", "ProgTimer" 

  
  
Set xmlDoc = CreateObject("Msxml2.DOMDocument.3.0") 

xmlDoc.async = true
'xmldoc.onreadystatechange = GetRef("CheckState")
xmlDoc.load("http://ws.audioscrobbler.com/1.0/artist/" & "TLC" & "/similar.xml") 

'...

End Sub
BTW: I din't set any Objects to Nothing here. Normally I should, but I assume I will use them later in the code...



Cheers
Steegy
Extensions: ExternalTools, ExtractFields, SongPreviewer, LinkedTracks, CleanImport, and some other scripts (Need Help with Addons > List of All Scripts).
Mike H
Posts: 39
Joined: Mon Mar 06, 2006 7:51 pm
Location: York, UK

Post by Mike H »

I get the same problem: I get script event errors if I register an event handler. (5.2RC3) When the event handler is called, a message box pops up saying script event error

Image

Does anyone know what causes this? The important point to note is that the event handler executes fine.

Steegy, you aren't storing the xmlDoc object anywhere, so it will be disposed when the method finishes, that's why the event is cancelled. You need to do

Code: Select all

set SDB.Objects("myXMLDoc") = xmlDoc
to store the object long enough to raise the event.

Also, I'm not sure if the GetRef method will work, beacause the script will no longer be available (I assume - Jiri?) between script invocations so the function pointer will be invalid.

Thanks for the workaround though.
Steegy
Posts: 3452
Joined: Sat Nov 05, 2005 7:17 pm

Post by Steegy »

The events SDB.OnPlay and SDB.OnPause (and probably this is for all events) can only be hooked to one event handling method.
This is certainly a strange thing, as I always thought SDB.OnPlay was the perfect replacement for ScriptType=2.

Can this be "fixed" please?

Cheers
Steegy
Extensions: ExternalTools, ExtractFields, SongPreviewer, LinkedTracks, CleanImport, and some other scripts (Need Help with Addons > List of All Scripts).
jiri
Posts: 5433
Joined: Tue Aug 14, 2001 7:00 pm
Location: Czech Republic
Contact:

Post by jiri »

Do you have a code example that doesn't work? I think it should work fine if you hook the event from two scripts...

Jiri
Steegy
Posts: 3452
Joined: Sat Nov 05, 2005 7:17 pm

Post by Steegy »

Using these 2 scripts separately (only one of both actually as Autoscript) works fine.
Together, only SignatureWriter handles the OnPlay event.

http://home.tiscali.be/ruben.castelein/ ... ouncer.vbs
http://home.tiscali.be/ruben.castelein/ ... Writer.vbs

Cheers
Steegy
Extensions: ExternalTools, ExtractFields, SongPreviewer, LinkedTracks, CleanImport, and some other scripts (Need Help with Addons > List of All Scripts).
jiri
Posts: 5433
Joined: Tue Aug 14, 2001 7:00 pm
Location: Czech Republic
Contact:

Post by jiri »

Ok, I see, it will be fixed in MM 2.5.3.

Thanks,
Jiri
Post Reply