基于要素(标题、父、类型、进程、控件id)获取windows窗口

来源:互联网 发布:scp基金会知乎 编辑:程序博客网 时间:2024/06/05 01:09

 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

当我们使用spy++查看窗体的信息时,会看到许多窗体的要素信息,其中比较典型的如下几个:

     参考父窗体
     参考标题
     参考类名称
     参考ProcID
     参考控件ID

基于这些信息,我们通常可以唯一确定一个窗口,基于此,代码中我们也可以通过这些要素找窗体,从而事项对程序的模拟操作。


下面是一个代码实现,基于这几个要素获取窗体选中的窗体

头文件中

// 检查选项    enum EnumWndCheckOption    {        enumUseParent     = 0x1,        // 检查父图元        enumUseTitle      = 0x2,        // 检查标题        enumUseClass      = 0x4,        // 检查类名称        enumUseProcID     = 0x8,        // 检查进程ID        enumUseControlID  = 0xF         // 检查控件ID    };    // 检查输入信息    struct WindowsCheckInfo    {        DWORD dwCheckOption;        // 检查选项,参见EnumWndCheckOption定义        HWND hParentWnd;            // 父窗体,为NULL时不检查        CStringArray sTitleKeys;    // 标题需要包含的内容,为空时不检查        CString sClassName;         // 类名称,为空时不检查        DWORD dwProcID;             // 进程ID,为-1时不检查        DWORD dwControlID;          // 控件ID,为-1时不检查        WindowsCheckInfo()            : dwCheckOption(0)            , dwProcID(-1)            , dwControlID(-1)        {        }    };    static HWND GetWndByCheckInfo(WindowsCheckInfo& info);

cpp的实现

HWND CSendMessage::GetWndByCheckInfo(WindowsCheckInfo& info){    // 获取首个检查窗口    HWND hCheckWnd = nullptr;    if ((info.dwCheckOption & enumUseParent) == enumUseParent && info.hParentWnd != NULL)    {        hCheckWnd = ::GetWindow(info.hParentWnd, GW_CHILD);;    }    else    {        hCheckWnd = ::GetTopWindow(0);    }    // 逐个遍历窗口    for (; hCheckWnd != NULL; hCheckWnd = ::GetNextWindow(hCheckWnd , GW_HWNDNEXT))    {        // 检查ProcID        if ((info.dwCheckOption & enumUseProcID) == enumUseProcID && info.dwProcID != -1)        {            DWORD dwWndPid = 0;            ::GetWindowThreadProcessId(hCheckWnd, &dwWndPid);            if (info.dwProcID != dwWndPid)            {                continue;            }        }                // 检查标题是否满足        if ((info.dwCheckOption & enumUseTitle) == enumUseTitle && !info.sTitleKeys.IsEmpty())        {            CString sWndTitle;            ::GetWindowText(hCheckWnd, sWndTitle.GetBuffer(c_nMaxStrLen), c_nMaxStrLen);            bool bAllTitleKeySatify = true;            for (int i=0; i<info.sTitleKeys.GetCount(); i++)            {                if (sWndTitle.Find(info.sTitleKeys[i]) == -1)                {                    bAllTitleKeySatify = false;                    break;                }            }            if (!bAllTitleKeySatify)            {                continue;            }        }        // 检查Class是否满足        if ((info.dwCheckOption & enumUseClass) == enumUseClass && !info.sClassName.IsEmpty())        {            // 获取类名            CString sWndClassName;            if (GetClassName(hCheckWnd, sWndClassName.GetBuffer(c_nMaxStrLen), c_nMaxStrLen) != 0)            {                if (_tcscmp(sWndClassName, info.sClassName) != 0)                 {                    continue;                }            }        }        // 检查ControlID        if ((info.dwCheckOption & enumUseControlID) == enumUseControlID && info.dwControlID != -1)        {            if (GetDlgCtrlID(hCheckWnd) != info.dwControlID)            {                continue;            }        }        // 返回当前符合要求的窗体句柄        return hCheckWnd;            }    return NULL;}


一个使用的样例:

    HWND hSearchWnd = NULL;     {        WindowsCheckInfo info;        info.dwCheckOption = enumUseParent|enumUseControlID;        info.hParentWnd = hParentWnd;        info.dwControlID = 1026;        hSearchWnd = GetWndByCheckInfo(info);;    }



 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)


原创粉丝点击