我使用此代码获取窗口名称:
#include <Windows.h>
#include <stdio.h>
int main() {
TCHAR title[500];
int i=0;
while(i<10) {
GetWindowText(GetForegroundWindow(), title, 500);
printf("%s\n",title);
i++;
system("pause");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,它只获得前景窗口.
我需要获取所有窗口名称
或者,实际上,我需要获取属于"notepad.exe"进程的一个特定窗口名称.
谢谢你的帮助 :)
我不认为使用原始winapi有任何更简单的方法,但是这里有:
这是我提出的代码:
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <tlhelp32.h>
bool isNotepad(const PROCESSENTRY32W &entry) {
return std::wstring(entry.szExeFile) == L"notepad.exe";
}
BOOL CALLBACK enumWindowsProc(HWND hwnd, LPARAM lParam) {
const auto &pids = *reinterpret_cast<std::vector<DWORD>*>(lParam);
DWORD winId;
GetWindowThreadProcessId(hwnd, &winId);
for (DWORD pid : pids) {
if (winId == pid) {
std::wstring title(GetWindowTextLength(hwnd) + 1, L'\0');
GetWindowTextW(hwnd, &title[0], title.size()); //note: C++11 only
std::cout << "Found window:\n";
std::cout << "Process ID: " << pid << '\n';
std::wcout << "Title: " << title << "\n\n";
}
}
return TRUE;
}
int main() {
std::vector<DWORD> pids;
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W entry;
entry.dwSize = sizeof entry;
if (!Process32FirstW(snap, &entry)) {
return 0;
}
do {
if (isNotepad(entry)) {
pids.emplace_back(entry.th32ProcessID);
}
} while (Process32NextW(snap, &entry));
EnumWindows(enumWindowsProc, reinterpret_cast<LPARAM>(&pids));
}
Run Code Online (Sandbox Code Playgroud)
顺序完成:
首先注意函数和字符串的宽泛版本.TCHAR不好用,如果其中一个标题碰巧有UTF-16,那将是一种耻辱.
isNotepad只检查结构的可执行文件名成员,PROCESSENTRY32W看它是否等于"notepad.exe".这假设记事本使用此进程名称,并且没有任何非记事本使用进程名称.为了消除误报,你必须做更多的检查,但你永远不能确定.
在enumWindowsProc,请注意,lParam它实际上是指向PID向量的指针(以避免必须使用全局).这构成了函数开头的演员表.接下来,我们得到我们找到的窗口的PID.然后,我们遍历传入的PID列表并检查它是否与任何匹配.如果是这样,我选择获取标题并输出PID和窗口标题.请注意,使用标准字符串作为缓冲区只能保证在C++ 11中工作,并且不能覆盖额外的空字符(不是长度的一部分).最后,我们返回,TRUE以便它一直枚举,直到它通过每个顶级窗口.
到main,你首先看到的是我们最初为空的PID的列表.我们对流程进行快照并完成它们.我们使用辅助函数isNotepad来检查进程是否为"notepad.exe",如果是,则存储其PID.最后,我们调用EnumWindows枚举窗口,并传递PID列表,伪装成必需的LPARAM.
如果你没有做过这类事情,这有点棘手,但我希望这是有道理的.如果你想要子窗口,那么正确的做法就是在我输出有关找到的窗口的信息的地方添加一个EnumChildWindowsProc并调用EnumChildWindows它.如果我是正确的,你不需要递归调用EnumChildWindows以获得孙子等,因为它们将包含在第一次调用中.