python中获取子窗口的句柄

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python中获取子窗口的句柄相关的知识,希望对你有一定的参考价值。

请教大神

一个问题,帮个忙
就是在IE上面,我打开一个网页会弹出域登录框

我用spy++获取到了句柄信息

我想通过python中的win32的包,来查找到E

dit类型的句柄,比如我选定的那个窗口。
我可以获取到DirectUIHWND类型的句柄,但是它了子窗口的类型和标题值都一样,不太好获取到。
python的win32中没有获取所有的子窗口句柄的方法,也没有获取下一个窗口句柄的方法。
求大神指点下

参考技术A 可以使用win32gui 以及pyhook 库来实现你的需求 参考技术B 获取目前窗口的层次,对于获取此窗口中指定的子窗口的句柄有非常重要的意义。此部分功能Pyspy++是无法提供的,因为它只提供一个子窗口,所以无法获得目前窗口的层次
例如我想获得OG2263登录界面的窗口层次方法如下:
使用1)中的方法将查找图标拖到登录界面的”windows安全”位置如【图8】,Spy++可以找到所有属于此登录界面的子窗口如【图8】

【图8】
可以根据1)中的方法找到你希望定位的子窗口,例如我希望定位的子窗口为”用户名”和”密码”此两个窗口。使用
首先需要搞清楚这些子窗口之前的关系。
第一层为此窗口的窗体:即窗口名称为0002029A “Windows安全”#32770(对话框)
第二层为此窗体下第一层的窗口,即打开第一层窗体的”+”号后的第一层:即名称为 0002029C”” Direct UIHWND
第三层为第二层下的窗口,即打开第二层窗体的”+”号后的第一层,即上述窗口下有8个平行的窗口均为第三层窗口
第四层为第三层下的窗口,即打开第三层窗体的”+”号后的第一层,即第7个窗口打开后窗体,名称为0003A28 “”Edit
然后了解这些窗口是如何编号的

|-0002029A “Windows安全”#32770(对话框) ->index 无任何
编号
|- 0002029C”” Direct UIHWND ->Index为0
|-窗口1 ->index 为0
|-窗口2 ->index为1
|-窗口3 ->index 为2
|-窗口4 ->index为3
|-窗口5 ->index为4
|-窗口6 ->index为5
|-窗口7 ->index为6
|-Edit1 ->index为0
|-窗口8 ->index为7
|-Edit2 ->index为0

然后使用以下两个函数:

windows 下在进程中使用createprocess创建一个窗口进程,并获取这个窗口HWND句柄

windows 下在一个进程中使用createprocess创建一个窗口进程,并获取这个窗口的HWND句柄

C++使用createprocess创建一个窗口进程,并获取这个窗口的HWND句柄。

主要思路是:

  1. 定义getDwProcessId函数,用于监听创建子窗口的活动。
  2. 定义EnumWindowsProcGetWndTitle回调函数,用于捕获子窗口句柄。
  3. 把捕获的句柄赋值给全局变量,用于主函数执行子窗口操作。

图例如下:

技术图片

