2009-04-30 28 views
6

Tôi cần mô phỏng một lần nhấn phím trong ứng dụng của bên thứ ba. Giả sử tôi có một ứng dụng C# cần gửi "8" đến ứng dụng Máy tính. Tôi không thể sử dụng SendKeys của. Net hoặc keybd_event của win32 api bởi vì cả hai đều yêu cầu cửa sổ là một trong những hoạt động hàng đầu, mà không phải là trường hợp trong tình hình của tôi.Tôi không thể hiểu cách sử dụng các cuộc gọi SendMessage hoặc PostMessage

Vì vậy, để lại cho tôi các cuộc gọi sendMessage và postMessage. Tôi đã cố gắng trong ba giờ đồng hồ cố gắng để có được một số kết quả nhưng bây giờ tôi hoàn toàn vô vọng.

tôi có như sau:

 [DllImport("user32.dll")] 
    public static extern int FindWindow(string lpClassName,string lpWindowName); 
    [DllImport("user32.dll")] 
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); 

    [return: MarshalAs(UnmanagedType.Bool)] 
    [DllImport("user32.dll", SetLastError = true)] 
    public static extern bool PostMessage(int hWnd, uint Msg, int wParam, int lParam); 

    private void button1_Click(object sender, EventArgs e) 
    { 
     const int WM_KEYDOWN = 0x100; 
     const int WM_SYSCOMMAND = 0x018; 
     const int SC_CLOSE = 0x053; 

     int WindowToFind = FindWindow(null,"Calculator"); 

     int result = SendMessage(WindowToFind, WM_SYSCOMMAND, SC_CLOSE, 0); 
     Boolean result2 = PostMessage(WindowToFind, WM_SYSCOMMAND, SC_CLOSE, 0); 

     int result3 = SendMessage(WindowToFind, WM_KEYDOWN,((int)Keys.NumPad7), 0); 
     Boolean result4 = PostMessage(WindowToFind, WM_KEYDOWN, ((int)Keys.NumPad7), 0); 
    } 

Như bạn thấy đấy, tôi làm cho bốn nỗ lực để giao tiếp với Máy tính. Sử dụng cả hai sendMessage và PostMessage để đóng cửa sổ và cũng để gửi phím 7. Không có gì hoạt động. Phương thức FindWindow hoạt động vì tôi có được trình xử lý của ứng dụng (thậm chí tôi đã thử khởi chạy quá trình đó và truy cập nó với process.MainWindowHandler, nhưng không may mắn). Không có lỗi hoặc ngoại lệ, nhưng nó không làm gì trong Máy tính.

Tôi cũng đã thử chính xác những điều tương tự với notepad và không có gì thay đổi quá.

Trả lời

11

Bất kỳ cơ hội nào bạn đang chạy trên máy 64 bit? Nếu vậy, tôi tin rằng tất cả những giá trị 'int' thực sự là hWnds (đối số đầu tiên cho Gửi/Đăng, giá trị trả về từ FindWindow) cần phải là IntPtr.


Sau khi kiểm tra nhiều hơn một chút, có vẻ như cho cả SendMessage và PostMessage, 1, 3, và các thông số 4 nên được IntPtr thay vì int (cũng như các giá trị trả lại cho tất cả các)

Vì vậy, chữ ký đúng sẽ là:

[DllImport("user32.dll")] 
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName); 
[DllImport("user32.dll")] 
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 
[DllImport("user32.dll")] 
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 
+0

Wow. Điều đó làm việc? Nói về một dự đoán may mắn. Tôi chưa bao giờ sử dụng hai phương pháp win32 đó. –

+0

Im thực sự trên 32bits, nhưng nó làm việc tuy nhiên :) –

+0

Hey, bất cứ điều gì hoạt động :) –

3

có một bài viết tốt về vấn đề này trên CodeProject: http://www.codeproject.com/KB/cs/SendKeys.aspx

SendKeys thực sự là ý tưởng chính xác, nhưng bạn cần lấy HWND (cửa sổ xử lý) của cửa sổ mục tiêu. This MSDN sample cho biết cách sử dụng SendKey hiệu quả, nhưng không phải cách khám phá HWND của bất kỳ điều gì khác ngoài cửa sổ trên cùng.

Kết hợp hai kỹ thuật, sử dụng ví dụ CodeProject để xác định HWND của ứng dụng bạn muốn nhắm mục tiêu, sau đó sử dụng bài viết MSDN để sử dụng SendKeys để gửi các nét chính

2

Không trực tiếp câu hỏi của bạn, nhưng sự khác biệt giữa SendMessagePostMessageSend là cuộc gọi chặn, Post trả về ngay lập tức (trước khi đơn đăng ký nhận được xử lý).

MSDN giải thích sự khác biệt: http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx

Ngoài ra nếu bạn đang ở trên vista nhưng không phải trên .NET 3.0 mà cũng có thể là một vấn đề:

Lớp SendKeys đã được cập nhật cho .NET Framework 3.0 để cho phép sử dụng trong các ứng dụng chạy trên Windows Vista. Bảo mật nâng cao của Windows Vista (được gọi là Kiểm soát Tài khoản Người dùng hoặc UAC) ngăn việc triển khai trước đó hoạt động như mong đợi.

1

Vì đây là cửa sổ Chỉnh sửa con bên trong cửa sổ notepad. Bạn nên gửi tin nhắn đến cửa sổ con bên phải. Đây là ví dụ hoạt động trong C:

#include <windows.h> 
#include <stdio.h> 

void main(void) { 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 
    HWND mainwnd,editwnd; 
    char c; 
    si.cb=sizeof(si); 
    si.lpReserved=NULL; 
    si.lpDesktop=NULL; 
    si.lpTitle=NULL; 
    si.dwFlags=0; 
    si.cbReserved2=0; 
    si.lpReserved2=NULL; 
    if(!CreateProcess("c:\\windows\\notepad.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) { 
     printf("Failed to run app"); 
     return; 
    } 
    WaitForInputIdle(pi.hProcess,INFINITE); 
    mainwnd=FindWindow(NULL,"Untitled - Notepad"); 
    if(!mainwnd) { 
     printf("Main window not found"); 
     return; 
    } 
    editwnd=FindWindowEx(mainwnd,NULL,"Edit",""); 
    if(!editwnd) { 
     printf("Edit window not found"); 
     return; 
    } 
    for(c='1';c<='9';c++) { 
     PostMessage(editwnd,WM_CHAR,c,1); 
     Sleep(100); 
    } 
} 
Các vấn đề liên quan