tam add chat

This commit is contained in:
2026-06-30 10:53:51 +07:00
parent 6e284e66fa
commit dc86524ff0
6 changed files with 298 additions and 176 deletions

View File

@@ -0,0 +1,91 @@
//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
}