如何管理使用Win32 API打开的应用程序的窗口记事本,Word,Outlook,Chrome等

问题描述

我们如何管理使用Win32 api运行的应用程序的wndproc函数?我使用的软件语言是Go。

我尝试了不止一种方法,但无法做到。你能帮忙吗?

I am learning the HANDLE (HWND) value of notepad application with Microsoft Spy ++

Then I watch the changes on Notepad ++ over SPY ++.

就像使用Spy ++一样,请帮助我管理我编写的自定义WNPROC函数

func main() {

    hwnd := w32.HWND(3736818)
    go SetwindowLongTest(w32.HWND(hwnd))
    time.Sleep(99999 * time.Second)
}


func SetwindowLongTest(hwnd w32.HWND) {
    result,err := win.SetwindowLongPtr(win.HWND(hwnd),win.GWL_WNDPROC,syscall.NewCallback(MyNewWndProc))
    if err != nil {
        fmt.Println("SetwindowLongPtr",err)
    }
    fmt.Println(result)
}



func MyNewWndProc(hwnd w32.HWND,uMsg uint,wParam w32.WParaM,lParam w32.LParaM) uintptr {
    fmt.Println(uMsg)
    fmt.Println("myNewWndProc",hwnd)
    return 0
}

  Result: 
    PS C:\Users\Cingozr\go\src> go run .\main.go
    SetwindowLongPtr Access is denied.
    0

方法2:

func main() {

    hwnd := w32.HWND(3736818)
    go SetClassLongTest(w32.HWND(hwnd))
    time.Sleep(99999 * time.Second)
}

func SetClassLongTest(hwnd w32.HWND) {
    result,err := w32.SetClassLongPtrW(hwnd,-24,syscall.NewCallback(MyNewWndProc))
    if err != nil {
        fmt.Println("SetClassLongPtrW Err",err)
    }
    fmt.Println("SetClassLongPtrW",result)

}

func MyNewWndProc(hwnd w32.HWND,hwnd)
    return 0
}

Result:
PS C:\Users\Cingozr\go\src> go run .\main.go
SetClassLongPtrW Err Access is denied.
SetClassLongPtrW 0

解决方法

答案是您不能用SetWindowLongPtr替换窗口过程跨进程,并且 SetClassLongPtr

使用索引currentSize 调用SetWindowLongPtr创建一个 窗口类的子类,用于创建窗口。一个 应用程序可以子类化系统类,但不能子类化 另一个进程创建的窗口类

使用索引GWLP_WNDPROC 调用SetClassLongPtr创建一个 窗口类的子类,随后会影响所有窗口 用该类创建的。应用程序可以将系统类子类化, 但不应子类化由另一个进程创建的窗口类

此外,SetWindowLongPtr的hwnd参数还具有UIPI限制:

如果 SetWindowLongPtr 函数拥有 由hWnd参数指定的窗口处于更高的过程 UIPI层次结构中的特权比进程调用线程的特权 居住在。

Windows XP / 2000::如果出现窗口, SetWindowLongPtr 函数将失败 由hWnd参数指定的进程与以下进程不属于同一进程 调用线程。

如果要监视窗口消息,建议使用SetWindowsHookEx。 您可以阅读以下文档:Using Hooks

您也可以create your own window,使用相同的GCLP_WNDPROC(目标窗口中的GetClassLongPtr)和样式(目标窗口中的GetWindowLongPtr)。

或者您已经知道自己在做什么,请尝试dll注入。