I found a script, modified it a bit and it works well.
There are 2 problems, though:
1)
If I quit the Windows media player, the mp3 tags are still there.
I would expect that the GUI would be empty (as if I started it without running Windows Media Player)
2)
For unknown reason, when I quit the WMP, the WMP process is still running (in the Windows Task Manager).
If the AHK GUI is not running and I start the quit WMP, there is not such an issue.
What could be the problem and how to solve it?
Code: Select all
;WMPlayer.ahk
#SingleInstance force
Gui, 1: +ToolWindow -border +HwndGuiHwnd +AlwaysOnTop
WonTop:=1
Gui, 1:Color, 120F00
Gui, 1: -DPIScale
Gui, 1: Font, S6 w700 cD0D0D0 , Tahoma ;Arial
Gui, 1: Font, S7 w700 cE1E1E1 , Arial ;Segoe UI ;
Gui, 1: Add, Text, x8 y10 w550 cAqua vtitel ; Song
Gui, 1: Add, Text, x8 y40 w550 cE1E1E1 vArtist ; Artist
Gui, 1: Add, Text, x8 y70 w550 cE1E1E1 vAlbum ; Album
Gui, 1: Show, w550 h160
wmp := new RemoteWMP ; Create new instance
GoSub, medien
GoSub, start_timers
return
start_timers:
Settimer, medien, 2000 ; Refresh all 2 seconds
return
medien: ; Update titel, artist and album title
media := wmp.player.currentMedia
song := media.getItemInfo("Title")
artist := media.getItemInfo("Artist")
album := media.getItemInfo("WM/AlbumTitle")
GuiControl,, titel, %song%
GuiControl,, artist, %artist%
GuiControl,, album, %album%
return
class RemoteWMP
{
__New()
{
static IID_IOleClientSite := "{00000118-0000-0000-C000-000000000046}", IID_IOleObject := "{00000112-0000-0000-C000-000000000046}"
Process, Exist, wmplayer.exe
if !ErrorLevel
{
song =
artist =
album =
;throw Exception("wmplayer.exe is not running")
}
if !this.player := ComObjCreate("WMPlayer.OCX.7")
{
throw Exception("Failed to get WMPlayer.OCX.7 object")
}
this.rms := IWMPRemoteMediaServices_CreateInstance()
this.ocs := ComObjQuery(this.rms, IID_IOleClientSite)
this.ole := ComObjQuery(this.player, IID_IOleObject)
DllCall(NumGet(NumGet(this.ole+0)+3*A_PtrSize), "Ptr", this.ole, "Ptr", this.ocs)
}
__Delete()
{
if !this.player
{
return
}
DllCall(NumGet(NumGet(this.ole + 0) + 3 * A_PtrSize), "Ptr", this.ole, "Ptr", 0)
for k, obj in [this.ole, this.ocs, this.rms]
{
ObjRelease(obj)
}
this.player := ""
}
Jump(sec)
{
this.player.Controls.currentPosition += sec
}
TogglePause()
{
if (this.player.playState = 3) ; Playing = 3
{
this.player.Controls.pause()
}
else
{
this.player.Controls.play()
}
}
SetRate(value := 1.0)
{
VarSetCapacity(rate, 8, 0)
NumPut(value, rate, "Double")
this.player.settings.rate := ComObject(0x4005, &rate)
}
}
IWMPRemoteMediaServices_CreateInstance()
{
static vtblUnk, vtblRms, vtblIsp, vtblOls, vtblPtrs := 0, size := (A_PtrSize + 4) * 4 + 4
if !VarSetCapacity(vtblUnk)
{
extfuncs := ["QueryInterface", "AddRef", "Release"]
VarSetCapacity(vtblUnk, extfuncs.Length() * A_PtrSize)
for i, name in extfuncs
{
NumPut(RegisterCallback("IUnknown_" . name), vtblUnk, (i - 1) * A_PtrSize)
}
}
if !VarSetCapacity(vtblRms)
{
extfuncs := ["GetServiceType", "GetScriptableObject", "GetCustomUIMode"]
VarSetCapacity(vtblRms, (3 + extfuncs.Length()) * A_PtrSize)
DllCall("ntdll\RtlMoveMemory", "Ptr", &vtblRms, "Ptr", &vtblUnk, "Ptr", A_PtrSize * 3)
for i, name in extfuncs
{
NumPut(RegisterCallback("IWMPRemoteMediaServices_" . name, "Fast"), vtblRms, (2 + i) * A_PtrSize)
}
}
if !VarSetCapacity(vtblIsp)
{
VarSetCapacity(vtblIsp, 4 * A_PtrSize)
DllCall("ntdll\RtlMoveMemory", "Ptr", &vtblIsp, "Ptr", &vtblUnk, "Ptr", A_PtrSize * 3)
NumPut(RegisterCallback("IServiceProvider_QueryService", "Fast"), vtblIsp, A_PtrSize * 3)
}
if !VarSetCapacity(vtblOls)
{
extfuncs := ["SaveObject", "GetMoniker", "GetContainer", "ShowObject", "OnShowWindow", "RequestNewObjectLayout"]
VarSetCapacity(vtblOls, (3 + extfuncs.Length()) * A_PtrSize)
DllCall("ntdll\RtlMoveMemory", "Ptr", &vtblOls, "Ptr", &vtblUnk, "Ptr", A_PtrSize * 3)
for i, name in extfuncs
{
NumPut(RegisterCallback("IOleClientSite_" . name, "Fast"), vtblOls, (2 + i) * A_PtrSize)
}
}
if !vtblPtrs
{
vtblPtrs := [&vtblUnk, &vtblRms, &vtblIsp, &vtblOls]
}
pObj := DllCall("GlobalAlloc", "UInt", 0, "Ptr", size, "Ptr")
for i, ptr in vtblPtrs
{
off := A_PtrSize*(i - 1) + 4 * (i - 1)
NumPut(ptr, pObj + 0, off, "Ptr")
NumPut(off, pObj + 0, off + A_PtrSize, "UInt")
}
NumPut(1, pObj + 0, size - 4, "UInt")
return pObj
}
IUnknown_QueryInterface(this_, riid, ppvObject)
{
static IID_IUnknown, IID_IWMPRemoteMediaServices, IID_IServiceProvider, IID_IOleClientSite
if !VarSetCapacity(IID_IUnknown)
{
VarSetCapacity(IID_IUnknown, 16), VarSetCapacity(IID_IWMPRemoteMediaServices, 16)
, VarSetCapacity(IID_IServiceProvider, 16), VarSetCapacity(IID_IOleClientSite, 16)
DllCall("ole32\CLSIDFromString", "WStr", "{00000000-0000-0000-C000-000000000046}", "Ptr", &IID_IUnknown)
DllCall("ole32\CLSIDFromString", "WStr", "{CBB92747-741F-44FE-AB5B-F1A48F3B2A59}", "Ptr", &IID_IWMPRemoteMediaServices)
DllCall("ole32\CLSIDFromString", "WStr", "{6d5140c1-7436-11ce-8034-00aa006009fa}", "Ptr", &IID_IServiceProvider)
DllCall("ole32\CLSIDFromString", "WStr", "{00000118-0000-0000-C000-000000000046}", "Ptr", &IID_IOleClientSite)
}
if DllCall("ole32\IsEqualGUID", "Ptr", riid, "Ptr", &IID_IUnknown)
{
off := NumGet(this_ + 0, A_PtrSize, "UInt")
NumPut(this_ - off, ppvObject + 0, "Ptr")
IUnknown_AddRef(this_)
return 0 ; S_OK
}
if DllCall("ole32\IsEqualGUID", "Ptr", riid, "Ptr", &IID_IWMPRemoteMediaServices)
{
off := NumGet(this_ + 0, A_PtrSize, "UInt")
NumPut((this_ - off) + (A_PtrSize + 4), ppvObject + 0, "Ptr")
IUnknown_AddRef(this_)
return 0 ; S_OK
}
if DllCall("ole32\IsEqualGUID", "Ptr", riid, "Ptr", &IID_IServiceProvider)
{
off := NumGet(this_ + 0, A_PtrSize, "UInt")
NumPut((this_ - off)+((A_PtrSize + 4) * 2), ppvObject + 0, "Ptr")
IUnknown_AddRef(this_)
return 0 ; S_OK
}
if DllCall("ole32\IsEqualGUID", "Ptr", riid, "Ptr", &IID_IOleClientSite)
{
off := NumGet(this_ + 0, A_PtrSize, "UInt")
NumPut((this_ - off) + ((A_PtrSize + 4) * 3), ppvObject + 0, "Ptr")
IUnknown_AddRef(this_)
return 0 ; S_OK
}
NumPut(0, ppvObject + 0, "Ptr")
return 0x80004002 ; E_NOINTERFACE
}
IUnknown_AddRef(this_)
{
off := NumGet(this_ + 0, A_PtrSize, "UInt")
iunk := this_ - off
NumPut((_refCount := NumGet(iunk + 0, (A_PtrSize + 4) * 4, "UInt") + 1), iunk + 0, (A_PtrSize + 4) * 4, "UInt")
return _refCount
}
IUnknown_Release(this_)
{
off := NumGet(this_ + 0, A_PtrSize, "UInt")
iunk := this_ - off
_refCount := NumGet(iunk + 0, (A_PtrSize + 4) * 4, "UInt")
if (_refCount > 0)
{
NumPut(--_refCount, iunk + 0, (A_PtrSize + 4) * 4, "UInt")
if (_refCount == 0)
{
DllCall("GlobalFree", "Ptr", iunk, "Ptr")
}
}
return _refCount
}
IWMPRemoteMediaServices_GetServiceType(this_, pbstrType)
{
NumPut(DllCall("oleaut32\SysAllocString", "WStr", "Remote", "Ptr"), pbstrType + 0, "Ptr")
return 0
}
IWMPRemoteMediaServices_GetScriptableObject(this_, pbstrName, ppDispatch)
{
return 0x80004001
}
IWMPRemoteMediaServices_GetCustomUIMode(this_, pbstrFile)
{
return 0x80004001
}
IServiceProvider_QueryService(this_, guidService, riid, ppvObject)
{
return IUnknown_QueryInterface(this_, riid, ppvObject)
}