2012-04-23 36 views
5

Tôi đang cố gắng sử dụng SendMessage để gửi một phím tắt, và không thực sự hiểu lParam. Tôi hiểu rằng các bit khác nhau đại diện cho mỗi tham số và chúng cần được sắp xếp theo thứ tự.Cách tạo lParam của SendMessage WM_KEYDOWN

Tôi đã đọc this question & this, vì vậy tôi biết mà đặt các bit cần phải được trong, tôi chỉ không biết làm thế nào để làm điều đó ...

Làm thế nào tôi sẽ tạo ra lParam sau đây?

repeat cound = 0, 
scan code = {Don't know what this is?}, 
extended key = 1, 
reserved = 0, 
context code = 0, 
previous key state = 1, 
transition state = 0 
+0

Khi bài tiểu bang liên kết, không sử dụng SendMessage để gửi tổ hợp phím, sử dụng SendInput để thay thế. http://blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx –

+1

@RussC: Cảm ơn, nhưng nó cần phải được thực hiện với SendMessage vì tôi muốn gửi chìa khóa đến cửa sổ khác so với hoạt động. Thực sự tôi chỉ cần biết cách xây dựng lParam này. – Drahcir

+0

Tôi đã cập nhật câu trả lời của mình bên dưới. Bạn có thể làm rõ rằng bạn sẽ gửi tin nhắn WM_KEYDOWN đến SendMessage? –

Trả lời

8

tôi nhận ra rằng AutoIT có các chức năng mà tôi cần, vì vậy có nhìn source tập tin sendKeys.cpp và tìm thấy C++ đoạn mã sau đây cho chức năng này, nó sẽ dễ dàng đủ để dịch sang C#:

scan = MapVirtualKey(vk, 0); 

// Build the generic lparam to be used for WM_KEYDOWN/WM_KEYUP/WM_CHAR 
lparam = 0x00000001 | (LPARAM)(scan << 16);   // Scan code, repeat=1 
if (bForceExtended == true || IsVKExtended(vk) == true) 
    lparam = lparam | 0x01000000;  // Extended code if required 

if ((m_nKeyMod & ALTMOD) && !(m_nKeyMod & CTRLMOD)) // Alt without Ctrl 
    PostMessage(m_hWnd, WM_SYSKEYDOWN, vk, lparam | 0x20000000); // Key down, AltDown=1 
else 
    PostMessage(m_hWnd, WM_KEYDOWN, vk, lparam); // Key down 

mã quét có thể gener ated với MapVirtualKey

C# Dịch:

public static void sendKey(IntPtr hwnd, VKeys keyCode, bool extended) 
{ 
    uint scanCode = MapVirtualKey((uint)keyCode, 0); 
    uint lParam; 

    //KEY DOWN 
    lParam = (0x00000001 | (scanCode << 16)); 
    if (extended) 
    { 
     lParam |= 0x01000000; 
    } 
    PostMessage(hwnd, (UInt32)WMessages.WM_KEYDOWN, (IntPtr)keyCode, (IntPtr)lParam); 

    //KEY UP 
    lParam |= 0xC0000000; // set previous key and transition states (bits 30 and 31) 
    PostMessage(hwnd, WMessages.WM_KEYUP, (uint)keyCode, lParam); 
} 

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
private static extern uint MapVirtualKey(uint uCode, uint uMapType); 
1

Nếu bạn hoàn toàn phải sử dụng SendMessage, thì bạn cần phải chuyển đổi bit int của bạn ở đúng vị trí.

Trang web này tài liệu làm thế nào để làm điều này trong C#:

http://codeidol.com/csharp/csharpckbk2/Classes-and-Structures/Turning-Bits-On-or-Off/

Đề cập đến câu hỏi của bạn, scancode là giá trị của khóa mà bạn đang cố gắng để gửi và đại diện một số bang quá. Ví dụ mã quét để ép A là khác nhau để mã cho giải phóng A.

Wikipedia có một bài viết về họ:

http://en.wikipedia.org/wiki/Scancode

Các vấn đề liên quan