您的位置:首页 > 其它

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

2017-08-17 20:42 1006 查看
 (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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: