Files
VRCWT-OSC/internal/app/discord.go
2026-06-26 09:16:46 +09:00

90 lines
2.1 KiB
Go

package app
import (
"fmt"
"log"
"strings"
"syscall"
"unsafe"
)
const (
vkControl = 0x11
vkShift = 0x10
vkM = 0x4D
keyUp = 0x0002
swRestore = 9
)
func pressDiscordMuteHotkey() error {
user32 := syscall.NewLazyDLL("user32.dll")
enumWindows := user32.NewProc("EnumWindows")
getWindowTextW := user32.NewProc("GetWindowTextW")
isWindowVisible := user32.NewProc("IsWindowVisible")
setForegroundWindow := user32.NewProc("SetForegroundWindow")
showWindow := user32.NewProc("ShowWindow")
getWindowRect := user32.NewProc("GetWindowRect")
keybdEvent := user32.NewProc("keybd_event")
setCursorPos := user32.NewProc("SetCursorPos")
sleep := syscall.NewLazyDLL("kernel32.dll").NewProc("Sleep")
var target uintptr
cb := syscall.NewCallback(func(hwnd uintptr, lparam uintptr) uintptr {
vis, _, _ := isWindowVisible.Call(hwnd)
if vis == 0 {
return 1
}
buf := make([]uint16, 512)
n, _, _ := getWindowTextW.Call(hwnd, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)))
if n == 0 {
return 1
}
title := strings.ToLower(strings.TrimSpace(syscall.UTF16ToString(buf[:n])))
if !strings.Contains(title, "discord") {
return 1
}
target = hwnd
return 0
})
r1, _, err1 := enumWindows.Call(cb, 0)
if r1 == 0 && target == 0 {
return fmt.Errorf("discord window not found: %v", err1)
}
if target == 0 {
return fmt.Errorf("discord window not found")
}
showWindow.Call(target, swRestore)
setForegroundWindow.Call(target)
sleep.Call(150)
type rect struct {
Left int32
Top int32
Right int32
Bottom int32
}
var r rect
if v, _, _ := getWindowRect.Call(target, uintptr(unsafe.Pointer(&r))); v != 0 {
x := int((r.Left + r.Right) / 2)
y := int((r.Top + r.Bottom) / 2)
setCursorPos.Call(uintptr(x), uintptr(y))
sleep.Call(50)
}
send := func(vk byte, flags uintptr) {
keybdEvent.Call(uintptr(vk), 0, flags, 0)
}
send(vkControl, 0)
send(vkShift, 0)
send(vkM, 0)
send(vkM, keyUp)
send(vkShift, keyUp)
send(vkControl, keyUp)
sleep.Call(100)
SetDiscordWindow("Discord")
log.Printf("discord hotkey sent via keybd_event")
return nil
}