2023-06-11  2024-09-18    233 字  1 分钟

将窗口标题中带有指定字符串的窗口置顶,使其显示在所有窗口之上

 1package main
 2
 3import (
 4	"golang.org/x/sys/windows"
 5	"strings"
 6	"syscall"
 7	"unsafe"
 8)
 9
10func AlwaysOnTop() {
11	SetWindowAlwaysOnTop(GetWindowHandleByWindowName("Title"))
12}
13
14const SWP_NOSIZE = uintptr(0x0001)
15const SWP_NOMOVE = uintptr(0x0002)
16
17// This is dumb but Go doesn't like the inline conversion (see above image).
18func IntToUintptr(value int) uintptr {
19	return uintptr(value)
20}
21
22func SetWindowAlwaysOnTop(hwnd uintptr) {
23	user32dll := windows.MustLoadDLL("user32.dll")
24	setwindowpos := user32dll.MustFindProc("SetWindowPos")
25	setwindowpos.Call(hwnd, IntToUintptr(-1), 0, 0, 100, 100, SWP_NOSIZE|SWP_NOMOVE)
26}
27
28func GetWindowHandleByWindowName(window_name string) uintptr {
29	user32dll := windows.MustLoadDLL("user32.dll")
30	enumwindows := user32dll.MustFindProc("EnumWindows")
31
32	var the_handle uintptr
33	window_byte_name := []byte(window_name)
34
35	// Windows will loop over this function for each window.
36	wndenumproc_function := syscall.NewCallback(func(hwnd uintptr, lparam uintptr) uintptr {
37		// Allocate 100 characters so that it has something to write to.
38		var filename_data [100]uint16
39		max_chars := uintptr(100)
40
41		getwindowtextw := user32dll.MustFindProc("GetWindowTextW")
42		getwindowtextw.Call(hwnd, uintptr(unsafe.Pointer(&filename_data)), max_chars)
43
44		// If there's a match, save the value and return 0 to stop the iteration.
45		if strings.Contains(string(windows.UTF16ToString([]uint16(filename_data[:]))), string(window_byte_name)) {
46			the_handle = hwnd
47			return 0
48		}
49
50		return 1
51	})
52
53	// Call the above looping function.
54	enumwindows.Call(wndenumproc_function, uintptr(0))
55
56	return the_handle
57}

除另有声明外本博客文章均采用 知识共享 (Creative Commons) 署名 4.0 国际许可协议 进行许可转载请注明原作者与文章出处