了解AttachThreadInput - 分离失去焦点 [英] Understanding AttachThreadInput - detaching lose focus

查看:2616
本文介绍了了解AttachThreadInput - 分离失去焦点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小问题完全理解AttachThreadInput。

i got a little problem fully understanding AttachThreadInput.

我知道它的连接的2个线程,消息队列它(我想做的事情)让我例如,迫使我在前台窗口(的WinForms)

I know it's "connecting" the message queue of 2 threads, which (what i want to do) allows me for example to force my window (winforms) in foreground.

我可以用这种方法做的:

Which I can do with this method:

private void SetForegroundWindowEx(IntPtr hWnd)
{
    uint SW_SHOW = 5;
    uint appThread = GetCurrentThreadId();     
    uint foregroundThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);         

    if (foregroundThread != appThread)
    {
        AttachThreadInput(foregroundThread, appThread, true);

        BringWindowToTop(hWnd);
        ShowWindow(hWnd, SW_SHOW);       
        AttachThreadInput(foregroundThread, appThread, false);

    }
    else
    {
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, SW_SHOW);
    }
}



不过这两个窗口的失去,一旦集中的线程分离。

However both of the windows lose focus as soon as the threads detach.

如果我等待消息队列为空(Application.DoEvents()),并激活我的窗口(这是现在在前台,但不集中),它会恢复焦点,并保持它。

If I wait for the message queue to empty (Application.DoEvents()) and activate my window (which is now in foreground but not focused) it will regain the focus and keep it.

如果我的消息队列之前做到这一点是空的,将失去再次对焦。

If I do it before the message queue is empty it will lose focus again.

所以我猜拆卸的东西需要从我的窗户的焦点,但我不知道那是什么或如何防止它。

So I would guess something of the detaching takes the focus from my windows but i have no idea what that is or how to prevent it.

这是第一次。事情我不明白

This is the first thing I do not quite understand.

我不明白的第二件事是,如果我没有我的窗口设置为前景:

The second thing I do not get is, if I do not set my window to foreground:

AttachThreadInput(foregroundThread, appThread, true);

AttachThreadInput(foregroundThread, appThread, false);
Application.DoEvents();
this.Activate();



等待消息队列为空,并激活我的窗口(这一次是不是在前台和其他窗口仍具有焦点),它实际上被激活,即使线程不再连接。

wait for the message queue to empty, and activate my window (this time it is not in foreground and the other window still has the focus), it actually gets activated, even though the threads are not attached anymore.

也许有人能够更好地了解AttachThreadInput可以回答我这些2提问

perhaps someone with a better understanding of AttachThreadInput can answer me these 2 questions.

信息:结果
我要偷的焦点在这种情况下,因为我的应用程序被称为通过一个API。调用我的,其他的应用程序等待来自我的应用程序的反馈,并在大部分时间冻结,直到它得到的信息。

INFO:
I need to steal the focus in this case, because my app gets called via an API. The other app that calls mine, waits for feedback from my app and in most times freezes until it gets the info.

在情况下,其他的应用程序是全屏许多用户不注意在任务栏的闪烁,并认为其他的应用程序崩溃,并与Taskmamanger杀死它。因为我不一定比其他应用程序的控制,我不能告诉你它设置焦点我的窗前。

In case the other app is Fullscreen many user do not notice the blinking in the taskbar and think the other app crashed and kill it with the Taskmamanger. Since i do not necessarily have control over the other app, i cannot tell it to set the focus to my window.

这方法不会被调用,如果它不是absolutelly必要的,在这种情况下这种行为,这是敌对的,我知道,作为深受我想为用户。

This method won't get called if it is not absolutelly necessary, in this case this behavior, which is hostile, i know that, is as well wanted by myself as by the user.

推荐答案

下面是一张我用为同一目的的C#代码。我想指出有合法的情况下,当这可能是必需的。在我们的情况,这是微软Word的自动化。每当用户点击我们的应用程序内的工具栏按钮,我们应该立即将Word窗口到用户的关注。

Here's a piece of c# code I use for the same purpose. I'd like to note there are legitimate cases when this may be required. In our situation, it was MS Word automation. Whenever user clicks a toolbar button inside our app, we should immediately bring the Word window up to the user's attention.

public static void ForceWindowIntoForeground(IntPtr window)
{
    uint currentThread = Win32.GetCurrentThreadId();

    IntPtr activeWindow = Win32.GetForegroundWindow();
    uint activeProcess;
    uint activeThread = Win32.GetWindowThreadProcessId(activeWindow, out activeProcess);

    uint windowProcess;
    uint windowThread = Win32.GetWindowThreadProcessId(window, out windowProcess);

    if (currentThread != activeThread)
        Win32.AttachThreadInput(currentThread, activeThread, true);
    if (windowThread != currentThread)
        Win32.AttachThreadInput(windowThread, currentThread, true);

    uint oldTimeout = 0, newTimeout = 0;
    Win32.SystemParametersInfo(Win32.SPI_GETFOREGROUNDLOCKTIMEOUT, 0, ref oldTimeout, 0);
    Win32.SystemParametersInfo(Win32.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ref newTimeout, 0);
    Win32.LockSetForegroundWindow(LSFW_UNLOCK);
    Win32.AllowSetForegroundWindow(Win32.ASFW_ANY);

    Win32.SetForegroundWindow(window);
    Win32.ShowWindow(window, Win32.SW_RESTORE);

    Win32.SystemParametersInfo(Win32.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ref oldTimeout, 0);

    if (currentThread != activeThread)
        Win32.AttachThreadInput(currentThread, activeThread, false);
    if (windowThread != currentThread)
        Win32.AttachThreadInput(windowThread, currentThread, false);
}

这篇关于了解AttachThreadInput - 分离失去焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