C#将焦点返回到上一个窗口

时间:2012-03-01 15:00:09

标签: c# winapi

我需要回到前台窗口,在我的应用程序窗口之前处于活动状态,我尝试使用user32.dll,但我找不到以前的窗口hendle。

   [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);

    [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
    public static extern IntPtr GetWindow(IntPtr hwnd, uint wFlag);

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetFocus();

    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    public static extern IntPtr SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern bool PostMessage(IntPtr hWnd, int Msg, char wParam, int lParam);

    [DllImport("user32")]
    public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

    [DllImport("user32")]
    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern uint GetCurrentThreadId();
     ...
        hMe = GetForegroundWindow();
        hNext = GetNextWindow(hMe, hw_next);
        System.Text.StringBuilder window = new StringBuilder(32);
        GetWindowText(hNext, window, 32);

我在下一个窗口中只得到“默认IME”或“M”,我怎样才能找到真正的应用程序窗口?

我循环投掷窗口,找到我的记事本窗口:

0: D:\univer\C#
1: 
2: 
3: 
4: 
5: 
6: Главное меню
7: 
8: 
9: M
10: Default IME
11: 
12: 
13: 
14: CiceroUIWndFrame
15: 
16: 
17: 
18: SysFader
19: SysFader
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: SysFader
36: 
37: 
38: HDMI Settings
39: S/PDIF IN/OUT Settings
40: Set Device Type
41: Mixer ToolBox
42: Параметры разъёма
43: CiceroUIWndFrame
44: TF_FloatingLangBar_WndTitle
45: Syn Zoom Window
46: Syn Visual Window
47: 
48: 
49: Начать отладку (F5)
50: M
51: Default IME
52: 
53: 
54: 
55: 
56: 
57: 
58: *new  2 - Notepad++

我已经得到了Hook的解决方案:

    delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

    [DllImport("user32.dll")]
    static extern bool UnhookWinEvent(IntPtr hWinEventHook);

    [DllImport("user32.dll")]
    static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);


 private static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        uint id = 0;
        if (eventType == EVENT_SYSTEM_FOREGROUND)
        {
            if (hwnd != _this.hKeyboard && hwnd != _this.hLast && hwnd != IntPtr.Zero)
            {
                _this.hLast = hwnd;

            }
        }
    }
 ...
 Form1_load(){
    _WinEvent = new WinEventDelegate(WinEventProc);
    mHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, _WinEvent, 0, 0, WINEVENT_OUTOFCONTEXT);
 }

1 个答案:

答案 0 :(得分:2)

Windows的Z顺序与它们被激活或切换到/从时没有直接关系。 获取先前活动窗口的hWnd的正确方法是处理WM_ACTIVATE消息。之前的hWnd将以lParam值传递。