我正在尝试为MusicBee(音乐播放器应用)编写一个简单的插件 我正在使用API提供的示例构建。
一些背景:当主.exe(musicbee)启动时,会启动此插件。
当用户进入选项菜单中的插件配置屏幕时,将运行Configure()
功能。
在
Dim configPanel As Panel = DirectCast(Panel.FromHandle(panelHandle), Panel)
Dim btn1 As New Button
和configPanel.Controls.AddRange(New Control() {btn1})
行添加一个按钮到这个配置屏幕,我用它来启用/禁用我的插件的唯一功能。
要提供用户反馈,我需要更改此按钮的文本(即" ON"," OFF")
问题:如果我在Configure()
函数中声明了按钮,我无法从其他点击事件函数访问它。 (btn1_Click()
)
如果我全局声明它,那么当用户关闭配置屏幕(而不是整个插件)时,btn1
会被释放(实际上configPanel
会被我认为的musicbee API处理掉)。当用户再次尝试打开配置屏幕时,我会收到异常,因为当它已经处理好并且未被重新声明时,它会尝试访问btn1
。
MusicBee v3.0.6132.15853 (Win6.1), 7 Mar 2017 20:53:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Button'.
必须有一种声明/设置btn1
的方法,以便这可行,但我不知道如何。
谢谢,蒂莫西。
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Windows.Forms
Public Class Plugin
Private mbApiInterface As New MusicBeeApiInterface
Private about As New PluginInfo
Dim playMode As Boolean
Public Function Initialise(ByVal apiInterfacePtr As IntPtr) As PluginInfo
CopyMemory(mbApiInterface, apiInterfacePtr, 4)
If mbApiInterface.MusicBeeVersion = MusicBeeVersion.v2_0 Then
' MusicBee version 2.0 - Api methods > revision 25 are not available
CopyMemory(mbApiInterface, apiInterfacePtr, 456)
ElseIf mbApiInterface.MusicBeeVersion = MusicBeeVersion.v2_1 Then
CopyMemory(mbApiInterface, apiInterfacePtr, 516)
ElseIf mbApiInterface.MusicBeeVersion = MusicBeeVersion.v2_2 Then
CopyMemory(mbApiInterface, apiInterfacePtr, 584)
ElseIf mbApiInterface.MusicBeeVersion = MusicBeeVersion.v2_3 Then
CopyMemory(mbApiInterface, apiInterfacePtr, 596)
ElseIf mbApiInterface.MusicBeeVersion = MusicBeeVersion.v2_4 Then
CopyMemory(mbApiInterface, apiInterfacePtr, 604)
ElseIf mbApiInterface.MusicBeeVersion = MusicBeeVersion.v2_5 Then
CopyMemory(mbApiInterface, apiInterfacePtr, 648)
Else
CopyMemory(mbApiInterface, apiInterfacePtr, Marshal.SizeOf(mbApiInterface))
End If
about.PluginInfoVersion = PluginInfoVersion
about.Name = "Single Play Mode"
about.Description = "Adds a single play mode i.e play one track and stop."
about.Author = "Timothy Hobbs"
about.TargetApplication = "" ' current only applies to artwork, lyrics or instant messenger name that appears in the provider drop down selector or target Instant Messenger
about.Type = PluginType.General
about.VersionMajor = 1 ' your plugin version
about.VersionMinor = 0
about.Revision = 1
about.MinInterfaceVersion = MinInterfaceVersion
about.MinApiRevision = MinApiRevision
about.ReceiveNotifications = ReceiveNotificationFlags.PlayerEvents
about.ConfigurationPanelHeight = 40 ' height in pixels that musicbee should reserve in a panel for config settings. When set, a handle to an empty panel will be passed to the Configure function
Return about
End Function
Public Function Configure(ByVal panelHandle As IntPtr) As Boolean
' save any persistent settings in a sub-folder of this path
Dim dataPath As String = mbApiInterface.Setting_GetPersistentStoragePath()
' panelHandle will only be set if you set about.ConfigurationPanelHeight to a non-zero value
' keep in mind the panel width is scaled according to the font the user has selected
' if about.ConfigurationPanelHeight is set to 0, you can display your own popup window
If panelHandle <> IntPtr.Zero Then
Dim configPanel As Panel = DirectCast(Panel.FromHandle(panelHandle), Panel)
Dim btn1 As New Button
btn1.Location = New Point(0, 0)
btn1.Size = New Size(150, 25)
btn1.Text = "Single Play Mode: OFF"
playMode = False
configPanel.Controls.AddRange(New Control() {btn1})
AddHandler btn1.Click, AddressOf btn1_Click
End If
Return True
End Function
Public Sub btn1_Click(sender As Object, e As EventArgs) 'toggle play mode
If playMode Then 'We are in single play mode so turn it OFF
playMode = False
btn1.Text = "Single Play Mode: OFF" '*******ERROR HERE*******
If mbApiInterface.Player_GetStopAfterCurrentEnabled() Then
mbApiInterface.Player_StopAfterCurrent() 'disable it
End If
'also disable stopaftercurrent once more for the current song.
Else 'We are in normal play mode so turn it ON
playMode = True
btn1.Text = "Single Play Mode: ON" '*******AND HERE*******
'enable it once
If Not mbApiInterface.Player_GetStopAfterCurrentEnabled() Then
mbApiInterface.Player_StopAfterCurrent() 'enable it
End If
End If
End Sub
' called by MusicBee when the user clicks Apply or Save in the MusicBee Preferences screen.
' its up to you to figure out whether anything has changed and needs updating
Public Sub SaveSettings()
' save any persistent settings in a sub-folder of this path
Dim dataPath As String = mbApiInterface.Setting_GetPersistentStoragePath()
End Sub
' MusicBee is closing the plugin (plugin is being disabled by user or MusicBee is shutting down)
Public Sub Close(ByVal reason As PluginCloseReason)
End Sub
' uninstall this plugin - clean up any persisted files
Public Sub Uninstall()
End Sub
' receive event notifications from MusicBee
' you need to set about.ReceiveNotificationFlags = PlayerEvents to receive all notifications, and not just the startup event
Public Sub ReceiveNotification(ByVal sourceFileUrl As String, ByVal type As NotificationType)
' perform some action depending on the notification type
Select Case type
Case NotificationType.PluginStartup
' perform startup initialisation
Select Case mbApiInterface.Player_GetPlayState()
Case PlayState.Playing, PlayState.Paused
' ...
End Select
Case NotificationType.TrackChanged
If playMode Then 'if single play mode is enabled
If Not mbApiInterface.Player_GetStopAfterCurrentEnabled() Then
mbApiInterface.Player_StopAfterCurrent() 'enable it
End If
End If
End Select
End Sub
' return an array of lyric or artwork provider names this plugin supports
' the providers will be iterated through one by one and passed to the RetrieveLyrics/ RetrieveArtwork function in order set by the user in the MusicBee Tags(2) preferences screen until a match is found
Public Function GetProviders() As String()
Return New String() {}
End Function
' return lyrics for the requested artist/title from the requested provider
' only required if PluginType = LyricsRetrieval
' return Nothing if no lyrics are found
Public Function RetrieveLyrics(ByVal sourceFileUrl As String, ByVal artist As String, ByVal trackTitle As String, ByVal album As String, ByVal synchronisedPreferred As Boolean, ByVal provider As String) As String
Return Nothing
End Function
' return Base64 string representation of the artwork binary data from the requested provider
' only required if PluginType = ArtworkRetrieval
' return Nothing if no artwork is found
Public Function RetrieveArtwork(ByVal sourceFileUrl As String, ByVal albumArtist As String, ByVal album As String, ByVal provider As String) As String
'Return Convert.ToBase64String(artworkBinaryData)
Return Nothing
End Function
End Class