示例如下:

  1. 程序入口点代码

    ```c++
    //zhaoanan 
    #pragma warning (disable : 4786)
    #include "stdafx.h"
    #include <stdlib.h>
    #include <winsock2.h>
    #include <iostream>
    #include <vector>
    #include <string>
    #include <fstream>
    #include <stdio.h>
    #include <windows.h>
    #include "RemoteCompileSFunc.h"
    
    #pragma comment(lib, "Kernel32.lib")
    using namespace std;
    
    #define RECEIVE_BUFFER_LEN 50
    
    #pragma comment(lib,"ws2_32.lib")
    
    void Build80Zc(const string& sExe, const string& sPath, const string& sCmd);
    BOOL CALLBACK EnumWindowsProcGetWndTitle(HWND hWnd, LPARAM lParam);
    DWORD getDwProcessId(DWORD g_dwProcessId);
    HWND g_hWnd = NULL;
    int main(int argc, char* argv[])
    {
       //执行make clean ab命令
       Build80Zc("C:\WindRiver3\wrenv.exe -p vxworks-cert-6.6.3.1", "cd C:\src\workspace\FAO_ZC_VXW_AB_TEST\cert", "make clean >> C:\src\workspace\FAO_ZC_VXW_AB_TEST\compile.txt");
       //执行make all ab命令
       Build80Zc("C:\WindRiver3\wrenv.exe -p vxworks-cert-6.6.3.1", "cd C:\src\workspace\FAO_ZC_VXW_AB_TEST\cert", "make all >> C:\src\workspace\FAO_ZC_VXW_AB_TEST\compile.txt");
       //执行make clean c命令
       Build80Zc("C:\WindRiver\wrenv.exe -p vxworks-6.9","cd C:\src\workspace\dtsApp\SIMNTdiab_SMP","make clean>>C:\src\workspace\dtsApp\compile.txt");
       //执行make all c命令
    Build80Zc("C:\WindRiver\wrenv.exe -p vxworks-6.9","cd C:\src\workspace\dtsApp\SIMNTdiab_SMP","make all>>C:\src\workspace\dtsApp\compile.txt");
       return 0;
    }
    
    BOOL CALLBACK EnumWindowsProcGetWndTitle(HWND hWnd, LPARAM lParam)
    {
    DWORD ProcID = 0;
    GetWindowThreadProcessId(hWnd, &ProcID);
    cout << "传入窗口的进程id:" << lParam << "当前窗口的进程id:" << ProcID << endl;
    cout << "当前窗口句柄:" << hWnd << endl;
    if (ProcID == lParam)//如果窗口的processid等于你的ID
    {
        HWND pWnd = GetParent(hWnd);
        cout << "第一父窗口句柄:" << pWnd << endl;
        while (GetParent(pWnd) != NULL)//得到父窗口的句柄
        {
            pWnd = GetParent(pWnd);
            cout << "父窗口句柄:" << pWnd << endl;
        }
        if (pWnd != NULL) 
        {
            g_hWnd = pWnd;
        } else 
        {
            g_hWnd = hWnd;
        }
        cout << "最终父窗口句柄:" << g_hWnd << endl;
        //ok ?pWnd 就是主窗口了。
        return FALSE;
    }
    return TRUE;
    }
    
    DWORD getDwProcessId(DWORD g_dwProcessId)
    {
    int nNumberDely = 1000;
    // 等待窗口动行起,获取到窗口HWND
    while(EnumWindows(EnumWindowsProcGetWndTitle,g_dwProcessId) && nNumberDely>0 )
    {
        nNumberDely--;
    }
    return g_dwProcessId;
    }
    
    void Build80Zc(const string& sExe, const string& sPath, const string& sCmd)
    {
    string::size_type idx;
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOW;
    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));
    idx = sPath.find("FAO_ZC_VXW_AB_TEST");
    if (idx == string::npos){
        CreateProcess(NULL, "C:\WindRiver\wrenv.exe -p vxworks-6.9", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
        cout << "打开C机编译器" << endl;
    }
    else{
        CreateProcess(NULL, "C:\WindRiver3\wrenv.exe -p vxworks-cert-6.6.3.1", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
        cout << "打开AB机编译器" << endl;
    }
    Sleep(1000);
    DWORD g_dwProcessId = pi.dwProcessId;
    DWORD dwProcessId = getDwProcessId(g_dwProcessId);
       //查找当前窗口句柄需要一定的枚举时间,经过测试5s之内能枚举完成
    Sleep(5000);
    char* buf = (char*)sPath.c_str();
    int i;
    for (i = 0; i < strlen(buf); i++)
    {
        ::SendMessage(g_hWnd, WM_IME_CHAR, buf[i], 0);
    }
    ::SendMessage(g_hWnd, WM_IME_CHAR, 13, 0);
    Sleep(1000);
    buf = (char*)sCmd.c_str();
    for (i = 0; i < strlen(buf); i++)
    {
        ::SendMessage(g_hWnd, WM_IME_CHAR, buf[i], 0);
    }
    ::SendMessage(g_hWnd, WM_IME_CHAR, 13, 0);
    idx = sCmd.find("clean");
    if (idx == string::npos){
        Sleep(120000);
    }
    else{Sleep(5000); }
    const string& gaoci = "exit";
    buf = (char*)gaoci.c_str();
    for (i = 0; i < strlen(buf); i++)
    {
        ::SendMessage(g_hWnd, WM_IME_CHAR, buf[i], 0);
    }
    ::SendMessage(g_hWnd, WM_IME_CHAR, 13, 0);
    
    //终止进程
    if (pi.hProcess)
    {
        cout << "开始关闭编译器" << endl;
        DWORD dwEC = 0;
        BOOL b = GetExitCodeProcess(pi.hProcess, &dwEC);
        if (b)
        {
            if (!TerminateProcess(pi.hProcess, dwEC))
            { cout << "强行关闭编译器" << endl; }
        }
        CloseHandle(pi.hProcess);
        cout << "关闭编译器成功" << endl;
    }
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    }
    
  2. 定义getDwProcessId函数,用于监听创建子窗口的活动:

    ```c++
    //监听创建子窗口的活动
    DWORD getDwProcessId(DWORD g_dwProcessId)
    {
    int nNumberDely = 1000;
    // 等待窗口动行起,获取到窗口HWND
    while(EnumWindows(EnumWindowsProcGetWndTitle,g_dwProcessId) && nNumberDely>0 )
    {
        nNumberDely--;
    }
    return g_dwProcessId;
    }
  3. 定义EnumWindowsProcGetWndTitle回调函数,用于捕获子窗口句柄:

    ```c++
    //定义EnumWindowsProcGetWndTitle回调函数,用于捕获子窗口句柄
    BOOL CALLBACK EnumWindowsProcGetWndTitle(HWND hWnd, LPARAM lParam)
    {
    DWORD ProcID = 0;
    GetWindowThreadProcessId(hWnd, &ProcID);
    cout << "传入窗口的进程id:" << lParam << "当前窗口的进程id:" << ProcID << endl;
    cout << "当前窗口句柄:" << hWnd << endl;
    if (ProcID == lParam)//如果窗口的processid等于你的ID
    {
        HWND pWnd = GetParent(hWnd);
        cout << "第一父窗口句柄:" << pWnd << endl;
        while (GetParent(pWnd) != NULL)//得到父窗口的句柄
        {
            pWnd = GetParent(pWnd);
            cout << "父窗口句柄:" << pWnd << endl;
        }
        if (pWnd != NULL) 
        {
            g_hWnd = pWnd;
        } else 
        {
            g_hWnd = hWnd;
        }
        cout << "最终父窗口句柄:" << g_hWnd << endl;
        //ok ?pWnd 就是主窗口了。
        return FALSE;
    }
    return TRUE;
    }
  4. 参考意见和网页地址:

    1. https://blog.csdn.net/moshang005/article/details/37932455

以上是关于python中获取子窗口的句柄的主要内容,如果未能解决你的问题,请参考以下文章

主窗口中如何获取子窗口某控件句柄?

如何使用子窗口中的句柄获取父窗口的调整大小事件?

VB获取窗口句柄的详细教程

VC获取自身窗口句柄

vb2013 已获得主窗口句柄,怎么遍历所有子窗句柄到TreeView中?

.NET (C#):只有进程句柄或 PID 时获取子窗口?