2009-04-30 14 views
6

サードパーティアプリケーションでキー押しをシミュレートする必要があります。たとえば、Calculatorアプリケーションに「8」を送信する必要があるC#アプリケーションがあるとします。 .NetのSendKeysやwin32 APIのkeybd_eventを使うことはできません。なぜなら、私の状況では大文字と小文字が区別されないため、ウィンドウがトップアクティブなものでなければならないからです。SendMessageまたはPostMessageコールの使用方法がわかりません

私はsendMessageとpostMessageの呼び出しを残します。私は最後の3時間でいくつかの結果を得ようとしていますが、今は完全に希望がありません。

私は、次のしている:

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

をあなたが見ることができるように、私は電卓と通信するための4つの試みを作ります。 sendMessageとPostMessageの両方を使用してウィンドウを閉じ、キーも送信します。7.何も動作しません。 FindWindowメソッドは、私がアプリケーションのハンドラを取得する原因となります(私は自分自身でプロセスを起動し、process.MainWindowHandlerでアクセスしてみましたが、運はありません)。エラーや例外はありませんが、Calculatorでは何もしません。

私はメモ帳でも全く同じことを試しましたが、何も変わっていません。

答えて

11

これは64ビットマシンで実行していますか?もしそうなら、実際にhWnds(Send/Postへの最初の引数、FindWindowからの戻り値)であるそれらのint値はすべてIntPtrである必要があります。もう少しチェックした後、それはのSendMessageとのPostMessage、第一、第三の両方のように見える、と4番目のパラメータはintの代わりにのIntPtrされなければならない(ならびにこれらのすべての戻り値)


だから、右のシグネチャは次のようになります。

[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です。それは働いた?幸運なことを話してください。私はこれらの2つの特定のwin32メソッドを使用したことはありません。 –

+0

実際には32ビットですが、それでも動作します:) –

+0

何でもいいよ:) –

3

CodeProjectの上でこの程度の良い記事があります: http://www.codeproject.com/KB/cs/SendKeys.aspx

SendKeysは実際には正しいアイデアですが、ターゲットウィンドウのHWND(ウィンドウハンドル)を取得する必要があります。 This MSDN sampleはSendKeysを効果的に使用する方法を示しますが、一番上のウィンドウ以外のHWNDを検出する方法は示していません。

CodeProjectの例を使用してターゲットにするアプリケーションのHWNDを特定し、MSDNの記事を使用してキーストローク(またはマウスイベント)をターゲットアプリケーションに送信するSendKeysを使用します。

2

ない直接あなたの質問が、SendMessagePostMessageとの違いは、(受信側アプリケーションがそれを処理した前)Sendはすぐに、Post戻りブロッキング呼び出しであるということです。

MSDNの違いについて説明します。あなたはVista上ではなく、.NET 3.0である場合にも問題がある可能性があることもhttp://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx

を:

のSendKeysクラスは、.NET Framework用に更新されました3.0を使用して、Windows Vista上で動作するアプリケーションでの使用を可能にします。 Windows Vistaのセキュリティ強化(ユーザーアカウント制御またはUAC)により、以前の実装が期待どおりに機能しなくなります。

1

メモ帳ウィンドウ内の子ウィンドウの編集です。右の子ウィンドウにメッセージを送信する必要があります。これは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); 
    } 
} 
関連する問題