发布时间:2024-12-23 05:48:11
Golang是一种目前非常流行的编程语言,也被广泛应用于Windows应用程序开发。在Golang中,我们可以使用一系列的库和方法来操作Win窗口,从而实现各种功能和交互。本文将介绍一些常用的Golang对Win窗口的操作方式。
要操作窗口,首先需要获取其句柄,即handle。在Golang中,我们可以使用`user32`库中的`FindWindow`函数来获取指定窗口标题或类名的句柄。
import (
"fmt"
"syscall"
"unsafe"
)
const (
MAX_PATH = 260
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
procGetModuleHandle = kernel32.MustFindProc("GetModuleHandleW")
user32 = syscall.MustLoadDLL("user32.dll")
procFindWindow = user32.MustFindProc("FindWindowW")
)
func GetWindowHandle(windowTitle string) (syscall.Handle, error) {
ret, _, err := procFindWindow.Call(0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(windowTitle))), 0)
if ret == 0 {
return 0, fmt.Errorf("failed to find window: %v", err)
}
return syscall.Handle(ret), nil
}
func main() {
hwnd, err := GetWindowHandle("Notepad")
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Window handle: %v\n", hwnd)
}
获取窗口句柄后,我们就可以使用`user32`库中的`SendMessage`函数向窗口发送消息。通过指定不同的消息类型和参数,我们可以实现对窗口的不同操作。
const (
WM_GETTEXT = 0x000D
WM_SETTEXT = 0x000C
WM_CLOSE = 0x0010
)
func SendMessage(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) {
user32.MustFindProc("SendMessageW").Call(
uintptr(hwnd),
uintptr(msg),
wParam,
lParam)
}
func GetWindowText(hwnd syscall.Handle) string {
buffer := make([]uint16, MAX_PATH)
user32.MustFindProc("GetWindowTextW").Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(MAX_PATH))
return syscall.UTF16ToString(buffer)
}
func SetWindowText(hwnd syscall.Handle, text string) {
user32.MustFindProc("SetWindowTextW").Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))))
}
func main() {
hwnd, err := GetWindowHandle("Notepad")
if err != nil {
fmt.Println(err)
return
}
SendMessage(hwnd, WM_SETTEXT, 0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Hello World"))))
text := GetWindowText(hwnd)
fmt.Printf("Window text: %s\n", text)
SendMessage(hwnd, WM_CLOSE, 0, 0)
}
除了直接指定窗口句柄,我们还可以使用`user32`库中的`EnumWindows`函数来枚举系统中所有的顶级窗口。配合`GetWindowText`函数和`SetWindowText`函数,我们可以对枚举的窗口进行更加灵活的操作。
type EnumInfo struct {
hwnds []syscall.Handle
keyword string
}
func EnumProc(hwnd syscall.Handle, lParam uintptr) uintptr {
enumInfo := (*EnumInfo)(unsafe.Pointer(lParam))
buffer := make([]uint16, MAX_PATH)
user32.MustFindProc("GetWindowTextW").Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(MAX_PATH))
text := syscall.UTF16ToString(buffer)
if strings.Contains(text, enumInfo.keyword) {
enumInfo.hwnds = append(enumInfo.hwnds, hwnd)
}
return 1
}
func EnumWindowsWithKeyword(keyword string) ([]syscall.Handle, error) {
var enumInfo EnumInfo
enumInfo.keyword = keyword
user32.MustFindProc("EnumWindows").Call(
uintptr(syscall.NewCallback(EnumProc)),
uintptr(unsafe.Pointer(&enumInfo)))
if len(enumInfo.hwnds) == 0 {
return nil, fmt.Errorf("failed to find windows with keyword: %s", keyword)
}
return enumInfo.hwnds, nil
}
func main() {
hwnds, err := EnumWindowsWithKeyword("Notepad")
if err != nil {
fmt.Println(err)
return
}
for _, hwnd := range hwnds {
fmt.Printf("Window handle: %v\n", hwnd)
SetWindowText(hwnd, "Hello World")
text := GetWindowText(hwnd)
fmt.Printf("Window text: %s\n", text)
SendMessage(hwnd, WM_CLOSE, 0, 0)
}
}
通过以上操作,我们可以在Golang中对Windows窗口进行各种操作,包括获取窗口句柄、发送消息以及枚举窗口等。这些操作使得我们可以灵活地控制和交互Windows应用程序,从而提高了开发效率和用户体验。