0

C# WinForms プログラムで AxInterop として使用している ActiveX コントロール (VB 6.0 または C++ で記述) があります。これはテキスト ボックスに非常によく似ていますが、いくつかの特別なロジックなどが含まれており、ツールバーに追加されています。

フォームが読み込まれると、キーボードのフォーカスをこのコントロール内に配置したいので、メソッドを使用.Focus.Selectましたが、それでもフォーカスが得られません。

Visual Studio から実行すると、コントロールがフォーカスを取得します。

IDE の外で実行すると、コントロールがフォーカスされません。

どうしてこれなの?

これもスクリーンショットです:

ここに画像の説明を入力

4

2 に答える 2

1

WindowsApi.SetFocusメソッドを使用してフォーカスを設定できます。このメソッドは、外部アプリケーション
の特定のコントロールにフォーカスを設定するために使用できるため、サードパーティ コントロールのアプリケーションで機能するはずです。

ここに別のオプションがあります - 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++>");

    }

そのテキストボックスのクラス名がわからない場合は、spy++を使用できます

于 2012-11-15T09:30:20.023 に答える
1

コンポーネントにフォーカスを当てようとしたときにコンポーネントが表示されていますか?

Form.Loadイベント ハンドラーでフォーカスを設定しようとしている場合は、Form.Shown代わりにハンドラーに移動してみてくださいControl.Enter

動作の違いは、タイミングの問題に起因する可能性があります。その他のアイデアについては、開始フォームでイベントが発生する順序について MSDNを参照してください。

于 2012-11-16T06:58:14.780 に答える