Показать форму без кражи фокуса?

Я использую форму для показа уведомлений (она отображается в правом нижнем углу экрана), но когда я показываю эту форму, она крадет фокус из основной формы. Есть ли способ показать эту форму «уведомления» без кражи фокуса?

Хм, не просто переопределить Form.ShowWithoutActivation достаточно?

protected override bool ShowWithoutActivation { get { return true; } } 

И если вы не хотите, чтобы пользователь щелкал это окно уведомления, вы можете переопределить CreateParams:

 protected override CreateParams CreateParams { get { CreateParams baseParams = base.CreateParams; const int WS_EX_NOACTIVATE = 0x08000000; const int WS_EX_TOOLWINDOW = 0x00000080; baseParams.ExStyle |= ( int )( WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW ); return baseParams; } } 

Украден из метода ShowWindow из PInvoke.net :

 private const int SW_SHOWNOACTIVATE = 4; private const int HWND_TOPMOST = -1; private const uint SWP_NOACTIVATE = 0x0010; [DllImport("user32.dll", EntryPoint = "SetWindowPos")] static extern bool SetWindowPos( int hWnd, // Window handle int hWndInsertAfter, // Placement-order handle int X, // Horizontal position int Y, // Vertical position int cx, // Width int cy, // Height uint uFlags); // Window positioning flags [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); static void ShowInactiveTopmost(Form frm) { ShowWindow(frm.Handle, SW_SHOWNOACTIVATE); SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST, frm.Left, frm.Top, frm.Width, frm.Height, SWP_NOACTIVATE); } 

(Алекс Лайман ответил на это, я просто расширяю его, просто вставляя код. Кто-то с правами редактирования может его скопировать и удалить для меня все, что мне нужно;))

Если вы хотите использовать Win32 P / Invoke , вы можете использовать метод ShowWindow (первый пример кода делает именно то, что вы хотите).

Выполнение этого похоже на хак, но, похоже, он работает:

 this.TopMost = true; // as a result the form gets thrown to the front this.TopMost = false; // but we don't actually want our form to always be on top 

Изменить: обратите внимание, что это просто создает уже созданную форму без кражи фокуса.

Это то, что сработало для меня. Он обеспечивает TopMost, но без фокуса.

  protected override bool ShowWithoutActivation { get { return true; } } private const int WS_EX_TOPMOST = 0x00000008; protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; createParams.ExStyle |= WS_EX_TOPMOST; return createParams; } } 

Не забудьте опустить настройку TopMost в дизайнере Visual Studio или в другом месте.

Это украдено, ошибочно, заимствовано отсюда (нажмите «Обходные пути»):

https://connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost

Образец кода из pinvoke.net в ответах Alex Lyman / TheSoftwareJedi сделает окно «самым верхним» окном, что означает, что после его появления вы не сможете поместить его в нормальные windows. Учитывая описание Матиаса того, что он хочет использовать, это может быть то, что он хочет. Но если вы хотите, чтобы пользователь мог поместить ваше окно за другие windows после того, как вы его всплыли, просто используйте HWND_TOP (0) вместо HWND_TOPMOST (-1) в образце.

В WPF вы можете решить это следующим образом:

В окне поместите эти атрибуты:

   

Последний атрибут – тот, который вам нужен. ShowActivated = “False”.

