2010-01-14 18 views
8

Tôi tìm thấy mã móc nối bàn phím này, mà tôi đang cố gắng sửa đổi một chút cho các mục đích của mình: http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspxTôi có thể thay đổi đầu vào bàn phím của người dùng không?

Tổng quan, tôi muốn người dùng nhấn một phím, nói 'E' và có bàn phím trả về một ký tự khác, 'Z', cho bất kỳ ứng dụng nào đang được lấy nét.

Phương pháp có liên quan tôi đã thay đổi bây giờ trông giống như:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
     { 
      //The truely typed character: 
      int vkCode = Marshal.ReadInt32(lParam); 
      Console.WriteLine((Keys)vkCode); 

      KBDLLHOOKSTRUCT replacementKey = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); 
      replacementKey.vkCode = 90; // char 'Z' 
      Marshal.StructureToPtr(replacementKey, lParam, false); 

      //Now changed to my set character 
      vkCode = Marshal.ReadInt32(lParam); 
      Console.WriteLine((Keys)vkCode); 
     } 
     return CallNextHookEx(_hookID, nCode, wParam, lParam); 
    } 

Giao diện điều khiển đầu ra một cách chính xác này như:

E 
Z 
T 
Z 
G 
Z 
etc. 

TUY NHIÊN, trong ứng dụng tập trung vẫn còn loại 'E' thay vì 'Z' . Tại sao? Tôi đã thay đổi đầu vào bàn phím nối để chứa 'Z' thay vì 'E', và các dòng giao diện điều khiển cho thấy rằng nó đã được thay đổi một cách chính xác!

Như tôi đã hiểu, gọi return CallNextHookEx(_hookID, nCode, wParam, lParam); là những gì sẽ gửi lệnh "in ngay bây giờ" này tới ứng dụng đang mở. Đó không phải là cách nó hoạt động? Có điều gì đó ngăn cản tôi nhập vào nhân vật tôi muốn không? Tôi biết các ứng dụng như AutoHotkey lấy khóa đầu vào, kiểm tra và trả về một ký tự khác. Làm thế nào để tôi làm như vậy ở đây?

Cảm ơn!

+3

trong tò mò, ứng dụng này là gì? –

+1

Nó không phải là một keylogger! :) Ứng dụng là công nghệ hỗ trợ.Hãy suy nghĩ bàn phím iPhone; đằng sau hậu trường, nó sửa đổi vùng chính, sửa lỗi rõ ràng và chạy mã thông minh khác để giúp bạn nhập nhanh hơn và chính xác hơn. Đây là một ứng dụng tương tự, nhưng đối với bàn phím đầy đủ. – cksubs

Trả lời

5

Tôi đã thực hiện việc này trước nhưng có một chút khác biệt.
Thay vì cố gắng thay đổi các tham số được gửi đến CallNextHookEx, tôi đã nuốt phím bấm (bạn có thể thực hiện điều này bằng cách trả về giá trị không đồng bộ từ thủ tục móc để ngăn các thủ tục tiếp theo được gọi).

Sau đó, tôi đã sử dụng SendInput để gửi khóa mới mà tôi muốn 'tiêm'.

Vì vậy, về cơ bản nó hoạt động như thế này:

  • thủ tục Hook xác định một khóa mục tiêu được nhấn
  • Gọi để SendInput, với chìa khóa mới
  • Return 1 từ thủ tục hook để bỏ qua phím gốc

Hãy cẩn thận chuyển hướng theo chu kỳ, tức là 'a' chuyển hướng đến 'b' chuyển hướng đến 'a', nó có thể dễ dàng thổi lên;)

+0

Thật tuyệt, tôi đã bỏ qua thành công khóa gốc với trả về '(IntPtr) 1; 'Bây giờ, làm thế nào để tôi' SendInput'? Có một 'sử dụng XXX' cụ thể nào tôi cần đưa vào tiêu đề hay mã khác mà tôi cần thêm để sử dụng lệnh không? – cksubs

+0

pinvoke.net có tất cả mã cần thiết để gọi 'SendInput' - http://www.pinvoke.net/default.aspx/user32/SendInput.html –

+0

Ok, đã nhận nó bằng cách sử dụng' [DllImport ("coredll.dll", SetLastError = true)] SendInput bên ngoài tĩnh (uint cInputs,/* [MarshalAs (UnmanagedType.LPArray)] */KEYBOARDINPUT [] đầu vào, int cbSize); 'và cấu trúc KEYBOARDINPUT. Bây giờ tôi đang làm việc để gửi SendInput() các tham số đúng. – cksubs

0

Bạn có, rất có thể, đã cài đặt móc "chỉ rộng" và không "rộng hệ thống", điều đó có nghĩa là bản dịch chính sẽ chỉ xảy ra cho chuỗi cài đặt móc.

Để cài đặt "hệ thống rộng", bạn sẽ cần hai phần: một dll có "nhà cung cấp móc" và một exe quản lý nó. Đây là một hướng dẫn tốt http://www.codeproject.com/KB/system/hooksys.aspx và ở đây một ví dụ: http://www.codeguru.com/cpp/com-tech/shell/article.php/c4509/

Nhưng: 1. Hệ thống Cài đặt móc rộng nghiêm trọng có thể vít lên hệ thống bạn (đảm bảo rằng bạn chuyển tiếp các phím mà bạn không dịch) . 2. Vui lòng ... không tạo một keylogger khác

+2

Ông sử dụng móc khóa bàn phím cấp thấp, không phải móc khóa bàn phím thông thường. Các móc cấp thấp không cần một dll riêng biệt mà được nạp vào mọi quá trình. Từ http://msdn.microsoft.com/en-us/library/ms644985.aspx - Tuy nhiên, móc WH_KEYBOARD_LL không được tiêm vào một tiến trình khác. Thay vào đó, bối cảnh chuyển trở lại quá trình cài đặt hook và nó được gọi trong bối cảnh ban đầu của nó. Sau đó, bối cảnh chuyển trở lại ứng dụng đã tạo sự kiện. –

+0

Vậy ... điều đó có nghĩa là tôi đang sử dụng đúng cách này? :) – cksubs

+0

Rất nhiều thông tin về việc triển khai/sử dụng WH_KEYBOARD_LL (và rất nhiều cuộc thảo luận về các vấn đề về phát hiện các công cụ điều chỉnh, chuyển thông tin quan trọng đến ứng dụng hoặc chặn tiếp theo, v.v. trong phần bình luận) CodeProject: http: // www. codeproject.com/KB/system/CSLLKeyboard.aspx "Các plugin Windows API mức thấp từ C# để dừng các lần nhấn phím không mong muốn" của Emma Burrows. 2007 bài viết. – BillW