Predefined Scripting Constants in MediaMonkey API

Post a reply

Smilies
:D :) :( :o :-? 8) :lol: :x :P :oops: :cry: :evil: :roll: :wink:

BBCode is ON
[img] is ON
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Predefined Scripting Constants in MediaMonkey API

by trixmoto » Tue Oct 09, 2007 4:12 pm

Thanks for doing that, I'm sure many scripters will find it useful.

by imd1b4u » Tue Oct 09, 2007 3:10 pm

Steegy wrote:What I meant is that you can add things to the wiki, or rewrite stuff so it is more understandable. If it's incomplete or not 100% correct, someone else (who might know exactly how it works) will see the updates and complete/correct them. Speaking for myself, I check the wiki's "recently changed" almost every day.
Actually, your meaning was clear. I appreciate you wanting to have new scripters adding material to the wiki. I didn't expect you (or anyone else) to consciously look for changes, though.

I still have a strong preference for people using weasel-words if they are uncertain about something, though. That way I know how to interpret what they write. It's not as if it is difficult to include them or to remove them once the information is checked. I don't think asking for this would discourage anyone from adding to the wiki. My post was intended more as a reminder that it is easy to include them (and improve the accuracy of what you are writing at the same time).

Back to the original subject: There are some constants in the MediaMonkeyScripting.chm file that are not defined in the MediaMonkey init.vbs file (and probably not the .js file, either). When someone tries to use those constants they get an error or have a bug if they don't define the constants themselves.

I extracted MediaMonkeyScripting.chm to text files and greped (grepped?) the results to extract the constants mentioned there. I wouldn't be surprised if I missed some. Also, the results may not be accurate - MediaMonkeyScripting.chm has mistakes, after all.

Here are the results presented in a way that anyone could paste into their VBScript script. It should be easy to convert them to JScript.

Code: Select all

' UI Common Align
Const alNone         = 0
Const alTop          = 1
Const alBottom       = 2
Const alLeft         = 3
Const alRight        = 4
Const alClient       = 5


' UI Common Anchors
Const akLeft         = 1
Const akTop          = 2
Const akRight        = 4
Const akBottom       = 8


' UI Drop Down Style
Const csDropDown     = 0
Const csDropDownList = 2


' UI Border Style
Const bsNone         = 0
Const bsSizeable     = 2
Const bsDialog       = 3
Const bsToolWindow   = 4
Const bsSizeToolWin  = 5


' UI Form Position
Const poDesigned     = 0
Const poDefault      = 1
Const poScreenCenter = 4
This does not include the constants that are already in MediaMonkey init.vbs (some of which are undocumented).

