0

I have an ActiveX control (written in VB 6.0 or C++ maybe) that we are using as an AxInterop in a C# WinForms program. It is very much like a text box but with some special logic etc... and we have added it to a toolbar.

When the form loads I want the keyboard focus to be inside this control, so I used .Focus and .Select methods on it but still it does NOT get the focus.

When I run from Visual Studio, the control gets the focus.

When I run outside of the IDE, the control does not get the focus.

Why is this?

Here is an screen shot of it too:

enter image description here

g t
  • 7,287
  • 7
  • 50
  • 85
Bohn
  • 26,091
  • 61
  • 167
  • 254

2 Answers2

1

You can use the WindowsApi.SetFocus method to set the focus.
This method can be used to set a focus on a specific control in an external application, so it should work in your application on a 3rd party control.

Here is another option - a working block of code to set focus for a control in an external application in winforms:

    [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++>");

    }

If you don't know the classname of that textbox you can use spy++

Community
  • 1
  • 1
Blachshma
  • 17,097
  • 4
  • 58
  • 72
  • I know the name of the control on the form...so in your first line instead of "this" I should use that? – Bohn Nov 15 '12 at 14:05
  • 1
    Updated answer with a complete piece of code to set focus for a specific control in a window - based on the control's classname – Blachshma Nov 16 '12 at 11:19
1

Are you sure the component is visible when you try to give it focus?

If you are trying to do the focussing in a Form.Load event handler, try moving it to the Form.Shown handler instead, or perhaps Control.Enter.

The difference in behaviour could be down to a timing issue. Have a look on MSDN for the order in which events occur on an opening form for more ideas.

g t
  • 7,287
  • 7
  • 50
  • 85