我正在尝试获取屏幕/触摸键盘的HWND-出现在屏幕底部的键盘。为此,我首先根据名称查找进程ID,然后执行EnumWindows来浏览所有窗口,并找到一个其进程ID与我所知道的进程ID相对应的窗口:
doTheThing(int pid)
{
EnumWindows(new EnumWindowsProc(Report), (IntPtr)pid);
}
protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
protected static bool Report(IntPtr hwnd, IntPtr lParam)
{
IntPtr lpdwProcessId;
GetWindowThreadProcessId(hwnd, out lpdwProcessId);
if (lpdwProcessId == lParam)
{
MessageBox.Show("True: " + hwnd.ToString());
return false;
}
return true;
}
现在Report已被调用多次,但实际上从未匹配过。如果我执行其他过程,则它可以工作,但似乎OnScreenkeyboard "System.Diagnostics.Process (WindowsInternal.ComposableShell.Experiences.TextInput.InputApp)"
不会随EnumWindows一起出现。
使用FindWindow无效,因为窗口没有标题,并且其类是通用ApplicationFrameHost。
在AHK中,我可以通过用MouseGetPos,,, WinUMID
将鼠标悬停在键盘上来获得HWND,因此肯定存在HWND。
EnumWindows是否有可能忽略某些窗口?如果是这样,我该如何预防呢?还有什么其他解决方案?
作为旁注,它也不会显示在UI Automation验证工具中。
注意:Windows现在显然有两个键盘。我的意思是您可以通过任务栏打开它。
阐明为什么我需要这个:
我有以下AHK脚本可使窗口指向半透明的窗口:
MouseGetPos,,, WinUMID
WinSet, Transparent, 100, ahk_id %WinUMID%
我注意到,当我将其指向触摸键盘上方时,它将使其透明,并且即使键盘消失,效果也将保持不变,直到重新启动系统为止。如果我保存WinUMID变量,甚至可以在不使用键盘的情况下更改透明度。
现在,我想使键盘在C#中半透明,只要我提供HWND,它就可以工作。但是,如果没有AHK的帮助,我想不出一种在C#中获取HWND的方法。
process.MainWindowHandle
返回0。
我也尝试过
ProcessThreadCollection threads = process.Threads;
foreach (ProcessThread thread in threads)
{
EnumThreadWindows((uint)thread.Id, new EnumThreadDelegate(EnumThreadCallback), IntPtr.Zero);
}
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
protected delegate bool EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);
protected static bool EnumThreadCallback(IntPtr hwnd, IntPtr lParam)
{
MessageBox.Show("Try");
IntPtr lpdwProcessId;
GetWindowThreadProcessId(hwnd, out lpdwProcessId);
if (lpdwProcessId == lParam)
{
MessageBox.Show("True: " + hwnd.ToString());
makeTransparent(lParam);
return false;
} else
MessageBox.Show("False: " + hwnd.ToString());
return true;
}
EnumThreadCallback
从未被调用,即使它适用于任何其他进程。
编辑:
我发现Keyboard进程实际上不是在创建Keyboard。相反,似乎键盘UI是由资源管理器创建的。
以下代码确实有效:
Process[] processes = Process.GetProcesses();
IntPtr hWnd = IntPtr.Zero;
while ((hWnd = FindWindowEx(IntPtr.Zero, hWnd, "ApplicationFrameWindow", null)) != IntPtr.Zero)
{
IntPtr lpdwProcessId;
GetWindowThreadProcessId(hWnd, out lpdwProcessId);
foreach (Process process in processes)
{
if (process.ToString() == "System.Diagnostics.Process (explorer)")
{
if (process.Id == (int)lpdwProcessId)
{
doThing(hWnd);
}
}
}
}
但是,使用了多个hWnd,其中只有一个属于键盘。现在,我需要找出如何过滤掉这个特定的对象。 该方法目前似乎没有缺点,但是我不愿意释放它而不知道是否因此而产生不利影响。受害者1:新的粘贴窗口。
答案 0 :(得分:0)
尝试以下替代解决方案:
var process = Process.GetProcessById(pid);
IntPtr hwnd = process.MainWindowHandle;