C# 通过在C中单击获取进程窗口句柄#
目前,我可以使用C# 通过在C中单击获取进程窗口句柄#,c#,winapi,process,click,hook,C#,Winapi,Process,Click,Hook,目前,我可以使用System.Diagnostics.Process.GetProcesses()并执行一个简单的LINQ查询,在主窗口中获得正在运行的进程列表 然后,我可以导入user32.dll和SetWindowPos函数,并操作其他进程的窗口参数 好的,它起作用了。现在我想通过单击来选择一个进程的窗口,比如calc.exe。换句话说,我想获得一个进程对象(然后是MainWindowHandle),它带有一个钩子,当我点击它的窗口时,钩子会捕捉进程名称 我怎样才能做到这一点呢?我不知道如何
System.Diagnostics.Process.GetProcesses()
并执行一个简单的LINQ查询,在主窗口中获得正在运行的进程列表
然后,我可以导入user32.dll
和SetWindowPos
函数,并操作其他进程的窗口参数
好的,它起作用了。现在我想通过单击来选择一个进程的窗口,比如calc.exe。换句话说,我想获得一个进程对象(然后是MainWindowHandle),它带有一个钩子,当我点击它的窗口时,钩子会捕捉进程名称
我怎样才能做到这一点呢?我不知道如何在C#中实现这一点,但您还将此问题标记为WinAPI,以便我可以提供帮助。在WinAPI中,可以这样做:
#include <stdio.h>
#include <Windows.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
int main(void)
{
/* Hacky loop for proof of concept */
while(TRUE) {
Sleep(100);
if(GetAsyncKeyState(VK_F12)) {
break;
}
if(GetAsyncKeyState(VK_LBUTTON)) {
HWND hwndPt;
POINT pt;
if(!GetCursorPos(&pt)) {
wprintf(L"GetCursorPos failed with %d\n", GetLastError());
break;
}
if((hwndPt = WindowFromPoint(pt)) != NULL) {
DWORD dwPID;
HANDLE hProcess;
GetWindowThreadProcessId(hwndPt, &dwPID);
hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPID);
if(hProcess == NULL) {
wprintf(L"OpenProcess failed with error: %d\n", GetLastError());
} else {
wchar_t lpFileName[MAX_PATH];
DWORD dwSize = _countof(lpFileName);
QueryFullProcessImageName(hProcess, 0, lpFileName, &dwSize);
wprintf(L"%s\n", lpFileName);
CloseHandle(hProcess);
}
}
}
}
return EXIT_SUCCESS;
}
#包括
#包括
#包括
#pragma注释(lib,“Psapi.lib”)
内部主(空)
{
/*用于概念证明的Hacky循环*/
while(TRUE){
睡眠(100);
if(GetAsyncKeyState(VK_F12)){
打破
}
if(GetAsyncKeyState(VK_LBUTTON)){
HWND-hwndPt;
点pt;
如果(!GetCursorPos(&pt)){
wprintf(L“GetCursorPos失败,错误为%d\n”,GetLastError());
打破
}
如果((hwndPt=WindowFromPoint(pt))!=NULL){
德沃德·德皮德;
处理hProcess;
GetWindowThreadProcessId(hwndPt和dwPID);
HPPROCESS=OpenProcess(进程查询有限信息,FALSE,dwPID);
if(hProcess==NULL){
wprintf(L“OpenProcess失败,错误:%d\n”,GetLastError());
}否则{
wchar_t lpFileName[MAX_PATH];
DWORD dwSize=_countof(lpFileName);
QueryFullProcessImageName(hProcess、0、lpFileName和dwSize);
wprintf(L“%s\n”,lpFileName);
CloseHandle(hProcess);
}
}
}
}
返回退出成功;
}
示例结果:
在本例中,我只是轮询以获得鼠标单击。更合适的方法是使用某种windows钩子。正如Mike Kwan所说,编写钩子会更好,尽管这两种方法都有各自的缺点,但bjarneds已经在这方面做了很好的工作。看一看。它是用C#编写的,可以满足您的需要,甚至更多
您还应该注意到,使用钩子越来越多余。根据您想做什么,其他WinAPI(如
GetForegroundWindow
)可能会更好。您可能需要捕获鼠标才能接收对另一个窗口的单击。@MartinLiversage:GetAsyncKeyState
可以用于此。我在获取光标位置时遇到一些问题。我打电话给GetCursorPos,但我得到的X坐标是647208716579385E-312,Y坐标是0。发生了什么事?@MikeKwan:但如果我将鼠标指针移到另一个窗口并单击它,我的应用程序就会失去焦点,无法获得鼠标单击事件。也就是说,除非我已经捕获了鼠标。@MartinLiversage:据我所知,你不需要为GetAsyncKeyState
捕获鼠标。