在软件开发中,经常需要从用户界面(UI)控件中获取数据。这些控件包括树形控件(TreeCtrl)、列表控件(ListCtrl)、组合框(ComboBox)、列表框(ListBox)、标题控件(HeaderCtrl)和编辑框(Edit)等。例如,可以从Windows资源管理器中获取文件夹树形数据和文件夹列表数据,并将其转换为文本格式。
定位窗口的过程类似于Microsoft Spy++。以下是详细的使用步骤:
首先,可以使用Finder工具来定位控件或窗口。用户可以点击并拖动Finder到任何窗口,相应的窗口将会被高亮显示。此外,也可以通过窗口树(Window Tree)来定位窗口。
点击“获取数据”按钮将会从选定的窗口(控件)中捕获数据。捕获的数据可以在“获取数据”按钮下方的文本区域中选择并复制,或者直接点击“复制数据”按钮。
另外,有一个选项叫做“最小顶部”(Smallest Top),它决定了是否搜索具有最小区域的窗口。这在需要定位被分组框包围的控件时非常有用。如果没有选择这个选项,将会使用简单的WindowFromPoint API来进行搜索。
定位的窗口可以通过点击“闪烁”按钮来确认。另一种方法是右键点击窗口树(Window Tree)并选择上下文菜单中的“闪烁”。
从ListCtrl和TreeCtrl捕获的数据使用制表符(TAB)作为分隔符。这有助于轻松地管理数据,以便粘贴和在MS Word或Excel中格式化。
下面展示了一个示例图片:从Windows资源管理器中捕获了Windows\System文件夹,然后将其粘贴并格式化为MS Word中的表格。
使用“最小顶部”方法定位窗口非常有趣。首先,需要找到鼠标光标下的窗口。之后,将检查所有位于相同鼠标光标位置的该窗口的兄弟窗口的区域(宽度x高度)。从这些窗口中,将确定具有最小区域的窗口。以下是主要的代码片段:
HWND hWnd = ::WindowFromPoint(point);
CPoint pointClient(point);
// 鼠标光标位置
::ScreenToClient(hWnd, &pointClient);
HWND hWndChild = ::ChildWindowFromPoint(hWnd, pointClient);
if ((0 != hWndChild) && ::IsWindowVisible(hWndChild)) {
hWnd = hWndChild;
}
// 最小顶部窗口搜索
if (m_bFindSmallestTop) {
DWORD dwWndArea = MAXDWORD;
// 避免顶级窗口
HWND hWndParent = ::GetParent(hWnd);
if (0 != hWndParent) {
if (0 == (::GetWindowLong(hWnd, GWL_STYLE) & WS_POPUP)) {
// 遍历子窗口
HWND hWndChild = ::GetWindow(hWndParent, GW_CHILD);
while (0 != hWndChild) {
// 忽略隐藏的窗口
if (::IsWindowVisible(hWndChild)) {
// 窗口在点下
CRect rect;
::GetWindowRect(hWndChild, ▭);
if (rect.PtInRect(point)) {
// 找到最小
DWORD dwChildArea = rect.Width() * rect.Height();
if (dwChildArea < dwWndArea) {
dwWndArea = dwChildArea;
hWnd = hWndChild;
}
}
}
hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT);
}
}
}
}
class ProcMem {
public:
ProcMem(HWND hWnd);
virtual ~ProcMem();
LPVOID Allocate(DWORD dwSize);
BOOL Write(LPVOID lpProcMem, LPVOID lpLocalMem, DWORD dwSize);
BOOL Read(LPVOID lpProcMem, LPVOID lpLocalMem, DWORD dwSize);
private:
HANDLE m_hProcess;
CArray m_arrayMemoryAllocated;
};