如何在 Spotify 歌曲最小化时为其加注星标?
好的,所以 Windows 上的 Spotify 应用程序没有内置支持全局热键和非常基本的热键,即使应用程序窗口当前处于活动状态也是如此。令人沮丧的是,“主演”当前正在播放的歌曲没有键盘快捷键,即使窗口处于活动状态也是如此。
所以我有一个自动热键脚本,它为我提供了用于播放控制、音量和复制歌曲标题(包括 em dash 修复)的全局热键,但我在试图弄清楚如何为当前歌曲加注星标时遇到了困难。
更麻烦的是,我只希望 Autohotkey 脚本在这首歌还没有加星标的情况下加星标。如果它已经出演了,那就别管它了。
我希望所有这一切都发生在应用程序位于托盘中时,而无需打开窗口。
编辑:半工作解决方案
所以我想出了一个合理的解决方案,即使程序被最小化,它也会打开一个上下文菜单,并且做所有事情,包括不取消明星的歌曲。不幸的是,上下文菜单意味着它将在瞬间最小化游戏等全屏应用程序。取决于游戏可能会很痛苦,但这是我能做的最好的事情,没有花哨的 DLL 调用和其他东西。
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
;|---------------|
;|--[ SOURCES ]--|
;|---------------|
;Base Spotify Script from: http://www.autohotkey.com/board/topic/36239-spotify-global-hotkeys/
;Base Starring Script from: http://superuser.com/questions/324416/any-spotify-tweaks-with-keyboard-shortcut-to-star-tracks
;|------------------|
;|--[ SETTING UP ]--|
;|------------------|
DetectHiddenWindows, On ;Detect Spotify even if it's minimized
#IfWinExist ahk_class SpotifyMainWindow ;Only do the following if Spotify is running
spotify = ahk_class SpotifyMainWindow ;Set variable for Spotify Window Name
;|---------------|
;|--[ HOTKEYS ]--|
;|---------------|
; "CTRL + ALT + PAGEUP" for previous
^!PGUP::
{
ControlSend, ahk_parent, ^{Left}, %spotify%
return
}
; "CTRL + ALT + PAGEDOWN" for next
^!PGDN::
{
ControlSend, ahk_parent, ^{Right}, %spotify%
return
}
; "CTRL + ALT + HOME" for pause
^!Home::
{
ControlSend, ahk_parent, {Space}, %spotify%
return
}
; "CTRL + ALT + END" for track-name
^!End::
{
WinGetTitle, spotify_playing, %spotify% ;Get the title of Spotify which contains the track-name
StringTrimLeft, trimmed_playing, spotify_playing, 10 ;Get rid of extra text and place into 'trimmed_playing'
StringReplace, replaced_playing, trimmed_playing, –, -, All ;Replace en dash with normal dash and place into 'replaced_playing'
clipboard = %replaced_playing% ;Copy the fixed text to clipboard
return
}
; "CTRL + ALT + UP" for volume up
^!Up::
{
ControlSend, ahk_parent, ^{Up}, %spotify%
return
}
; "CTRL + ALT + DOWN" for volume down
^!Down::
{
ControlSend, ahk_parent, ^{Down}, %spotify%
return
}
; "CTRL + ALT + INSERT" for starring the current song
^!Insert::
{
;Store active window and mouse position.
MouseGetPos, , , winID
;Right click near the song title in the "Now Playing" box.
WinGetPos, , , , spotifyHeight, %spotify%
clickX := 100
clickY := spotifyHeight-70
ControlClick, x%clickX% y%clickY% , %spotify%, , Right, , NA
;Get the contents of the context menu.
WinWait, ahk_class #32768
SendMessage, 0x1E1 ;MN_GETHMENU
allContextMenuInfo := ErrorLevel
;The "Star" command is the 2nd menu item.
;If the song is Unstarred the text is Star, and vice versa. But sometimes some wierd characters are included.
;The only reliable way I found is to check if the first letter is S.
menuText_StarUnstar := GetContextMenuItemText(allContextMenuInfo, 2)
StringGetPos, positionOfS, menuText_StarUnstar, S
;If S is the first letter, star the song.
notStarred := (%positionOfS% = 0)
If notStarred
{
;Arrow down to the Star menu item and press enter.
ControlSend, ahk_parent, {Down}{Down}{Enter}, %spotify%
}
Else
{
;Just close the context menu.
ControlSend, ahk_parent, {Escape}, %spotify%
}
;Restore original window and mouse position.
WinActivate ahk_id %winID%
return
}
;|-----------------|
;|--[ FUNCTIONS ]--|
;|-----------------|
;Context menu helper function.
GetContextMenuItemText(hMenu, nPos)
{
length := DllCall("GetMenuString"
, "UInt", hMenu
, "UInt", nPos
, "UInt", 0 ; NULL
, "Int", 0 ; Get length
, "UInt", 0x0400) ; MF_BYPOSITION
VarSetCapacity(lpString, length + 1)
length := DllCall("GetMenuString"
, "UInt", hMenu
, "UInt", nPos
, "Str", lpString
, "Int", length + 1
, "UInt", 0x0400)
return lpString
}
我修改了一些隐藏在互联网上的现有脚本。其来源可以在源代码的顶部找到,如果有人想尝试让它在不出现上下文菜单的情况下完全工作,它可能会有所帮助。
正常使用应用程序时如何给歌曲加星标?
在 Spotify 中似乎只有 2 条路线可以为歌曲加注星标。
- 右键单击左下角的专辑封面,然后使用星号上下文菜单选项。
- 右键单击播放列表中的歌曲并使用星号上下文菜单选项。
为了让事情变得尴尬,如果某些东西已经加星标,星标菜单选项将在完全相同的位置替换为取消星标菜单选项。当菜单打开时,它们也有相同的快捷键(t 键)。因此,您不能在不先进行某种检查的情况下进行盲目的菜单选择。
那么我们可以采取哪些可能的路线呢?
右击左下角的专辑封面是唯一现实的路线。
如果我们可以在最小化的情况下从上下文菜单中读取文本,我们可以通过将文本从“星号”更改为“取消星号”来判断某些内容是否已加星标。在那次测试之后,我们可以决定是否按下 T 键来真正为这首歌加注星标。
我还花了一些时间在 Window Detective 上,看看我是否可以发送一个相对简单的 PostMessage/SendMessage 来为歌曲加注星标。但是我的经验很少,我不知道如何将它们链接在一起以获得我想要的结果。
我发现星号和取消星号上下文菜单选项实际上是不同的:
Star -> WM_MENUSELECT (0x11F) | item identifier = 11 | flags = NONE | MF_HILITE
Unstar -> WM_MENUSELECT (0x11F) | item identifier = 12 | flags = NONE | MF_HILITE
但是我不知道如何真正将 PostMessages/SendMessages 链接在一起以打开菜单,然后只选择项目 #11,然后按 Enter。
Spotify 在为某事加注星标时收到的消息列表
以防万一这有助于确定是否可以执行 PostMessage/SendMessage 路由。
->WM_RBUTTONDOWN (0x204)
->WM_RBUTTONUP (0x205)
->WM_MENUSELECT (0x11F)
<-WM_MENUSELECT (0x11F)
->WM_KEYDOWN (0x100)
->WM_MENUSELECT (0x11F)
<-WM_MENUSELECT (0x11F)
->WM_KEYUP (0x101)
后记
我已经搜索了一段时间,试图找到 PostMessages/SendMessages 用于执行这种上下文菜单选择的好例子,但没有找到任何东西。
谢谢你的时间。
当前的自动热键脚本
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; "CTRL + ALT + PAGEUP" for previous
^!PGUP::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, ^{Left}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
; "CTRL + ALT + PAGEDOWN" for next
^!PGDN::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, ^{Right}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
; "CTRL + ALT + HOME" for pause
^!Home::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, {space}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
; "CTRL + ALT + END" for info
^!End::
{
DetectHiddenWindows, On
WinGetTitle, spotify_playing, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
StringTrimLeft, trimmed_playing, spotify_playing, 10
StringReplace, replaced_playing, trimmed_playing, –, -, All
clipboard = %replaced_playing%
return
}
; "CTRL + ALT + UP" for volume up
^!Up::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, ^{Up}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
; "CTRL + ALT + DOWN" for volume down
^!Down::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, ^{Down}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
/*
PLAN: I want to make this star the current song if it's unstarred
NOTES:
WM_MENUSELECT for star seems to be item identifier 11, unstar is 12
Star -> WM_MENUSELECT (0x11F) | item identifier = 11 | flags = NONE | MF_HILITE
Unstar -> WM_MENUSELECT (0x11F) | item identifier = 12 | flags = NONE | MF_HILITE
*/
; "CTRL + ALT + INSERT" for starring the current song
^!Insert::
{
DetectHiddenWindows, On
DetectHiddenWindows, Off
return
}