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);
展开
 我来答
getborn
2008-07-19 · TA获得超过964个赞
知道小有建树答主
回答量:337
采纳率:0%
帮助的人:458万
展开全部
强制转换是肯定不行的,我想了个笨方法。在获得某进程的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);
}
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
zjk_1986
2008-07-12 · 超过15用户采纳过TA的回答
知道答主
回答量:218
采纳率:0%
帮助的人:72.2万
展开全部
不会,谢谢你的两份
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式