VC怎么通过进程ID得到窗口句柄
我试过网上的好多办法,到我这都不管用,气之又气..我通过CreateToolhelp32Snapshot来枚举所有进程,接下来再通过Process32First以及Pro...
我试过网上的好多办法,到我这都不管用,气之又气..
我通过CreateToolhelp32Snapshot 来枚举所有进程,接下来再通过Process32First以及Process32Next查看我想要的进程名,进程ID,得到进程ID后再通过OpenProcess函数得到了一个句柄,是HANDEL的,我想要的是HWND窗口句柄,进行强制转换是不可以的,用强制转换后的句柄去操作另外一个进程调用GetWindowText和SetWindowText失败,Get的是空,在GetLastError中的提示是无效句柄,我试过好多办法了都不行(包括SendMessage)..
先说一下我的目的 我是想通过进程句得到窗口句柄,然后改窗口标题名的,条件,在本进程内操作的是其他的进程...
下面是我代码,请大家帮帮忙,看该怎么弄,这里先谢谢了....
HANDLE hProcessSnap = NULL;
HWND h_test;
PROCESSENTRY32 pe32 = {0};
BOOL exist = false;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
// Fill in the size of the structure before using it
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap,&pe32))
{
do
{
if(strcmp("notepad.exe",pe32.szExeFile)==0)
{
//这里这样强制转换后下面的句柄好像都是错的,不知道得到窗口句柄这步该怎么弄了...
h_test = (HWND)OpenProcess(PROCESS_ALL_ACCESS,0,pe32.th32ProcessID);
//下面的三行是测试用,看是否能得到窗口标题
//TCHAR temp[255];
//::GetWindowText(h_test,temp,sizeof(temp)/sizeof(TCHAR));
//MessageBox(temp); //这一步弹出来的信息总是一堆"烫"..
//以下代码是显示错误信息的.
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Process any inserts in lpMsgBuf.
// ...
// Display the string.
MessageBox((LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
//设置窗口标题
if(!::SetWindowText(h_test,"ele1")) //此处我用了SendMessage发WM_SETTEXT消息也没有成功...
{
MessageBox("窗口标题设置失败!!");
}
else
{
MessageBox("成功!!");
}
exist = true;
break;
}
} while(Process32Next(hProcessSnap,&pe32));
if(!exist)
{
MessageBox("请先开个文本!!");
}
}
CloseHandle(hProcessSnap); 展开
我通过CreateToolhelp32Snapshot 来枚举所有进程,接下来再通过Process32First以及Process32Next查看我想要的进程名,进程ID,得到进程ID后再通过OpenProcess函数得到了一个句柄,是HANDEL的,我想要的是HWND窗口句柄,进行强制转换是不可以的,用强制转换后的句柄去操作另外一个进程调用GetWindowText和SetWindowText失败,Get的是空,在GetLastError中的提示是无效句柄,我试过好多办法了都不行(包括SendMessage)..
先说一下我的目的 我是想通过进程句得到窗口句柄,然后改窗口标题名的,条件,在本进程内操作的是其他的进程...
下面是我代码,请大家帮帮忙,看该怎么弄,这里先谢谢了....
HANDLE hProcessSnap = NULL;
HWND h_test;
PROCESSENTRY32 pe32 = {0};
BOOL exist = false;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
// Fill in the size of the structure before using it
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap,&pe32))
{
do
{
if(strcmp("notepad.exe",pe32.szExeFile)==0)
{
//这里这样强制转换后下面的句柄好像都是错的,不知道得到窗口句柄这步该怎么弄了...
h_test = (HWND)OpenProcess(PROCESS_ALL_ACCESS,0,pe32.th32ProcessID);
//下面的三行是测试用,看是否能得到窗口标题
//TCHAR temp[255];
//::GetWindowText(h_test,temp,sizeof(temp)/sizeof(TCHAR));
//MessageBox(temp); //这一步弹出来的信息总是一堆"烫"..
//以下代码是显示错误信息的.
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Process any inserts in lpMsgBuf.
// ...
// Display the string.
MessageBox((LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
//设置窗口标题
if(!::SetWindowText(h_test,"ele1")) //此处我用了SendMessage发WM_SETTEXT消息也没有成功...
{
MessageBox("窗口标题设置失败!!");
}
else
{
MessageBox("成功!!");
}
exist = true;
break;
}
} while(Process32Next(hProcessSnap,&pe32));
if(!exist)
{
MessageBox("请先开个文本!!");
}
}
CloseHandle(hProcessSnap); 展开
2个回答
展开全部
强制转换是肯定不行的,我想了个笨方法。在获得某进程的Id后,获取桌面上每个窗口的进程Id,再与先获得的进程Id进行比较,然后就能知道哪个窗口属于哪个进程的了。
另外网上找的一篇文章:http://www.vckbase.com/document/viewdoc/?id=404
下面是我弄的笨方法,将记事本的标题改为123,在MFC下编译通过:
void ChangeTitle()
{
// 需要修改的进程名
CString strFind = L"notepad.exe";
// 替换的文字
CString strReplace = L"123";
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
DWORD m_dwProcessId;
// 获得句柄
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == (HANDLE)-1)
{
printf("\nCreateToolhelp32Snapshot()failed:%d",GetLastError());
return;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
// 列举所有进程名称
if (Process32First(hProcessSnap, &pe32))
{
do
{
CString str;
str.Format(L"%s",pe32.szExeFile);
// 找到需要修改的进程的Id
if(str == strFind)
{
m_dwProcessId = pe32.th32ProcessID;
}
}
while (Process32Next(hProcessSnap, &pe32));
}
else
{
printf("\nProcess32Firstt() failed:%d",GetLastError());
}
// 关闭句柄
CloseHandle (hProcessSnap);
////////////////////////////
HWND hwnd = ::FindWindow(L"Shell_TrayWnd",NULL);
if (hwnd)
{
hwnd = ::FindWindowEx(hwnd,NULL,L"ReBarWindow32",NULL);
if (hwnd)
{
hwnd = ::FindWindowEx(hwnd,NULL,L"MSTaskSwWClass",NULL);
if (hwnd)
{
hwnd = ::FindWindowEx(hwnd,NULL,L"ToolbarWindow32",NULL);
}
}
}
if (!hwnd)
{
AfxMessageBox(L"Find Window Error");
return;
}
// 获取任务栏按钮数量
int nCount = ::SendMessage(hwnd,TB_BUTTONCOUNT,0,0);
CString str;
str.Format(L"%u",nCount);
m_editX.SetWindowText(str);
// 分配内存
DWORD dwProcessId;
// 获取任务栏的进程Id
DWORD hThread = ::GetWindowThreadProcessId(hwnd, &dwProcessId);
// 打开任务栏的进程(Explorer)
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessId);
// 在任务栏的进程空间分配内存
HANDLE hMem = VirtualAllocEx(hProcess,NULL,0x1000,MEM_COMMIT,PAGE_READWRITE);
if (hMem == NULL)
{
AfxMessageBox(L"Memory alloc error.");
return;
}
WCHAR sz[600];
for(int i = 0; i < nCount; i++)
{
// 获取按钮信息
::SendMessage(hwnd,TB_GETBUTTON,i,(LPARAM)hMem);
TBBUTTON tb;
SIZE_T nByteRead = 0;
::ReadProcessMemory(hProcess,hMem,&tb,sizeof(tb),&nByteRead);
// 由得到的按钮Id获取按钮文字
::SendMessage(hwnd,TB_GETBUTTONTEXT,tb.idCommand,(LPARAM)hMem);
::ReadProcessMemory(hProcess,hMem,sz,sizeof(WCHAR) * 600,&nByteRead);
str.Format(L"%s",sz);
HWND hwndFind = ::FindWindow(NULL, str);
::GetWindowThreadProcessId(hwndFind, &dwProcessId);
if(dwProcessId == m_dwProcessId)
{
::SetWindowText(hwndFind,strReplace);
}
}
::VirtualFreeEx(hProcess,hMem,NULL,MEM_RELEASE);
::CloseHandle(hProcess);
}
另外网上找的一篇文章:http://www.vckbase.com/document/viewdoc/?id=404
下面是我弄的笨方法,将记事本的标题改为123,在MFC下编译通过:
void ChangeTitle()
{
// 需要修改的进程名
CString strFind = L"notepad.exe";
// 替换的文字
CString strReplace = L"123";
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
DWORD m_dwProcessId;
// 获得句柄
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == (HANDLE)-1)
{
printf("\nCreateToolhelp32Snapshot()failed:%d",GetLastError());
return;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
// 列举所有进程名称
if (Process32First(hProcessSnap, &pe32))
{
do
{
CString str;
str.Format(L"%s",pe32.szExeFile);
// 找到需要修改的进程的Id
if(str == strFind)
{
m_dwProcessId = pe32.th32ProcessID;
}
}
while (Process32Next(hProcessSnap, &pe32));
}
else
{
printf("\nProcess32Firstt() failed:%d",GetLastError());
}
// 关闭句柄
CloseHandle (hProcessSnap);
////////////////////////////
HWND hwnd = ::FindWindow(L"Shell_TrayWnd",NULL);
if (hwnd)
{
hwnd = ::FindWindowEx(hwnd,NULL,L"ReBarWindow32",NULL);
if (hwnd)
{
hwnd = ::FindWindowEx(hwnd,NULL,L"MSTaskSwWClass",NULL);
if (hwnd)
{
hwnd = ::FindWindowEx(hwnd,NULL,L"ToolbarWindow32",NULL);
}
}
}
if (!hwnd)
{
AfxMessageBox(L"Find Window Error");
return;
}
// 获取任务栏按钮数量
int nCount = ::SendMessage(hwnd,TB_BUTTONCOUNT,0,0);
CString str;
str.Format(L"%u",nCount);
m_editX.SetWindowText(str);
// 分配内存
DWORD dwProcessId;
// 获取任务栏的进程Id
DWORD hThread = ::GetWindowThreadProcessId(hwnd, &dwProcessId);
// 打开任务栏的进程(Explorer)
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessId);
// 在任务栏的进程空间分配内存
HANDLE hMem = VirtualAllocEx(hProcess,NULL,0x1000,MEM_COMMIT,PAGE_READWRITE);
if (hMem == NULL)
{
AfxMessageBox(L"Memory alloc error.");
return;
}
WCHAR sz[600];
for(int i = 0; i < nCount; i++)
{
// 获取按钮信息
::SendMessage(hwnd,TB_GETBUTTON,i,(LPARAM)hMem);
TBBUTTON tb;
SIZE_T nByteRead = 0;
::ReadProcessMemory(hProcess,hMem,&tb,sizeof(tb),&nByteRead);
// 由得到的按钮Id获取按钮文字
::SendMessage(hwnd,TB_GETBUTTONTEXT,tb.idCommand,(LPARAM)hMem);
::ReadProcessMemory(hProcess,hMem,sz,sizeof(WCHAR) * 600,&nByteRead);
str.Format(L"%s",sz);
HWND hwndFind = ::FindWindow(NULL, str);
::GetWindowThreadProcessId(hwndFind, &dwProcessId);
if(dwProcessId == m_dwProcessId)
{
::SetWindowText(hwndFind,strReplace);
}
}
::VirtualFreeEx(hProcess,hMem,NULL,MEM_RELEASE);
::CloseHandle(hProcess);
}
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询