Again, what is in MediaMonkeyScripting.chm is not necessarily accurate (and of course, Garbage_In => Garbage_Out.) Using a constant already in the init files as an example: according to the documentation, mbHelp is 12, but the init file really sets mbHelp to 14 and mbIgnoreToAll to 12. (I just happened to notice that, so I don't know how bad it is.) I have done no testing to verify that anything I provided actually works correctly; it just matches the documentation.

by Steegy » Mon Oct 08, 2007 3:51 pm

What I meant is that you can add things to the wiki, or rewrite stuff so it is more understandable. If it's incomplete or not 100% correct, someone else (who might know exactly how it works) will see the updates and complete/correct them. Speaking for myself, I check the wiki's "recently changed" almost every day.
Obviously this isn't the ideal way to add 100% correct stuff to the wiki at once, but it is a way that does probably give more valuable contents (as wiki contents has been coming very slowly).

Once you're not newbie anymore, it's more difficult to write information understandable for new scripters, as things will seem more obvious and you'll tend to leave them out or oversimplicate them. At least that's my experience.

But it's a fact that virtually all valuable wiki content comes from somewhere in the forum.

by imd1b4u » Mon Oct 08, 2007 2:42 pm

Steegy wrote:Feel free to change things in the wiki (as long as it's mostly correct); you might be in a situation that makes it much easier to explain stuff for new scripters, as for people who already know the stuff, some necessary and important details (?!) might look "obvious". If you get something wrong, don't worry, it'll get fixed.
I disagree somewhat. Yes, mistakes will happen, but IMO, people should not write "'X'" in the wiki unless they are confident that 'X' is really true. It is worse to mislead someone than it is to leave them unknowing.

Also, keep in mind that "I think 'X'" is virtually guaranteed to be true, unless the author is being dishonest. If someone is uncertain about something it is important to indicate the uncertainty, IMO. That way the reader knows how to interpret what was written.

Thanks for everything else in your post.

by Steegy » Sun Oct 07, 2007 2:29 pm

Is there any particular reason you didn't "Set WB = Nothing" in CloseDown?
Yes, because that's *completely* useless. Variable declarations that go out of scope (here the scope of the CloseDown procedure) are automatically gotten rid of (in virtually any programming language).
Set X = Nothing is only useful if X is a script-wide scoped variable and you want to free its resources at some point before the script itself is freed (usually when MM exits).

Stickied scripting resource post: it now links to the Scripting Wiki

Feel free to change things in the wiki (as long as it's mostly correct); you might be in a situation that makes it much easier to explain stuff for new scripters, as for people who already know the stuff, some necessary and important details (?!) might look "obvious". If you get something wrong, don't worry, it'll get fixed.
Asking the questions like you do is important, because I'm sure that a lot of scripters can benefit from this information, and throw some of the old (event mechanism) / useless (set to Nothing) habits away.

by imd1b4u » Sat Oct 06, 2007 7:52 pm

Peke wrote:Good points.
You dint saved objSSL object (I didn't payed attencion on that) and thats why it do not exist in second pass (reason it is not initialized) When you init Some Var save it for later using Objects and you will always get Zoro.
Oh! So, basically that means that what Steegy said a few posts ealier:
Steegy wrote:Variables defined for the complete script scope can be reached by code that is called by an event using the new scripting mechanism (recommended, only isn't possible for option sheets). These variables can NOT be used by an event using the old event mechanism (only use this for now for option sheets).
... is relevant to what I am doing after all.

Now I see (and am beginning to appreciate the significance of) what Steegy wrote in the wiki (Tips & Tricks):
There are still 2 scripting mechanisms available:

* Using the (mostly deprecated) old event mechanism (using Control.OnClickFunc and Control.UseScript), your global variables aren't remembered in the event handlers (e.g. kind of like the script is reopened). For those scripts, you had to use ParentControl.ChildControl("control name") or save object references to SDB's Objects dictionary.
* Using the new event mechanism, your global variables are remembered so you can use their values in the event handlers. The Objects dictionary is now only necessary to communicate/store object references between different scripts.

==> So always use the new event mechanism where you can. Only for option panels (sheets) this is not yet possible. There you'll need to store values between the main program and the event handlers in SDB.Objects, in the INI or in the Registry.
So, I guess that means I was using what Steegy called the "old mechanism" with my top button, and the "new mechanism" with the bottom button. And that's why the bottom button worked, while the top one didn't.

@Steegy, would you mind deleting the text in your Resourcesstickied post and just leaving links to both of the wiki Resourses and Tips & Tricks pages? If not, would you please add a link to the Tips & Tricks page (similar to the one to the Resources wiki page) to that post? Having two different versions of the same information is confusing, as was not knowing there was a newer version of the "Tips" around. In the "Tips" of the forum post, you talk about a "new" and an "old" "mechanism" without giving a clue as to which is which. To you it is probably obvious which is new, but to someone new to MM scripting, it isn't. Actually, the first time I saw the Tips & Tricks wiki page, I thought the "new mechanism" was something specific to MM3, which is "new" and mentioned in the wiki after all. So if there are better terms than "new" and "old" (I can't think of anything myself) it sure would be nice to change to them.

by Peke » Sat Oct 06, 2007 9:51 am

Good points.
You dint saved objSSL object (I didn't payed attencion on that) and thats why it do not exist in second pass (reason it is not initialized) When you init Some Var save it for later using Objects and you will always get Zoro.

by imd1b4u » Sat Oct 06, 2007 12:23 am

Peke wrote:Are you sure you are doing it like you want?
Thanks for trying to help. All I was trying to do, though, was demonstrate some strange behavior that I don't understand that involves variable scope issues. The code serves no useful purpose beyond that. I probably confused things by referring to two different objects. The same issues should apply to any SDB object AFAIK.
Peke wrote:Sub onStartup is executed on MM start and objSSL will have same value untill you close MM and may produce wrong value.
I set it up that way so someone could just paste it into a file and run it to see what I am talking about without messing with the scripts\scripts.ini file. It doesn't have to be that way - the same problems exist no matter how you start the script, or what the Sub is called. As it is, objSSL.Count should be zero, because nothing could be selected yet on Startup. I just wanted to see if I got an error trying to refer to the objSSL variable. First the script displays the message saying objSSL.count is zero, but then I get a VBScript error saying objSSL doesn't exist when I click the button, but only if I set up the button the way I did the other button. This doesn't make sense to me.
Peke wrote:Also no need to use Set objSDB = SDB as SDB is parsed to each running of script and you can always access it.
Right. I just wanted to see if I could use objSDB without generating an vbScript error.

If I call the subroutines directly, I can access the object variables as expected. If I set up the buttons the way I did with the first one, supposedly the objects don't exist when I click the button, even though obviously do exist, because I just used them! But if I do it they way I did for the second one, then they exist when I click a button. That makes no sense to me.

by Peke » Fri Oct 05, 2007 10:36 pm

Are you sure you are doing it like you want?

Sub onStartup is executed on MM start and objSSL will have same value untill you close MM and may produce wrong value.

Also no need to use Set objSDB = SDB as SDB is parsed to each running of script and you can always access it.

by imd1b4u » Fri Oct 05, 2007 8:26 pm

Steegy wrote:"MediaMonkey init.vbs" is included (each time) for each script that is executed. As it is merely included, the variables (constants) aren't "shared" with other scripts and you can't globally change them (therefore there's SDB.Objects).

Variables defined for the complete script scope can be reached by code that is called by an event using the new scripting mechanism (recommended, only isn't possible for option sheets). These variables can NOT be used by an event using the old event mechanism (only use this for now for option sheets).
I am not really understanding that stuff. Does it have something to do with the very strange behavior here:

Code: Select all

Option Explicit
Dim objSDB, objSSL, frmForm, btnShowVersionHi, btnShowCount
Sub onStartup
  Set objSDB = SDB
  Set objSSL = SDB.SelectedSongList
  Set frmForm = SDB.UI.NewForm
  Set btnShowVersionHi = SDB.UI.NewButton(frmForm)
  btnShowVersionHi.Common.SetRect 10, 10, 100, 30
  btnShowVersionHi.Caption = "VersionHi"
  btnShowVersionHi.UseScript = Script.ScriptPath
  btnShowVersionHi.OnClickFunc = "ShowVersionHi"
  Set btnShowCount = SDB.UI.NewButton(frmForm)
  btnShowCount.Common.SetRect 10, 50, 100, 30
  btnShowCount.Caption = "ShowCount"
  Script.RegisterEvent btnShowCount, "OnClick", "ShowCount"
  ShowVersionHi(btnShowVersionHi)    ' This works this time!
  ShowCount                          ' This works, too!
  frmForm.ShowModal
  ' But when I click on the buttons on the form, the VersionHi one
  ' doesn't work because objSDB supposedly doesn't exist!  Yet,
  ' ojbSSL still exists when I click on the ShowCount button.
  Script.UnregisterAllEvents
End Sub
Sub ShowVersionHi(btnShowVersionHi)
  MsgBox "VersionHi = " & objSDB.VersionHi
End Sub
Sub ShowCount()
  MsgBox objSSL.Count & " songs are selected."
End Sub
This has my head spinning! I guess I have learned (finally!) to use the second method of triggering code to run when a button is clicked, but I sure don't understand how the method I used for the top button makes objects disappear!

by imd1b4u » Fri Oct 05, 2007 1:05 pm

Thanks to everyone. It's making a lot more sense now.

I just didn't see the declaration for mmFormScreenCenter. :oops: Actually, I wasn't interested in it per se; I had run into something similar (I forget which constant) and was just using mmFormScreenCenter as an example since it was used near the top. The discussion has been very helpful, none the less.

I (incorrectly?) guessed that Steegy wrote his declarations near the bottom of the file so that they would be outside any Sub (and therefore not just local to it) and because I thought (perhaps incorrectly) it was written somewhere that the first statement in a script file must be "Sub ProcName", where ProcName matches what was in the Scripts\Scripts.ini file. Now I can't find where I read that. Was I just imagining things? If that requirement doesn't exist, why do so many scripts files start out that way?

@trixmoto: The Scripting.doc documentation says:
“MediaMonkey init.vbs” file is always executed before your script and therefore it contains some constants that can be later used in your script.
(I missed that earlier. :-? ) That must mean it is safe to assume it exists. It's too bad they didn't put many of the constants from the documentation in there. :(

@Maaspuck: You probably don't need to be told this, but if you start messing with MediaMonkey init.vbs, you are asking for trouble if you try to upgrade MM or share your scripts with anyone else later on. Have you considered writing to a custom .ini (SDB.IniFile) or other flat file? That's the old-fashioned way of doing non-volatile data storage. (Using SDB.Objects is over my head, and not relevant for what I'm doing. EDIT :o Maybe that's why my script won't "compile"!!! I need to look into that more.)

@Everyone: The wiki looks like a good resource. I missed it in part because it isn't mentioned here: http://www.mediamonkey.com/developers.htm , or on any of the other main MM web pages (unless I'm missing something, which I've been doing a lot lately :-?). If anyone has control over that, it would be a worthwhile addition, IMHO. @Steegy, your resources page looks great and mentions the wiki - I must have been a bit overwhelmed when I read it.

@Steegy: Is there any particular reason you didn't "Set WB = Nothing" in CloseDown?

by Steegy » Thu Oct 04, 2007 2:35 pm

"MediaMonkey init.vbs" is included (each time) for each script that is executed. As it is merely included, the variables (constants) aren't "shared" with other scripts and you can't globally change them (therefore there's SDB.Objects).

Variables defined for the complete script scope can be reached by code that is called by an event using the new scripting mechanism (recommended, only isn't possible for option sheets). These variables can NOT be used by an event using the old event mechanism (only use this for now for option sheets).

BTW: All this information can be found in the MM Wiki here and here.

by Maaspuck » Wed Oct 03, 2007 4:17 pm

@Steegy,

thx for the explanation, this helps to improve the understanding of the execution mechanisms. I hope i am not responsible for any kind of confusion due to my comment above. If yes, i am sorry about that.

@all
But may i ask another question about defining variables in scripts?

- Can i declare a global variable like 'variable1=1' in one subroutine (e.g. the 'OnStartUp' sub) and use it later in another sub without using the sdb.objects method?

- Which way do i have to use in order to keep a variable definition alive until the MM exits? Up to now i wasn't able to do so. Consequently i have included the definition code at the top of my script before the first subroutine as i thought that this part will be executed everytime any sub of this script is called.

- This raises another question. When is the MediaMonkey init.vbs called? Once at the start of the program or everytime a script or a sub of a script is executed? Can I make a global variable by editing the MediaMonkey init.vbs? I tested this and it was possibleto make a definition. I included a

Code: Select all

Dim testvariable
testvariable = "This is only a test"
in the MediaMonkey init.vbs and it was possible to use this variable in any script without using the dim-command. Then i changed the value of the testvariable in the MediaMonkey init.vbs while MM was running and got the new value also in the script with the msgbox command. So it seems that the MediaMonkey init.vbs is called everytime another script is called. But you can't change the value of the variable within any script as it will be redefined the next time a script is started. Even if you call another sub within a script after changing the value you get the 'original' value. Therefore it seems to me that the MediaMonkey init.vbs is only useful for constants but not for variables.

This behaviour is confusing and i really do not understand how this works though i wrote a quite large script. I hope that i have explained the problems i encountered in a way that can be understood.

Best regards

Maaspuck

by Steegy » Wed Oct 03, 2007 2:13 pm

Some constants (defined in "MediaMonkey init.vbs") are included by default for each script that is executed, as Trixmoto explained.

Other constants that can be found in the scripting help have to be defined by yourself (better this than just using the values).

Why I used this non-standard name at the time is not clear to me either.

Code: Select all

So, it is not necessary to declare a constant above its usage.
It IS necessary to define constants (or anything else) before its usage. The constants in the PTE script are below the "real" script code, but they are read sooner that that "real" script code (which is only executed when the PTE menu item is clicked).

The way how scripts are loaded and executed in MM (and how/which variables/objects keep living) is sometimes not very straightforward, and there's certainly a big difference between the old event mechanism (Button.OnClick = ...) and the new one (Script.RegisterEvent Button, "OnClick", "Button_OnClick"). Scripts using the newer event mechanism can use variables that were assigned when the script was first loaded, and these variables will continue to exist until MM exits (and the script unloads). This is not the same for the older system (where the events execute in a "separate space").
The only place where you can't use the newer event mechanism yet is with options sheets.

by trixmoto » Wed Oct 03, 2007 4:52 am

Open file "..\MediaMonkey\Scripts\MediaMonkey init.vbs" (or.js) in a text editor - this contains a list of all the constants. I believe this is automatically included by MM so these are always available, but if not then it can be easily included (or just copy and paste the ones you need, which is I assume what Steegy did). :)

EDIT: Actually "mmFormScreenCenter" is not in that list, sorry! :oops:

Top