2011-09-11 9 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

하지만 내가 널 얻을 제어 할 수 캐스팅 할 때.

foreach (IntPtr i in childWindows) 
{ 
    Control c = Control.FromHandle(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

나는 그들의 이름/비밀번호/도메인에 대한 사용자하라는 메시지를 표시하는 애플리케이션에 싱글 사인온 (SSO)을 수행 할 수 년 동안이 성공적으로 같은 코드를 사용하고있다. 주의 할 점은 대상으로 삼고있는 대화 상자의 제어 구조를 알아야한다는 것입니다. 그러나 이것은 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.CompoBox 값을 선택하는 대신 콤보 상자 값을 선택하려고합니다. 콤보 상자 (내 파일 경로)의 텍스트를 설정하려고합니다. 다음 코드를 시도하고 있습니다. SendMessage (ws3, 0x000C, 0, "내 파일 경로"); // ws3은 콤보 상자의 핸들입니다. 내가 누락 된 부분을 알아낼 수 있습니까? –

+0

Khan - ComboBox 컨트롤의 자식 인 "편집"컨트롤에 WM_SETTEXT가 필요하다고 생각합니다. 답변에 추가 한 스크린 샷을 참조하십시오. – JimSTAT

+0

그래서 스크린 샷에서 ComboBox 핸들 (001B1174)을 시작점으로 사용하여 첫 번째 "편집"컨트롤 (000511CA)의 핸들을 얻으려는 답을 추가했습니다. FindWindowEx 또는 GetWindow와 GW_CHILD 매개 변수를 사용하여이를 수행 할 수 있습니다. 마지막으로 "SendMessage (hEditControl, WM_SETTEXT,"내 파일 경로 ")와 같은 텍스트를 설정할 것입니다 .Fyi - WM_SETTEXT = 0x000C – JimSTAT

0

Control.FromHandle은 Control 자손에 의해 구현되는 프로세스의 컨트롤에서만 작동 할 수 있습니다. 이 창은 당신의 과정 밖에있는 것 같아요.

수정하려면 Win32 API 메서드를 사용해야합니다.