win32api/user32_window_test.go
starainrt 0f82ba044b
修正 Win32 封装语义并补齐关键结构体/进程测试覆盖
- 修正 WTS 会话相关类型、枚举与活动会话选择逻辑
- 对齐 FILE_ID_DESCRIPTOR 布局与 FILE_ID_TYPE 语义,修复 OpenFileById 调用前提
- 修正 user32/shell32/kernel32 部分 API 的返回值、参数个数与错误处理
- 完善剪贴板更新格式读取的缓冲区重试逻辑
- 补充常用进程、线程、调试、桌面与会话 helper
- 增加结构体布局、会话查询、剪贴板、CreateProcess 等回归测试
- 将默认 CreateProcess 相关测试切到 helper 进程,并保留显式开启的 cmd.exe 集成覆盖
2026-06-06 17:46:02 +08:00

130 lines
3.6 KiB
Go

//go:build windows
package win32api
import (
"syscall"
"testing"
)
func TestDesktopWindowAndThreadProcess(t *testing.T) {
desktop := GetDesktopWindow()
if desktop == 0 {
t.Fatal("GetDesktopWindow returned 0")
}
threadID, processID, err := GetWindowThreadProcessId(desktop)
if err != nil {
t.Fatalf("GetWindowThreadProcessId(desktop) failed: %v", err)
}
if threadID == 0 {
t.Fatal("GetWindowThreadProcessId(desktop) threadID is 0")
}
if processID == 0 {
t.Fatal("GetWindowThreadProcessId(desktop) processID is 0")
}
if _, err := GetWindowText(desktop); err != nil {
t.Fatalf("GetWindowText(desktop) failed: %v", err)
}
}
func TestShellAndForegroundWindow(t *testing.T) {
shell := GetShellWindow()
if shell != 0 {
if _, _, err := GetWindowThreadProcessId(shell); err != nil {
t.Fatalf("GetWindowThreadProcessId(shell) failed: %v", err)
}
if _, err := GetWindowText(shell); err != nil {
t.Fatalf("GetWindowText(shell) failed: %v", err)
}
}
fg := GetForegroundWindow()
if fg != 0 {
if _, _, err := GetWindowThreadProcessId(fg); err != nil {
t.Fatalf("GetWindowThreadProcessId(foreground) failed: %v", err)
}
if _, err := GetWindowText(fg); err != nil {
t.Fatalf("GetWindowText(foreground) failed: %v", err)
}
}
}
func TestOpenInputDesktopAndSwitch(t *testing.T) {
desk, err := OpenInputDesktop(0, false, DESKTOP_READOBJECTS|DESKTOP_SWITCHDESKTOP)
if err != nil {
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED {
t.Skipf("OpenInputDesktop access denied in current context: %v", err)
}
t.Fatalf("OpenInputDesktop failed: %v", err)
}
defer func() {
_ = CloseDesktop(desk)
}()
if err := SwitchDesktop(desk); err != nil {
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED {
t.Skipf("SwitchDesktop access denied in current context: %v", err)
}
t.Fatalf("SwitchDesktop failed: %v", err)
}
}
func TestGetThreadDesktopAndSetCurrentDesktop(t *testing.T) {
threadID := GetCurrentThreadId()
if threadID == 0 {
t.Fatal("GetCurrentThreadId returned 0")
}
desk, err := GetThreadDesktop(threadID)
if err != nil {
t.Fatalf("GetThreadDesktop failed: %v", err)
}
if desk == 0 {
t.Fatal("GetThreadDesktop returned 0")
}
if err := SetThreadDesktop(desk); err != nil {
if errno, ok := err.(syscall.Errno); ok {
if errno == syscall.Errno(170) || errno == syscall.ERROR_ACCESS_DENIED {
t.Skipf("SetThreadDesktop is restricted in current context: %v", err)
}
}
t.Fatalf("SetThreadDesktop failed: %v", err)
}
}
func TestGetMessageReturnsNilOnPostedQuit(t *testing.T) {
PostQuitMessage(23)
var msg MSG
ret, err := GetMessage(&msg, 0, 0, 0)
if err != nil {
t.Fatalf("GetMessage returned error for WM_QUIT: %v", err)
}
if ret != 0 {
t.Fatalf("GetMessage return = %d, want 0", ret)
}
if msg.Message != WM_QUIT {
t.Fatalf("message = %#x, want WM_QUIT", msg.Message)
}
if msg.WParam != 23 {
t.Fatalf("WM_QUIT exit code = %d, want 23", msg.WParam)
}
}
func TestUser32BoolWrappersReturnErrors(t *testing.T) {
if ok, err := AddClipboardFormatListener(0); err == nil || ok {
t.Fatalf("AddClipboardFormatListener(0) = (%v, %v), want failure with error", ok, err)
}
if ok, err := RemoveClipboardFormatListener(0); err == nil || ok {
t.Fatalf("RemoveClipboardFormatListener(0) = (%v, %v), want failure with error", ok, err)
}
if ok, err := DestroyWindow(0); err == nil || ok {
t.Fatalf("DestroyWindow(0) = (%v, %v), want failure with error", ok, err)
}
if ok, err := PostMessage(HWND(1), WM_USER, 0, 0); err == nil || ok {
t.Fatalf("PostMessage(invalid) = (%v, %v), want failure with error", ok, err)
}
}