Произвольные окна
FAQ по UI и .Net
Если диалоговых окон iikoFront API недостаточно, плагин может показывать собственные окна, однако, необходимо учитывать некоторые нюансы.
Во-первых, хост-процесс плагина по умолчанию не содержит необходимого для UI STA-потока. Плагин должен создать его самостоятельно. Пример кода:
ctor()
{
var windowThread = new Thread(EntryPoint);
windowThread.SetApartmentState(ApartmentState.STA);
windowThread.Start();
}
...
private void EntryPoint()
{
Window window = new MyWindow();
window.ShowDialog();
}
Во-вторых, открытое фоновым процессом окно по умолчанию не имеет фокуса, поэтому события ввода будут направлены прежнему активному окну (то есть окну iikoFront). По задумке Microsoft, приложение не может стать активным само по себе, эстафету ему может передать только предыдущее активное окно, либо фокус может назначить пользователь. Однако, последнее можно имитировать программно:
public static void ClickWindow(Window wnd)
{
try
{
var wih = new WindowInteropHelper(wnd);
WinApi.RECT rect;
WinApi.GetWindowRect(new HandleRef(wnd, wih.Handle), out rect);
var x = rect.Left + (rect.Right - rect.Left) / 2;
var y = rect.Top + (rect.Bottom - rect.Top) / 4;
WinApi.LeftMouseClick(x, y);
}
catch (Exception) { }
}
В-третьих, окно плагина, будучи независимым окном, может оказаться позади окна iikoFront. Режим отображения поверх всех окон — тоже не панацея, потому что могут быть и другие topmost-окна (в том числе само приложение iikoFront). Плагин может привязать своё окно как дочернее к окну iikoFront через WinApi-функцию SetParent
. Хотя в API не публикуется hwnd фронтового окна, плагин может самостоятельно его найти.