2012-02-22 22 views
4

私はMedia Subtitlerと呼ばれるプログラム内のメニュー項目をクリックしようとしています。C#WinAPIメニュー項目をクリックする

まず、GetMenu関数を使用しようとしましたが、IntPtr.Zeroが返されました。 次に、私のメニューの最初の文字を使ってALTキーを使ってみましたが(Fはファイルを表します)、何もしませんでした。 次に、単純なMOUSEDOWNとMOUSEUPメッセージを使用してみましたが、何もしませんでした(その範囲のすべてをクリックするループを作成しようとしましたが、その領域にはクリックがありませんでした)。

明らかに私が知っているのは、正しいウィンドウで作業しているということです。

私は間違っていますか?

誰かが試してみたいと思えば、無料でMedia Subtitlerをダウンロードすることができます。

また、ここで私がテストしてきたコードは次のとおりです。任意のヘルプ

Process p = Process.Start(@"C:\Program Files\DivXLand\Media Subtitler\MediaSub.exe"); 
     p.WaitForInputIdle(1500); 
     Thread.Sleep(3000); 

     SetForegroundWindow(p.MainWindowHandle); 
     ShowWindow(p.MainWindowHandle, SW_MAXIMIZE); 

     IntPtr handle = p.MainWindowHandle; 

     SendMessage(handle, WM_NCHITTEST, 0, MakeLParam(18, 29)); 

     //for (int i = 0; i < 200; i++) 
     //{ 
     // for (int x = 0; x < 200; x++) 
     // { 
     //  SendMessage(p.MainWindowHandle, WM_LBUTTONDOWN, 0, MakeLParam(i, x)); 
     //  SendMessage(p.MainWindowHandle, WM_LBUTTONUP, 0, MakeLParam(i, x)); 
     // } 
     //} 
     //IntPtr menuItems = GetMenu(p.MainWindowHandle); 
     return; 
     //SendMessage(p.MainWindowHandle, WM_COMMAND, 6, 0); 
     SendMessage(p.MainWindowHandle, WM_KEYDOWN, VK_MENU, 0); 
     SendMessage(p.MainWindowHandle, WM_KEYUP, VK_MENU, 0); 
     SendMessage(p.MainWindowHandle, WM_KEYDOWN, VK_F, 0); 
     SendMessage(p.MainWindowHandle, WM_KEYUP, VK_F, 0); 

ありがとう!

答えて

6

アプリケーションのメインウィンドウに送信されたメッセージを監視することによって、メニュー項目のメニュー識別子を抽出しました。

[DllImport("user32.dll")] 
public static extern IntPtr PostMessage(IntPtr hWnd, Message msg, int wParam, int lParam); 

PostMessage(handle, WM_COMMAND, 2, 0); // File->New subtitle 

PostMessage(handle, WM_COMMAND, 3, 0); // File->New from clipboard 

PostMessage(handle, WM_COMMAND, 5, 0); // File->Open text or subtitle 

PostMessage(handle, WM_COMMAND, 6, 0); // File->Open video 

... 

は、私はメディアSubtitlerでコードをテストしてみた、そしてそれは魔法のように動作します:あなたはwParamなどのメニュー項目のIDと、ウィンドウにWM_COMMANDメッセージを投稿することができます!これがうまくいかない唯一の状況は、Windows Vistaまたは7で、ターゲットプログラムが管理者として実行されており、C#プログラムが実行されていない場合です。それに気づいてください!

メニューIDは、WM_COMMANDメッセージ(Spy ++を使用)を監視することで簡単に調べることができます。
PostMessageの代わりにSendMessageを使用することもできますが、メニュー操作で開いたウィンドウを閉じるまでプログラムはフリーズします。

他のコマンドをアプリケーションの他のウィンドウに送信する場合も、同じ方法を使用できます。たとえば、「ビデオを開く」ウィンドウの「開く」ボタンをクリックします。

+0

返信いただきありがとうございます。 spy ++でプログラムを見たときに、メニューハンドラが見えませんでした。どのように見つけましたか?メニューハンドラを取得するためのコードも記述できますか?ありがとう。 –

+1

メニューハンドラを取得する必要はありません(ただし、spy ++のウィンドウのプロパティで利用可能です)。私はウィンドウのメッセージを監視しました。 spy ++でウィンドウリストを更新し、 'Find Window'ツールをクリックして十字線をあなたのウィンドウにドラッグします。見つけたら、右クリックして 'Messages'を選択してください。このウィンドウでは、spy ++はすべてのメッセージが送信されてウィンドウに表示されることを示します。 'Messages'メニュー(Ctrl + O)から' Logging options'を選択することでメッセージをフィルタリングできます。 –

+0

ありがとう!できます! –

0

Visual Studioには、オブジェクトのハンドルを表示できるツールSpy ++があります。 あなたがそこに表示された場合、あなたがそれらを取得するuser32.dllの機能に

[DllImport("user32.dll", SetLastError = true)] 
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string lpszWindow); 

を使用してそれを取得することができるはず(ハンドルがアプリを実行する別のたびになります) あなたは右のハンドルを取得した場合、 SendMessageを使用してEnterを送信するか、をクリックする必要があります。

は1つのアプリでこれを試みたが、私はそれは文句を言わないあなたはまた、System.Windows.Automation名前空間を使用して、このすべてを行うことができます

+2

もう一つの便利なツールは、[Windows SDK](http://www.microsoft.com/download/en/details.aspx?id=8279)でInsptect Objects(またはUISpyを古いバージョン)を使用して、ウィンドウ間の関係を確認します。オートメーションコードを書くときに非常に便利です。 –

4

を作業している場合だけなので申し訳ありませんが、読んで、テキストを書くためにそれを使用:http://msdn.microsoft.com/en-us/library/ms590934.aspx

この名前空間を使用すると、Win32 APIとの相互運用を行う必要はありません。ここでは、その名前が含まれている文字列を検索することで、ウィンドウを取得する方法の例です:

public static AutomationElement GetWindowByName(string name) 
{ 
    AutomationElement root = AutomationElement.RootElement; 
    foreach (AutomationElement window in root.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window))) 
    { 
     if (window.Current.Name.Contains(name) && window.Current.IsKeyboardFocusable) 
     { 
      return window; 
     } 
    } 
    return null; 
} 

あなたがたAutomationElementオブジェクトとしてウィンドウを持った後、あなたがコントロールのためにそれを検索し、これらのコントロールの操作を行うことができ、など。

これは役に立ちます。

+0

大きなヒントはありますが、この名前空間は_WPF_Windowsにのみ関連しています – itsho

関連する問題