只是一个简单的问题,你能告诉我为什么我无法访问我的控件,如弹出窗口或文本框或带有注释的函数内的'this',请检查出来。我真的需要知道为什么尽快。非常感谢你!
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DispatcherTimer timer;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
public const int WH_KEYBOARD_LL = 13;
public const int WM_KEYDOWN = 0x0100;
public static LowLevelKeyboardProc _proc = HookCallback;
public static IntPtr _hookID = IntPtr.Zero;
public const uint VK_NUMLOCK = 0x90;
public const uint VK_CAPITAL = 0x14;
public MainWindow()
{
MouseDown += delegate { DragMove(); };
InitializeComponent();
_hookID = SetHook(_proc);
}
public void mainForm_Loaded(object sender, RoutedEventArgs e)
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Tick += timer_Tick;
}
public void timer_Tick(object sender, EventArgs e)
{
Popup1.IsOpen = false;
timer.Stop();
}
public static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
public static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
if (vkCode == VK_CAPITAL)
{
if (Console.CapsLock == true)
{
// I WANT TO ACCESS MY CONTROLS HERE (popup, textbox, etc... this);
}
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
protected override void OnClosed(EventArgs e)
{
UnhookWindowsHookEx(_hookID);
base.OnClosed(e);
}
}
答案 0 :(得分:4)
这是一种静态方法。 &#34;这&#34;控件属于实例,无法在静态方法中看到。
使用这些.dll,我无法提供访问它的防弹方法。我不建议诉诸希望和梦想,但在MainWindow是活动窗口的情况下,您可以执行以下操作:
public static void StaticMainWindowMethod(string incomingMessage)
{
var activeWindow = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
if (activeWindow != null)
{
var mainWindow = activeWindow as MainWindow;
if (mainWindow != null)
{
mainWindow.InstanceMainWindowMethod(incomingMessage);
}
}
}
protected void InstanceMainWindowMethod(string passedFromStaticMessage)
{
this.MainTextBox.Text = passedFromStaticMessage;
}
这个想法是你需要获取窗口的实例才能获得它的属性/控件。根据应用程序的设计方式,您可以通过应用程序级属性获取它。它的可靠性完全取决于应用程序的设计。
答案 1 :(得分:2)
首先,在窗口中添加一个静态事件:
public static event EventHandler CapsLockEnabled;
接下来,为此事件添加处理程序:
public MainWindow()
{
MouseDown += delegate { DragMove(); };
InitializeComponent();
_hookID = SetHook(_proc);
CapsLockEnabled += (sender, e) => { Console.WriteLine("caps lock enabled"); };
}
您的事件处理程序,因为它在实例上定义,可以完全访问所有窗口的控件。
最后,从您的HookCallback
方法提升事件:
public static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
if (vkCode == VK_CAPITAL)
{
if (Console.CapsLock == true)
{
var handler = CapsLockEnabled;
if (handler != null)
{
handler(typeof(MainWindow), EventArgs.Empty);
}
}
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}