如何在Windows中创建一个窗口的子类?(使用Go语言)

huangapple go评论76阅读模式
英文:

How to subclass a window in Windows? (using Go)

问题

我想要对实际窗口进行子类化,以便在其大小发生变化时进行检测。

以下是相关代码,我尝试使用CallWindowProcW和SetWindowLongW对其进行子类化,但是当我最大化窗口时没有显示任何消息,所以我猜测我可能错误地设置了其中一些过程。如何做到这一点?

var oldWindowProc uintptr

func windowProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
	switch msg {
	case WM_SIZE:
		fmt.Println("Size")
		if wparam == SIZE_MAXIMIZED {
			fmt.Println("Changed!")
		}
	default:
		return CallWindowProcW(oldWindowProc, hwnd, msg, wparam, lparam)
	}
	return 0
}

func main() {
	oldWindowProc, _ = SetWindowLongW(syscall.Stdin, GWLP_WNDPROC,
		syscall.NewCallback(windowProc))

	for {

	}
}
英文:

I want to sub-class the actual window to detect when its size has changed.

This is the code relevant where I've tried to subclassing it, using CallWindowProcW and SetWindowLongW, but it does not show any message when I maximize the window, so I'm supposed I've set wrongly some of those procedures. How to do it?

var oldWindowProc uintptr

func windowProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
	switch msg {
	case WM_SIZE:
		fmt.Println("Size")
		if wparam == SIZE_MAXIMIZED {
			fmt.Println("Changed!")
		}
	default:
		return CallWindowProcW(oldWindowProc, hwnd, msg, wparam, lparam)
	}
	return 0
}

func main() {
	oldWindowProc, _ = SetWindowLongW(syscall.Stdin, GWLP_WNDPROC,
		syscall.NewCallback(windowProc))

	for {
	
	}
}

答案1

得分: 2

我对winapi了解不多,但是你的代码似乎与go-winapi包装器的一个示例非常相似。

使用这个包装器库,这个修改后的版本对我来说似乎可以工作:

完整代码

snip

<!-- language: lang-go -->

// 窗口过程
func WndProc(hwnd winapi.HWND, msg uint32, wparam uintptr, lparam uintptr) uintptr {
	switch msg {
	case winapi.WM_SIZE:
		if wparam == SIZE_MAXIMIZED {
			fmt.Println("Changed!")
		}
	}
	// 调用原始过程
	return winapi.CallWindowProc(uintptr(oldWndProc), hwnd, msg, wparam, lparam)
}

我相信你可以查看那个包装器库并找到更直接的方法来实现它。

英文:

I don't know much about winapi, but it seems your code closely resembles an example of go-winapi wrapper

And using that wrapper lib, this modified version seems to work for me:

(Full code)

snip

<!-- language: lang-go -->

// window procedure
func WndProc(hwnd winapi.HWND, msg uint32, wparam uintptr, lparam uintptr) uintptr {
	switch msg {
	case winapi.WM_SIZE:
		if wparam == SIZE_MAXIMIZED {
			fmt.Println(&quot;Changed!&quot;)
		}
	}
	// call original procedure
	return winapi.CallWindowProc(uintptr(oldWndProc), hwnd, msg, wparam, lparam)
}

I am sure you could look at that wrapper lib and derive the more direct way of doing it.

答案2

得分: 0

你的代码写着:

SetWindowLongW(syscall.Stdin, GWLP_WNDPROC, syscall.NewCallback(windowProc))

但是为什么你把syscall.Stdin传递给SetWindowLongW呢?你不应该传递窗口句柄吗?

Alex

英文:

You code says:

SetWindowLongW(syscall.Stdin, GWLP_WNDPROC, syscall.NewCallback(windowProc))

But why are you passing syscall.Stdin to SetWindowLongW? Aren't you suppose to supply window handle instead?

Alex

huangapple
  • 本文由 发表于 2012年9月14日 04:55:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/12414669.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定