Тема: AHK: Получение информации у медиа с WinRT API и MediaControl Class.
https://learn.microsoft.com/en-us/uwp/a … inrt-22621
Данный код получает название, артиста и hbitmap обложки проигрываемого медиа в фаерфоксе.
Но можно получать еще много чего, а также управлять медиа.
https://learn.microsoft.com/en-us/uwp/a … inrt-22621
app := "firefox.exe"
CreateClass("Windows.Media.Control.GlobalSystemMediaTransportControlsSessionManager", IGlobalSystemMediaTransportControlsSessionManagerStatics := "{2050c4ee-11a0-57de-aed7-c97c70338245}", GlobalSystemMediaTransportControlsSessionManagerStatics)
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionManagerStatics+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionManagerStatics, "ptr*", GlobalSystemMediaTransportControlsSessionManager) ; GlobalSystemMediaTransportControlsSessionManager.RequestAsync
WaitForAsync(GlobalSystemMediaTransportControlsSessionManager)
DllCall("LoadLibrary", "str", "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0) ; sizeof(GdiplusStartupInput) = 16, 24
NumPut(0x1, si, "uint")
DllCall("gdiplus\GdiplusStartup", "ptr*", pToken:=0, "ptr", &si, "ptr", 0)
return
f11::
title := artist := ""
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionManager+0)+7*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionManager, "ptr*", GlobalSystemMediaTransportControlsSessionList) ; GlobalSystemMediaTransportControlsSessionManager.GetSessions
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionList+0)+7*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionList, "int*", count) ; count
loop % count
{
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionList+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionList, "int", A_Index-1, "ptr*", GlobalSystemMediaTransportControlsSession)
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSession+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSession, "ptr*", SourceAppUserModelId) ; GlobalSystemMediaTransportControlsSession.get_SourceAppUserModelId
buffer := DllCall("Combase.dll\WindowsGetStringRawBuffer", "ptr", SourceAppUserModelId, "uint*", length, "ptr")
if (StrGet(buffer, "UTF-16") = app)
{
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSession+0)+7*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSession, "ptr*", GlobalSystemMediaTransportControlsSessionMediaProperties) ; GlobalSystemMediaTransportControlsSession.TryGetMediaPropertiesAsync
WaitForAsync(GlobalSystemMediaTransportControlsSessionMediaProperties)
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionMediaProperties+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionMediaProperties, "ptr*", hTitle) ; GlobalSystemMediaTransportControlsSessionMediaProperties.get_Title
buffer := DllCall("Combase.dll\WindowsGetStringRawBuffer", "ptr", hTitle, "uint*", length, "ptr")
title := StrGet(buffer, "UTF-16")
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionMediaProperties+0)+9*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionMediaProperties, "ptr*", hTitle) ; GlobalSystemMediaTransportControlsSessionMediaProperties.get_Artist
buffer := DllCall("Combase.dll\WindowsGetStringRawBuffer", "ptr", hTitle, "uint*", length, "ptr")
artist := StrGet(buffer, "UTF-16")
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionMediaProperties+0)+15*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionMediaProperties, "ptr*", RandomAccessStreamReference) ; GlobalSystemMediaTransportControlsSessionMediaProperties.get_Thumbnail
if (DllCall(NumGet(NumGet(RandomAccessStreamReference+0)+6*A_PtrSize), "ptr", RandomAccessStreamReference, "ptr*", RandomAccessStreamWithContentType) = 0) ; IRandomAccessStreamReference.OpenReadAsync
{
WaitForAsync(RandomAccessStreamWithContentType)
VarSetCapacity(CLSID, 16, 0)
DllCall("ole32\CLSIDFromString", "wstr", IID_IStream := "{0000000C-0000-0000-C000-000000000046}", "ptr", &CLSID)
DllCall("ShCore\CreateStreamOverRandomAccessStream", "ptr", RandomAccessStreamWithContentType, "ptr", &CLSID, "ptr*", Stream, "uint")
DllCall("gdiplus\GdipCreateBitmapFromStream", "ptr", Stream, "ptr*", pBitmap)
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "ptr", pBitmap, "ptr*", hBitmap, "uint", 0xffffffff)
DllCall("Gdiplus.dll\GdipDisposeImage", "ptr", pBitmap)
ObjReleaseClose(Stream)
ObjReleaseClose(RandomAccessStreamWithContentType)
}
ObjReleaseClose(RandomAccessStreamReference)
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionMediaProperties)
ObjReleaseClose(GlobalSystemMediaTransportControlsSession)
break
}
ObjReleaseClose(GlobalSystemMediaTransportControlsSession)
}
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionList)
msgbox % "title: " title "`nartist: " artist "`nhbitmap: " hbitmap
if hbitmap
{
DllCall("DeleteObject", "ptr", hBitmap)
hBitmap := ""
}
return
CreateClass(string, interface := "", ByRef Class := "")
{
CreateHString(string, hString)
if (interface = "")
result := DllCall("Combase.dll\RoActivateInstance", "ptr", hString, "ptr*", Class, "uint")
else
{
VarSetCapacity(GUID, 16)
DllCall("ole32\CLSIDFromString", "wstr", interface, "ptr", &GUID)
result := DllCall("Combase.dll\RoGetActivationFactory", "ptr", hString, "ptr", &GUID, "ptr*", Class, "uint")
}
if (result != 0)
{
if (result = 0x80004002)
msgbox No such interface supported
else if (result = 0x80040154)
msgbox Class not registered
else
msgbox error: %result%
ExitApp
}
DeleteHString(hString)
}
CreateHString(string, ByRef hString)
{
DllCall("Combase.dll\WindowsCreateString", "wstr", string, "uint", StrLen(string), "ptr*", hString)
}
DeleteHString(hString)
{
DllCall("Combase.dll\WindowsDeleteString", "ptr", hString)
}
WaitForAsync(ByRef Object)
{
AsyncInfo := ComObjQuery(Object, IAsyncInfo := "{00000036-0000-0000-C000-000000000046}")
loop
{
DllCall(NumGet(NumGet(AsyncInfo+0)+7*A_PtrSize), "ptr", AsyncInfo, "uint*", status) ; IAsyncInfo.Status
if (status != 0)
{
if (status != 1)
{
DllCall(NumGet(NumGet(AsyncInfo+0)+8*A_PtrSize), "ptr", AsyncInfo, "uint*", ErrorCode) ; IAsyncInfo.ErrorCode
msgbox AsyncInfo status error: %ErrorCode%
ExitApp
}
ObjRelease(AsyncInfo)
break
}
sleep 10
}
DllCall(NumGet(NumGet(Object+0)+8*A_PtrSize), "ptr", Object, "ptr*", ObjectResult) ; GetResults
ObjReleaseClose(Object)
Object := ObjectResult
}
ObjReleaseClose(ByRef Object)
{
if Object
{
if (Close := ComObjQuery(Object, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}"))
{
DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close) ; Close
ObjRelease(Close)
}
ObjRelease(Object)
}
Object := ""
}
Пример отлова событий:
app := "firefox.exe"
GoSub init
return
Connected:
Disconnected:
Closed:
Opened:
Changing:
Stopped:
Playing:
Paused:
msgbox % a_thislabel
return
init:
#Persistent
OnExit, ExitSub
Events := [3 ;QueryInterface
,1 ;AddRef
,1 ;Release
,3] ;Invoke
VarSetCapacity(vtbl1, A_PtrSize*Events.MaxIndex(), 0)
For Index, ParameterCount In Events
NumPut(RegisterCallback("PlaybackInfoChangedEvent", "Fast", ParameterCount, A_Index-1), vtbl1, A_PtrSize*(A_Index-1))
PlaybackInfoChangedEvent := DllCall("GlobalAlloc", "uint", 0, "ptr", A_PtrSize, "ptr")
NumPut(&vtbl1, PlaybackInfoChangedEvent+0, 0)
CreateClass("Windows.Media.Control.GlobalSystemMediaTransportControlsSessionManager", IGlobalSystemMediaTransportControlsSessionManagerStatics := "{2050c4ee-11a0-57de-aed7-c97c70338245}", GlobalSystemMediaTransportControlsSessionManagerStatics)
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionManagerStatics+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionManagerStatics, "ptr*", GlobalSystemMediaTransportControlsSessionManager) ; GlobalSystemMediaTransportControlsSessionManager.RequestAsync
WaitForAsync(GlobalSystemMediaTransportControlsSessionManager)
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionManagerStatics)
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionManager+0)+7*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionManager, "ptr*", GlobalSystemMediaTransportControlsSessionList) ; GlobalSystemMediaTransportControlsSessionManager.GetSessions
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionList+0)+7*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionList, "int*", count) ; count
loop % count
{
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionList+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionList, "int", A_Index-1, "ptr*", GlobalSystemMediaTransportControlsSession)
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSession+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSession, "ptr*", SourceAppUserModelId) ; GlobalSystemMediaTransportControlsSession.get_SourceAppUserModelId
buffer := DllCall("Combase.dll\WindowsGetStringRawBuffer", "ptr", SourceAppUserModelId, "uint*", length, "ptr")
if (StrGet(buffer, "UTF-16") = app)
{
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSession+0)+27*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSession, "ptr", PlaybackInfoChangedEvent, "int64*", PlaybackInfoChangedEventToken) ; GlobalSystemMediaTransportControlsSession.add_PlaybackInfoChanged
GlobalSystemMediaTransportControlsSessionCurrent := GlobalSystemMediaTransportControlsSession
SetTimer, Connected, -1
break
}
ObjReleaseClose(GlobalSystemMediaTransportControlsSession)
}
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionList)
VarSetCapacity(vtbl2, A_PtrSize*Events.MaxIndex(), 0)
For Index, ParameterCount In Events
NumPut(RegisterCallback("SessionsChangedEvent", "Fast", ParameterCount, A_Index-1), vtbl2, A_PtrSize*(A_Index-1))
SessionsChangedEvent := DllCall("GlobalAlloc", "uint", 0, "ptr", A_PtrSize*3+8+StrLen(app)+1, "ptr")
NumPut(&vtbl2, SessionsChangedEvent+0, 0)
NumPut(PlaybackInfoChangedEvent, SessionsChangedEvent+0, A_PtrSize)
NumPut(GlobalSystemMediaTransportControlsSessionCurrent, SessionsChangedEvent+0, A_PtrSize*2)
NumPut(PlaybackInfoChangedEventToken, SessionsChangedEvent+0, A_PtrSize*3, "int64")
StrPut(app, SessionsChangedEvent+A_PtrSize*3+8, "utf-8")
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionManager+0)+10*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionManager, "ptr", SessionsChangedEvent, "int64*", SessionsChangedEventToken) ; GlobalSystemMediaTransportControlsSessionManager.add_SessionsChanged
return
ExitSub:
GlobalSystemMediaTransportControlsSessionCurrent := NumGet(SessionsChangedEvent+0, A_PtrSize*2)
PlaybackInfoChangedEventToken := NumGet(SessionsChangedEvent+0, A_PtrSize*3, "int64")
if GlobalSystemMediaTransportControlsSessionCurrent
{
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionCurrent+0)+28*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionCurrent, "int64", PlaybackInfoChangedEventToken) ; GlobalSystemMediaTransportControlsSession.remove_PlaybackInfoChanged
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionCurrent)
}
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionManager+0)+11*A_PtrSize), "int64", SessionsChangedEventToken) ; GlobalSystemMediaTransportControlsSessionManager.remove_SessionsChanged
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionManager)
DllCall("GlobalFree", "ptr", PlaybackInfoChangedEvent, "ptr")
DllCall("GlobalFree", "ptr", SessionsChangedEvent, "ptr")
ObjReleaseClose(PlaybackInfoChangedEvent)
ObjReleaseClose(SessionsChangedEvent)
ExitApp
PlaybackInfoChangedEvent(this, guid = "", ppvObject = "")
{
static IID_IUnknown, p1, p2, oPlaybackStatus := {0:"Closed", 1:"Opened", 2:"Changing", 3:"Stopped", 4:"Playing", 5:"Paused"}
if !IID_IUnknown
{
VarSetCapacity(p1, 16, 0)
DllCall("ole32\CLSIDFromString", "wstr", IID_IUnknown := "{00000000-0000-0000-C000-000000000046}", "ptr", &p1)
VarSetCapacity(p2, 16, 0)
DllCall("ole32\CLSIDFromString", "wstr", IID_IPlaybackInfoChangedEvent := "{2bdf1426-d41f-5896-897f-efc0b0fa7392}", "ptr", &p2)
}
If (A_EventInfo = 0)
{
if DllCall("ole32\IsEqualGUID", "ptr", guid, "ptr", &p1) or DllCall("ole32\IsEqualGUID", "ptr", guid, "ptr", &p2)
{
NumPut(this, ppvObject+0)
return 0
}
else
{
NumPut(0, ppvObject+0)
return 0x80004002
}
}
else if (A_EventInfo = 3) ; Invoke
{
DllCall(NumGet(NumGet(guid+0)+9*A_PtrSize), "ptr", guid, "ptr*", GlobalSystemMediaTransportControlsSessionPlaybackInfo) ; GlobalSystemMediaTransportControlsSession.GetPlaybackInfo
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionPlaybackInfo+0)+7*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionPlaybackInfo, "int*", PlaybackStatus) ; GlobalSystemMediaTransportControlsSessionPlaybackInfo.PlaybackStatus
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionPlaybackInfo)
SetTimer, % oPlaybackStatus[PlaybackStatus], -1
return 0
}
return 1
}
SessionsChangedEvent(this, guid = "", ppvObject = "")
{
static IID_IUnknown, p1, p2, PlaybackInfoChangedEvent, GlobalSystemMediaTransportControlsSessionCurrent, PlaybackInfoChangedEventToken, app, oPlaybackStatus
if !IID_IUnknown
{
VarSetCapacity(p1, 16, 0)
DllCall("ole32\CLSIDFromString", "wstr", IID_IUnknown := "{00000000-0000-0000-C000-000000000046}", "ptr", &p1)
VarSetCapacity(p2, 16, 0)
DllCall("ole32\CLSIDFromString", "wstr", IID_ISessionsChangedEvent := "{2e2a8630-dc8c-530a-9746-bc984d4b029e}", "ptr", &p2)
PlaybackInfoChangedEvent := NumGet(this+0, A_PtrSize)
GlobalSystemMediaTransportControlsSessionCurrent := NumGet(this+0, A_PtrSize*2)
PlaybackInfoChangedEventToken := NumGet(this+0, A_PtrSize*3, "int64")
app := strget(this+A_PtrSize*3+8, "utf-8")
}
If (A_EventInfo = 0)
{
if DllCall("ole32\IsEqualGUID", "ptr", guid, "ptr", &p1) or DllCall("ole32\IsEqualGUID", "ptr", guid, "ptr", &p2)
{
NumPut(this, ppvObject+0)
return 0
}
else
{
NumPut(0, ppvObject+0)
return 0x80004002
}
}
else if (A_EventInfo = 3) ; Invoke
{
DllCall(NumGet(NumGet(guid+0)+7*A_PtrSize), "ptr", guid, "ptr*", GlobalSystemMediaTransportControlsSessionList) ; GlobalSystemMediaTransportControlsSessionManager.GetSessions
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionList+0)+7*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionList, "int*", count) ; count
loop % count
{
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionList+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionList, "int", A_Index-1, "ptr*", GlobalSystemMediaTransportControlsSession)
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSession+0)+6*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSession, "ptr*", SourceAppUserModelId) ; GlobalSystemMediaTransportControlsSession.get_SourceAppUserModelId
buffer := DllCall("Combase.dll\WindowsGetStringRawBuffer", "ptr", SourceAppUserModelId, "uint*", length, "ptr")
if (StrGet(buffer, "UTF-16") = app)
{
SessionFound := 1
if !GlobalSystemMediaTransportControlsSessionCurrent
{
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSession+0)+27*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSession, "ptr", PlaybackInfoChangedEvent, "int64*", PlaybackInfoChangedEventToken) ; GlobalSystemMediaTransportControlsSession.add_PlaybackInfoChanged
GlobalSystemMediaTransportControlsSessionCurrent := GlobalSystemMediaTransportControlsSession
NumPut(GlobalSystemMediaTransportControlsSessionCurrent, this+0, A_PtrSize*2)
NumPut(PlaybackInfoChangedEventToken, this+0, A_PtrSize*3, "int64")
SetTimer, Connected, -1
}
else
ObjReleaseClose(GlobalSystemMediaTransportControlsSession)
break
}
ObjReleaseClose(GlobalSystemMediaTransportControlsSession)
}
if !SessionFound and GlobalSystemMediaTransportControlsSessionCurrent
{
DllCall(NumGet(NumGet(GlobalSystemMediaTransportControlsSessionCurrent+0)+28*A_PtrSize), "ptr", GlobalSystemMediaTransportControlsSessionCurrent, "int64", PlaybackInfoChangedEventToken) ; GlobalSystemMediaTransportControlsSession.remove_PlaybackInfoChanged
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionCurrent)
NumPut(0, this+0, A_PtrSize*2)
NumPut(0, this+0, A_PtrSize*3, "int64")
SetTimer, Disconnected, -1
}
ObjReleaseClose(GlobalSystemMediaTransportControlsSessionList)
return 0
}
return 1
}
CreateClass(string, interface := "", ByRef Class := "")
{
CreateHString(string, hString)
if (interface = "")
result := DllCall("Combase.dll\RoActivateInstance", "ptr", hString, "ptr*", Class, "uint")
else
{
VarSetCapacity(GUID, 16)
DllCall("ole32\CLSIDFromString", "wstr", interface, "ptr", &GUID)
result := DllCall("Combase.dll\RoGetActivationFactory", "ptr", hString, "ptr", &GUID, "ptr*", Class, "uint")
}
if (result != 0)
{
if (result = 0x80004002)
msgbox No such interface supported
else if (result = 0x80040154)
msgbox Class not registered
else
msgbox error: %result%
ExitApp
}
DeleteHString(hString)
}
CreateHString(string, ByRef hString)
{
DllCall("Combase.dll\WindowsCreateString", "wstr", string, "uint", StrLen(string), "ptr*", hString)
}
DeleteHString(hString)
{
DllCall("Combase.dll\WindowsDeleteString", "ptr", hString)
}
WaitForAsync(ByRef Object)
{
AsyncInfo := ComObjQuery(Object, IAsyncInfo := "{00000036-0000-0000-C000-000000000046}")
loop
{
DllCall(NumGet(NumGet(AsyncInfo+0)+7*A_PtrSize), "ptr", AsyncInfo, "uint*", status) ; IAsyncInfo.Status
if (status != 0)
{
if (status != 1)
{
DllCall(NumGet(NumGet(AsyncInfo+0)+8*A_PtrSize), "ptr", AsyncInfo, "uint*", ErrorCode) ; IAsyncInfo.ErrorCode
msgbox AsyncInfo status error: %ErrorCode%
ExitApp
}
ObjRelease(AsyncInfo)
break
}
sleep 10
}
DllCall(NumGet(NumGet(Object+0)+8*A_PtrSize), "ptr", Object, "ptr*", ObjectResult) ; GetResults
ObjReleaseClose(Object)
Object := ObjectResult
}
ObjReleaseClose(ByRef Object)
{
if Object
{
if (Close := ComObjQuery(Object, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}"))
{
DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close) ; Close
ObjRelease(Close)
}
hr := ObjRelease(Object)
}
Object := ""
return hr
}