2015-03-12 2 views
0

просто быстрый вопрос, можете ли вы сказать мне, почему я не могу получить доступ к своим элементам управления, таким как всплывающее окно или текстовое поле или «это» внутри функции с комментарием, пожалуйста, проверьте это. Мне действительно нужно знать, почему асап. Спасибо огромное!Элементы управления не могут быть доступны внутри моей функции

/// <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); 
     } 

    } 

ответ

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); 
} 
+0

Мне нравится, что это намного лучше, и кажется, что он хорошо интегрируется. Хороший, Стивен. –

+0

Привет, сэр Стивен, большое спасибо, однако, «это» в обработчике дает мне ошибку. Недействительно в статическом свойстве, статическом методе , или статический инициализатор, что-то вроде этого. – Glenn

+0

Эй, сэр Стив, я помету ваш ответ как ответ. Большое вам спасибо! Я просто заменил это на что угодно. Как «" строка и т. д .... Это работает, Я не могу добавить больше вещей в обработчик событий. Как и timer.start(); Во всяком случае, еще раз спасибо! :) – Glenn

4

Это статический метод. «this» и элементы управления принадлежат экземпляру и не могут быть замечены внутри статического метода.

С использованием этих .dlls я не могу предоставить пуленепробиваемый метод доступа к нему. Я бы не советовал прибегать к надеждам и мечтам, но в том случае, когда 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; 
    } 

Идея заключается в том, что вам нужно, чтобы получить экземпляр окна чтобы получить его свойства/элементы управления. В зависимости от того, как ваше приложение разработано, вы можете получить его через свойства уровня приложения. Его надежность действительно зависит от дизайна приложения.

+0

О, я вижу. В любом случае я могу получить доступ к своим элементарным элементам внутри статического метода? PLSS? – Glenn

+0

Привет, спасибо, Марк, теперь я знаю. импорт .dll должен быть статическим, если я удалю все статическое ключевое слово во всей моей программе, программа не будет запущена. Мне нужно найти способ каким-то образом заставить всплывающее управление всплывать: ((( – Glenn

+1

см. Редактирование). Не очень или надежно, но, надеюсь, вы начнете с пути решения лучшего решения. –

Смежные вопросы