92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
//go:build windows
|
|
|
|
package winapi
|
|
|
|
import (
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
"unsafe"
|
|
)
|
|
|
|
var (
|
|
user32Window = syscall.NewLazyDLL("user32.dll")
|
|
procFindWindowW = user32Window.NewProc("FindWindowW")
|
|
procEnumWindows = user32Window.NewProc("EnumWindows")
|
|
procGetWindowTextW = user32Window.NewProc("GetWindowTextW")
|
|
procIsWindowVisible = user32Window.NewProc("IsWindowVisible")
|
|
procShowWindow = user32Window.NewProc("ShowWindow")
|
|
procSetForegroundWindow = user32Window.NewProc("SetForegroundWindow")
|
|
procFlashWindowEx = user32Window.NewProc("FlashWindowEx")
|
|
procMessageBeep = user32Window.NewProc("MessageBeep")
|
|
)
|
|
|
|
const (
|
|
swRestore = 9
|
|
)
|
|
|
|
type flashwinfo struct {
|
|
cbSize uint32
|
|
hwnd uintptr
|
|
dwFlags uint32
|
|
uCount uint32
|
|
dwTimeout uint32
|
|
}
|
|
|
|
// ActivateAppWindow — đưa cửa sổ app lên trước + nhấp nháy taskbar
|
|
func ActivateAppWindow(titleHint string) {
|
|
hwnd := findWindowByTitleContains(titleHint)
|
|
if hwnd == 0 {
|
|
return
|
|
}
|
|
_, _, _ = procShowWindow.Call(hwnd, swRestore)
|
|
_, _, _ = procSetForegroundWindow.Call(hwnd)
|
|
var fi flashwinfo
|
|
fi.cbSize = uint32(unsafe.Sizeof(fi))
|
|
fi.hwnd = hwnd
|
|
fi.dwFlags = 0x0000000E // FLASHW_ALL | FLASHW_TIMERNOFG
|
|
fi.uCount = 4
|
|
fi.dwTimeout = 0
|
|
_, _, _ = procFlashWindowEx.Call(uintptr(unsafe.Pointer(&fi)))
|
|
}
|
|
|
|
// PlayNotifySound — beep hệ thống Windows (không phụ thuộc autoplay trình duyệt)
|
|
func PlayNotifySound() {
|
|
_, _, _ = procMessageBeep.Call(0x00000040) // MB_ICONASTERISK
|
|
time.Sleep(120 * time.Millisecond)
|
|
_, _, _ = procMessageBeep.Call(0xFFFFFFFF) // MB_OK
|
|
}
|
|
|
|
var enumTargetTitle string
|
|
var enumFoundHwnd uintptr
|
|
|
|
var enumWindowsCallback = syscall.NewCallback(func(hwnd uintptr, lParam uintptr) uintptr {
|
|
ret, _, _ := procIsWindowVisible.Call(hwnd)
|
|
if ret == 0 {
|
|
return 1
|
|
}
|
|
buf := make([]uint16, 256)
|
|
_, _, _ = procGetWindowTextW.Call(hwnd, uintptr(unsafe.Pointer(&buf[0])), 256)
|
|
title := syscall.UTF16ToString(buf)
|
|
if title != "" && strings.Contains(strings.ToLower(title), strings.ToLower(enumTargetTitle)) {
|
|
enumFoundHwnd = hwnd
|
|
return 0
|
|
}
|
|
return 1
|
|
})
|
|
|
|
func findWindowByTitleContains(hint string) uintptr {
|
|
if hint == "" {
|
|
return 0
|
|
}
|
|
titlePtr, _ := syscall.UTF16PtrFromString(hint)
|
|
hwnd, _, _ := procFindWindowW.Call(0, uintptr(unsafe.Pointer(titlePtr)))
|
|
if hwnd != 0 {
|
|
return hwnd
|
|
}
|
|
enumTargetTitle = hint
|
|
enumFoundHwnd = 0
|
|
_, _, _ = procEnumWindows.Call(enumWindowsCallback, 0)
|
|
return enumFoundHwnd
|
|
}
|