2012-11-14 5 views
0

C# WinForms 프로그램에서 AxInterop으로 사용하고있는 ActiveX 컨트롤 (VB 6.0 또는 C++으로 작성된 것 같습니다)이 있습니다. 텍스트 상자와 매우 비슷하지만 특별한 논리 등이 있습니다 ... 도구 모음에 추가했습니다.폼로드시 포커스 문제

폼이로드 될 때 키보드 포커스를이 컨트롤 안에두기 위해 .Focus.Select 메서드를 사용했지만 여전히 포커스를 얻지는 못합니다.

Visual Studio에서 실행할 때 컨트롤이 포커스를 얻습니다.

IDE 외부에서 실행하면 컨트롤에 포커스가 적용되지 않습니다.

왜 이런가요?

enter image description here

답변

1

포커스를 주려고 할 때 구성 요소를 볼 수 있습니까?

Form.Load 이벤트 핸들러에서 포커스를 수행하려는 경우 Form.Shown 핸들러로 이동하거나 Control.Enter으로 이동하십시오.

동작의 차이는 타이밍 문제 일 수 있습니다. 더 많은 아이디어를 얻기 위해 오프닝 양식에 이벤트가 발생하는 순서는 on MSDN입니다.

1

당신은 포커스를 설정하기 위해 WindowsApi.SetFocus 방법을 사용할 수 있습니다 : 여기

도 그것의 스크린 샷이다.
an external application의 특정 컨트롤에 포커스를 설정하는 데이 메서드를 사용할 수 있으므로 타사 컨트롤에서 응용 프로그램에서 작동해야합니다. 여기

다른 옵션 - 윈폼에서 외부 응용 프로그램에서 컨트롤에 대한 포커스를 설정하는 코드의 작업 블록 :

[DllImport("user32.dll")] 
    static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId); 
    [DllImport("kernel32.dll")] 
    static extern IntPtr GetCurrentThread(); 

    [DllImport("user32.dll")] 
    static extern bool AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, bool fAttach); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern bool BringWindowToTop(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool SetForegroundWindow(IntPtr hWnd); 

    [DllImport("User32.dll", EntryPoint = "FindWindow")] 
    public static extern IntPtr FindWindow(String lpClassName, String lpWindowName); 
    [DllImport("user32.dll")] 
    static extern IntPtr SetFocus(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, string lParam); 
    private delegate bool EnumWindowsProc(IntPtr hWnd, string className); 

    [DllImport("user32.dll")] 
    static extern uint RealGetWindowClass(IntPtr hwnd, [Out] StringBuilder pszType, uint cchType); 


    void SetFocus(IntPtr hwndTarget, string childClassName) 
    { 
     // hwndTarget is the other app's main window 
     // ... 
     IntPtr targetThreadID = GetWindowThreadProcessId(hwndTarget, IntPtr.Zero); //target thread id 
     IntPtr myThreadID = GetCurrentThread(); // calling thread id, our thread id 

     bool lRet = AttachThreadInput(myThreadID, targetThreadID, true); // attach current thread id to target window 

     // if it's not already in the foreground... 
     lRet = BringWindowToTop(hwndTarget); 
     SetForegroundWindow(hwndTarget); 

     // Enumerate and find target to set focus on 
     EnumChildWindows(hwndTarget, OnChildWindow, childClassName); 
    } 

    List<object> windowHandles = new List<object>(); 
    static bool OnChildWindow(IntPtr handle, string className) 
    { 
     // Find class of current handle 
     StringBuilder pszType = new StringBuilder(); 
     pszType.Capacity = 255; 
     RealGetWindowClass(handle, pszType, (UInt32)pszType.Capacity); 

     string s = pszType.ToString(); 

     // Remove (potentially) unneeded parts of class 
     if (s.Length > className.Length) 
     { 
      s = s.Substring(0, className.Length); 
     } 

     // Set focus on correct control 
     if (s == className) 
     { 
      SetFocus(handle); 
     } 

     return true; 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     InitializeComponent(); 

     SetFocus(this.Handle, "<ClassName from Spy++>"); 

    } 

당신이 스파이를 사용할 수있는 텍스트 상자의 클래스 이름을 모르는 경우 ++

+0

폼의 컨트롤 이름을 알고 있습니다 ... "this"대신 첫 번째 줄에 사용해야합니다. – Bohn

+0

코드를 컴파일 할 때 어떤 네임 스페이스를 포함해야합니까? – Bohn

+1

컨트롤의 클래스 이름을 기반으로 창에서 특정 컨트롤의 포커스를 설정하는 코드 전체가 업데이트되었습니다. – Blachshma