I need to get back to foreground window, that was active before my app window, I tryed to use user32.dll for this, but i can’t find previous window 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);
and i get only “default IME” or “M” in next window, how can i found real app window?
i’ve loop thrue windows, to find my notepad window:
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++
I’ve got the solution with 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);
}
The Z-Order of windows has no direct relationship to when they were activated or switched to/from.
The correct way to get the hWnd of the previously active window is to handle the
WM_ACTIVATEmessage. The previous hWnd will be passed in thelParamvalue.