无礼:,我同意 Jimi 和 jmcilhinney 的 cmets,我也同意
相信这不是实现屏幕键盘的正确方法,
但这篇文章只是想帮助你:
当该窗口被激活时,查找已停用窗口的句柄
您可以使用SetWinEventHook 来监听其他进程的some events,并注册一个WinEventProc 回调方法,以便在事件引发时接收事件。
这里我们对EVENT_SYSTEM_FOREGROUND 感兴趣。每次我们收到这个事件,如果激活的窗口不是我们的窗体,我们跟踪已经被激活的窗口,然后当我们的窗口被激活时,我们查看被跟踪的窗口的值,它现在是之前丢失的窗口重点。
C#
这是我尝试过的代码:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class MyForm : Form
{
public const uint EVENT_SYSTEM_FOREGROUND = 0x0003;
public const uint EVENT_OBJECT_DESTROY = 0x8001;
public const uint WINEVENT_OUTOFCONTEXT = 0;
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild,
uint dwEventThread, uint dwmsEventTime);
[DllImport("user32.dll")]
public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax,
IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc,
uint idProcess, uint idThread, uint dwFlags);
[DllImport("user32.dll")]
public static extern bool UnhookWinEvent(IntPtr hWinEventHook);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
IntPtr hook = IntPtr.Zero;
protected override void OnLoad(EventArgs e)
{
previous = GetForegroundWindow();
hook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND,
EVENT_SYSTEM_FOREGROUND,
IntPtr.Zero, new WinEventDelegate(WinEventProc),
0, 0, WINEVENT_OUTOFCONTEXT);
base.OnLoad(e);
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
UnhookWinEvent(hook);
base.OnFormClosing(e);
}
IntPtr? previous = null;
void WinEventProc(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread,
uint dwmsEventTime)
{
if (hwnd != this.Handle)
{
previous = hwnd;
}
else
{
if (previous.HasValue)
this.Text = $"Previous window: {(int)previous:X}";
else
this.Text = $"No idea about previous window.";
}
}
}
VB.NET
Imports System.Runtime.InteropServices
Public Class MyForm
Inherits Form
Public Const EVENT_SYSTEM_FOREGROUND As UInteger = &H3
Public Const EVENT_OBJECT_DESTROY As UInteger = &H8001
Public Const WINEVENT_OUTOFCONTEXT As UInteger = 0
Public Delegate Sub WinEventDelegate(ByVal hWinEventHook As IntPtr,
ByVal eventType As UInteger,
ByVal hwnd As IntPtr,
ByVal idObject As Integer,
ByVal idChild As Integer,
ByVal dwEventThread As UInteger,
ByVal dwmsEventTime As UInteger)
<DllImport("user32.dll")>
Public Shared Function SetWinEventHook(ByVal eventMin As UInteger,
ByVal eventMax As UInteger,
ByVal hmodWinEventProc As IntPtr,
ByVal lpfnWinEventProc As WinEventDelegate,
ByVal idProcess As UInteger,
ByVal idThread As UInteger,
ByVal dwFlags As UInteger) As IntPtr
End Function
<DllImport("user32.dll")>
Public Shared Function UnhookWinEvent(ByVal hWinEventHook As IntPtr) As Boolean
End Function
<DllImport("user32.dll")>
Private Shared Function GetForegroundWindow() As IntPtr
End Function
Private hook As IntPtr = IntPtr.Zero
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
previous = GetForegroundWindow()
hook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND,
EVENT_SYSTEM_FOREGROUND, IntPtr.Zero,
New WinEventDelegate(AddressOf WinEventProc),
0, 0, WINEVENT_OUTOFCONTEXT)
MyBase.OnLoad(e)
End Sub
Protected Overrides Sub OnFormClosing(ByVal e As FormClosingEventArgs)
UnhookWinEvent(hook)
MyBase.OnFormClosing(e)
End Sub
Private previous As IntPtr? = Nothing
Private Sub WinEventProc(ByVal hWinEventHook As IntPtr,
ByVal eventType As UInteger,
ByVal hwnd As IntPtr,
ByVal idObject As Integer,
ByVal idChild As Integer,
ByVal dwEventThread As UInteger,
ByVal dwmsEventTime As UInteger)
If hwnd <> Me.Handle Then
previous = hwnd
Else
If previous.HasValue Then
Me.Text = $"Previous window: {CInt(previous):X}"
Else
Me.Text = $"No idea about previous window."
End If
End If
End Sub
End Class