2011-09-11 7 views
0

動的に表示されるダイアログボックスを自動化しようとしています。 テキストフィールドにテキストを渡してから、ボタンを押してください。 これまでに何を試みましたか?ハンドルCを使用したフォームとの対話

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] 
     static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); 

IntPtr handle= FindWindowByCaption(System.IntPtr.Zero, "Caption Of File"); 

ダイアログボックスのハンドルを正しく取得しています。

List<IntPtr> childWindows= GetChildWindows(handle);//To get the child controls in this dialogue box 

Source

しかし、私はnullを取得し制御することをキャストしようとします。

foreach (IntPtr i in childWindows) 
{ 
    Control c = Control.FromHandle(i); 
} 

だから、すべてのボディはwrong.Iは、私がコントロールして、コントロールのプロパティ(例えば:テキスト)と対話するためにハンドルを投じるものと仮定していているものを伝えることができます。

+2

Windowsメッセージの処理の複雑さを隠すために、白などのUIオートメーションフレームワークを使用することを検討しましたか? (http://code.google.com/p/white-project/)ここで例を見つけることができます:http://scip.be/index.php?Page=ArticlesNET19&Lang=NL –

+0

私は試みました。例外があります。キャストしようとするとCastle.Proxies.Win32ComboBoxProxyからキャストできません。 –

答えて

2

enter image description here

私は自分のユーザー名/パスワード/ドメインのユーザーに求めアプリケーションへのシングルサインオンを実行するために年間このsucessfullyのようなコードを使用してきました。唯一の注意点は、ターゲットとするダイアログのコントロール構造を知る必要があることですが、これはSpy ++で簡単に実現でき、変更はほとんどありません。もちろん、このコードをウィンドウのコントロール構造に合わせて変更する必要があります。

 [DllImport("user32.dll")] 
     static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, 
      string lpszClass, string lpszWindow); 

     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, int wParam, string lParam); 

     [DllImport("User32.Dll")] 
     public static extern IntPtr PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam); 

     private const uint WM_GETTEXTLENGTH = 0x000E; 
     private const uint WM_SETTEXT = 0x000C; 
     private const uint WM_GETTEXT = 0x000D; 
     private const uint BM_CLICK = 0x00F5; 
     private const uint WM_CLOSE = 0x0010; 

     enum GetWindow_Cmd : uint 
     { 
      GW_HWNDFIRST = 0, 
      GW_HWNDLAST = 1, 
      GW_HWNDNEXT = 2, 
      GW_HWNDPREV = 3, 
      GW_OWNER = 4, 
      GW_CHILD = 5, 
      GW_ENABLEDPOPUP = 6 
     } 

var dialog FindWindow("optionalClassNameHere", "Log On"); //Get the handle of the window 
var w3 = GetWindow(dialog , (uint)GetWindow_Cmd.GW_CHILD); //I use GetWindow to walk the window controls 
var wUid = FindWindowEx(w3, IntPtr.Zero, "Edit", ""); 
var w4 = GetWindow(wUid, (uint)GetWindow_Cmd.GW_HWNDNEXT); 
var wPwd = FindWindowEx(w4 , IntPtr.Zero, "Edit", ""); 
var wOK = FindWindowEx(w3, IntPtr.Zero, "Button", "OK"); 
SendMessage(wUid, WM_SETTEXT, 0, _WinDomain + "\\" + Username); //Send username to username edit control 
SendMessage(wPwd, WM_SETTEXT, 0, Password); //Send password to password edit control 
PostMessage(wOK, BM_CLICK, 0, 0); //Send left click(0x00f5) to OK button 
+0

ありがとうJimStat.Iコンボボックスの値を選択するのではなく、コンボボックスの値を選択しようとしています。コンボボックスのテキスト(My file path)を設定しようとしています。 私は次のコードを試しています。 SendMessage(ws3、0x000C、0、 "My file path"); // ws3はコンボボックスのハンドルです。 私は何が欠けているのか理解できますか? –

+0

Khan - ComboBoxコントロールの子である「編集」コントロールにWM_SETTEXTする必要があると思います。私が答えに加えたスクリーンショットを見てください。 – JimSTAT

+0

したがって、スクリーンショットでは、ComboBoxハンドル(001B1174)を開始点として使用して、最初の「編集」コントロール(000511CA)のハンドルを取得することを回答に追加しました。 FindWindowExまたはGetWindowとGW_CHILDパラメータを使用して、これを達成できます。最後に、 "SendMessage(hEditControl、WM_SETTEXT、" My file path ")のようなテキストを設定します。Fyi - WM_SETTEXT = 0x000C – JimSTAT

0

Control.FromHandleは、コントロールの子孫によって実装されるプロセス内のコントロールに対してのみ機能します。私はこのウィンドウがあなたのプロセスの外にあると思います。

これを変更するには、Win32 APIメソッドを使用する必要があります。