Создайте и запустите форму уведомления в отдельном streamе и верните фокус обратно в свою основную форму после открытия формы. У формы уведомлений есть событие OnFormOpened, которое запускается из события Form.Shown . Что-то вроде этого:

 private void StartNotfication() { Thread th = new Thread(new ThreadStart(delegate { NotificationForm frm = new NotificationForm(); frm.OnFormOpen += NotificationOpened; frm.ShowDialog(); })); th.Name = "NotificationForm"; th.Start(); } private void NotificationOpened() { this.Focus(); // Put focus back on the original calling Form } 

Вы также можете сохранить дескриптор объекта NotifcationForm, чтобы он мог программно закрываться основной формой ( frm.Close() ).

Некоторые детали отсутствуют, но, надеюсь, это заставит вас идти в правильном направлении.

Возможно, вам захочется рассмотреть, какое уведомление вы хотите отобразить.

Если абсолютно важно сообщить пользователю о каком-либо событии, использование Messagebox.Show было бы рекомендуемым способом, из-за его характера блокировать любые другие события в главном окне, пока пользователь не подтвердит это. Однако помните о всплывающей слепоте.

Если это менее критично, вы можете использовать альтернативный способ отображения уведомлений, например панель инструментов в нижней части windows. Вы написали, что вы показываете уведомления в правом нижнем углу экрана – стандартный способ сделать это – использовать воздушный шар с комбинацией значка в системном трее .

У меня что-то похожее, и я просто показываю форму уведомления, а затем делаю

 this.Focus(); 

чтобы снова обратить внимание на основную форму.

Это хорошо работает:

 [System.Runtime.InteropServices.DllImport("user32")] public static extern long OpenIcon(long hwnd); [System.Runtime.InteropServices.DllImport("user32")] public static extern long SetForegroundWindow(long hwnd); public static void ActivateInstance() { long MyHndl = 0; long result = 0; Process objProcess = Process.GetCurrentProcess(); MyHndl = objProcess.MainWindowHandle.ToInt32(); result = OpenIcon(MyHndl); // Restore the program. result = SetForegroundWindow(MyHndl); // Activate the application. //System.Environment.Exit(0); // End the current instance of the application. } 

Вы можете справиться с этим только по логике, хотя я должен признать, что предложения, приведенные выше, когда вы заканчиваете метод BringToFront без фактического кражи фокуса, являются самыми изящными.

Во всяком случае, я столкнулся с этим и решил его, используя свойство DateTime, чтобы не допустить дальнейших вызовов BringToFront, если вызовы были сделаны уже недавно.

Предположим, что основной class – «Core», который обрабатывает, например, три формы: «Form1, 2 и 3». Для каждой формы требуется свойство DateTime и событие Activate, которое вызывает Core для вывода окон на передний план:

 internal static DateTime LastBringToFrontTime { get; set; } private void Form1_Activated(object sender, EventArgs e) { var eventTime = DateTime.Now; if ((eventTime - LastBringToFrontTime).TotalMilliseconds > 500) Core.BringAllToFront(this); LastBringToFrontTime = eventTime; } 

А затем создайте работу в Core Class:

 internal static void BringAllToFront(Form inForm) { Form1.BringToFront(); Form2.BringToFront(); Form3.BringToFront(); inForm.Focus(); } 

Если вы хотите восстановить свернутое окно в исходное состояние (не максимизировано), используйте:

 inForm.WindowState = FormWindowState.Normal; 

Опять же, я знаю, что это просто исправление в отсутствие BringToFrontWithoutFocus. Это означает, что вы хотите избежать DLL-файла.

Я не знаю, считается ли это некроположением, но это то, что я сделал с тех пор, как не смог заставить его работать с методами «ShowWindow» и «SetWindowPos» user32. И нет, переопределение «ShowWithoutActivation» не работает в этом случае, так как новое окно должно быть всегда на вершине. Во всяком случае, я создал вспомогательный метод, который принимает форму как параметр; при вызове он показывает форму, выводит ее на передний план и делает ее TopMost без кражи фокуса текущего windows (видимо, это так, но пользователь не заметит).

  [DllImport("user32.dll")] static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] static extern IntPtr SetForegroundWindow(IntPtr hWnd); public static void ShowTopmostNoFocus(Form f) { IntPtr activeWin = GetForegroundWindow(); f.Show(); f.BringToFront(); f.TopMost = true; if (activeWin.ToInt32() > 0) { SetForegroundWindow(activeWin); } } 

Я знаю, это может показаться глупым, но это сработало:

 this.TopMost = true; this.TopMost = false; this.TopMost = true; this.SendToBack(); 

Мне нужно было сделать это с моим окном TopMost. Я применил метод PInvoke выше, но обнаружил, что мое событие Load не получило вызова как Talha выше. Я, наконец, добился успеха. Может быть, это поможет кому-то. Вот мое решение:

  form.Visible = false; form.TopMost = false; ShowWindow(form.Handle, ShowNoActivate); SetWindowPos(form.Handle, HWND_TOPMOST, form.Left, form.Top, form.Width, form.Height, NoActivate); form.Visible = true; //So that Load event happens 

Когда вы создаете новую форму, используя

 Form f = new Form(); f.ShowDialog(); 

он крадет фокус, потому что ваш код не может продолжать выполнение в основной форме до тех пор, пока эта форма не будет закрыта.

Исключением является использование threading для создания новой формы, а затем Form.Show (). Убедитесь, что stream глобально виден, потому что, если вы объявите его в функции, как только ваша функция выйдет, ваш stream закончится, и форма исчезнет.

window.WindowState = WindowState.Minimized; это: window.WindowState = WindowState.Minimized; ,

  • Как обеспечить отображение формы на «дополнительном» мониторе в сценарии с двумя мониторами?
  • Изменить цвет границы в TextBox C #
  • Ribbon UI Control для WinForms
  • Закругленные края в кнопке C # (WinForms)
  • Несколько streamов пользовательского интерфейса - Winforms
  • process.WaitForExit () асинхронно
  • Вызвать метод из другой формы
  • Как убить stream мгновенно в C #?
  • C # listView, как добавить элементы в столбцы 2, 3 и 4 и т. Д.?
  • Как приостановить рисование для элемента управления и его детей?
  • Как изменить список избранных строк, даже если вы фокусируетесь на другом элементе управления?
  • Interesting Posts

    Нажатие на Уведомление не запускает намеченную активность?

    Ярлык клавиатуры для правого клика в Mac OS X

    Почему строки возвращаются с помощью «объяснения», не равны count ()?

    jQuery исключает элементы с определенным classом в селекторе

    Получить части NSURL в объективе c

    Excel VBA: диапазон до строкового массива в 1 шаг

    .net XML Serialization – Сохранение ссылки вместо копирования объектов

    Многослойное стекло GlassPane в корневом контейнере

    как блокировать виртуальную клавиатуру при нажатии на edittext в android?

    Работа с несколькими пользовательскими шаблонами таблиц, исключающими повторяющийся код

    AsyncTask: где возвращается возвращаемое значение doInBackground ()?

    Ошибка Mysql 1452 – Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполняется

    Android GCM отправлен успешно, но не принят на некоторых устройствах

    Как перебирать имена файлов, возвращаемые find?

    Полноэкранные цифровые часы для DOS 6.22?

    Давайте будем гением компьютера.