Returning to Window previously selected before clicking Notification Area Icon

浪子不回头ぞ 提交于 2020-01-05 10:28:53

问题


I have built an application that has a Notification Area Icon, which when clicked brings up a form that is designed for a single click, after which the user can then return to what they where doing before hand.

Currently, I am using this.Hide() to remove the form (either when the desired event in the form occurs, or when the form is Deactivated), but when I do, Windows sets the users focus to the Task Bar. How can I get it to return the Users focus to the Window they where on before clicking on the Notification Area Icon?


回答1:


I have managed to find out how. I used the following code:

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int SetForegroundWindow(IntPtr hwnd);

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern IntPtr GetWindow(IntPtr hwnd, int wFlag);

private void switchToLast() {
    IntPtr thisWindow = GetForegroundWindow();
    IntPtr lastWindow = GetWindow(thisWindow, 3);
    SetForegroundWindow(lastWindow);
    this.Hide();
}

I found numerous references to the problem, and this is what I have so far. The main difference between this and other examples I have found is the line GetWindow(thisWindow, 3), where the second was 2 in other examples, I have changed this to 3. I believe this is because having it set to 2 was getting the Pointer to the TaskBar.




回答2:


Rather than trying to figure this out after the fact, you should determine it at the outset when your app is first receiving the focus. In other words, the sooner you figure it out the better.

The obvious solution would be to handle either the WM_SETFOCUS or WM_ACTIVATE messages, which pass the handle to the previously-active window as the lParam. Unfortunately, this works only for windows in the same thread; otherwise, the lParam will be NULL.

So you need to use WM_ACTIVATEAPP, which passes the identifier of the thread that owns the window being deactivated as the lParam. Once you have the thread identifier, use the GetGUIThreadInfo function to determine the active window in that thread. This works regardless of which process owns the window, so it is not subject to the limitations discussed above for WM_SETFOCUS and WM_ACTIVATE.

Keep track of this window handle, and simply restore focus to it when you are finished.



来源:https://stackoverflow.com/questions/16048088/returning-to-window-previously-selected-before-clicking-notification-area-icon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!