Я создаю глобальную горячую клавишу, чтобы показать окно с помощью PInvoking RegisterHotKey()
. Но для этого мне нужно это окно HWND
, которое не существует до тех пор, пока окно не будет загружено, это означает, что показано в первый раз. Но я не хочу показывать окно, прежде чем я могу установить горячую клавишу. Есть ли способ создать HWND
для этого окна, которое невидимо для пользователя?Загрузка окна WPF без его отображения
ответ
Если вы ориентируетесь .NET 4.0 вы можете использовать новый метод EnsureHandle
доступный на WindowInteropHelper
:
public void InitHwnd()
{
var helper = new WindowInteropHelper(this);
helper.EnsureHandle();
}
(благодаря Томасу Левескё для pointing this out.)
Если вы ориентируетесь старую версию .NET Framework, самый простой способ, чтобы открыть окно, чтобы добраться до HWND при установке нескольких свойств, чтобы убедиться, что окно невидимо и не ворует фокус:
var window = new Window() //make sure the window is invisible
{
Width = 0,
Height = 0,
WindowStyle = WindowStyle.None,
ShowInTaskbar = false,
ShowActivated = false
};
window.Show();
После того, как вы хотите, чтобы показать фактическое окно, которое вы можете установить содержание, размер и изменить стиль обратно в обычное окно.
Класс WindowInteropHelper должен позволить вам получить HWND для окна WPF.
MyWindow win = new MyWindow();
WindowInteropHelper helper = new WindowInteropHelper(win);
IntPtr hwnd = helper.Handle;
Это то, что я делаю, но таким образом, Окно еще не имеет HWND, поэтому helper.Handle 0, что не то, что мне нужно. – svick
Я никогда не пытался делать то, что вы делаете, но если вам нужно, чтобы показать окно, чтобы получить HWND, но не хочу показать это, установите Непрозрачность окна до 0. Это также предотвратит появление любого теста на наличие ударов. Тогда у вас может быть открытый метод в окне, чтобы изменить непрозрачность до 100, когда вы хотите сделать его видимым.
Это своего рода грязный хак, но он будет работать точно. –
К сожалению, для того, чтобы параметр Opacity был эффективным, AllowsTransparency должен быть установлен в true, а это, в свою очередь, вынуждает WindowStyle к WindowStyle.None, чего я не хочу. Кроме того, AllowsTransparency нельзя изменить после отображения окна, поэтому я не могу установить его обратно. – svick
Другим вариантом в аналогичном ключе для установки непрозрачности 0 является установка размера 0 и установка положения на экране. Для этого не требуется AllowsTransparency = True.
Также помните, что как только вы показали его, как только сможете, спрячьте его и все еще получите hwnd.
Это грязный хак, но он должен работать, и не имеет минусы изменения непрозрачности:
- Установите
WindowStartupLocation
вManual
- установить
Top
иLeft
свойства где-то за пределами экран - установить
ShowInTaskbar
ложь, так что пользователь не понимает, есть новое окно Show
иHide
й е окно
Теперь вы должны быть в состоянии восстановить HWND
EDIT: еще один вариант, вероятно, лучше: установить ShowInTaskBar
ложь и WindowState
в Minimized
, а затем показать его: он не будет виден на всех
+1 ShowInTaskBar = false и WindowState = Минимизированные работы. –
С помощью вашего другого варианта я вижу окно, свернутое в левом нижнем углу экрана. Но первый выглядит многообещающим. – svick
@svick: какую ОС вы используете? В Windows 7 свернутое окно не видно –
Сделайте размер окна 0 x 0 px, поместите ShowInTaskBar в значение false, покажите его, а затем измените его размер по мере необходимости.
Я ничего не знаю о WPF, но могли бы вы создать message only window другими способами (например, PInvoke) для получения сообщения WM_HOTKEY? Если да, то после получения WM_HOTKEY вы можете запустить окно WPF оттуда.
+1, вы можете просто использовать окно Winforms в другом потоке, если хотите это сделать. –
Вы также можете изменить окно в так называемое окно только для сообщений. Поскольку этот тип окна не поддерживает графические элементы, он никогда не будет показан. В основном это сводится к телефону:
SetParent(hwnd, (IntPtr)HWND_MESSAGE);
Либо создать специальное окно сообщения, которое всегда будет скрыто, или использовать окно реального GUI и изменить его обратно в обычное окно, когда вы хотите, чтобы отобразить его. Более полный пример приведен ниже.
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hwnd, IntPtr hwndNewParent);
private const int HWND_MESSAGE = -3;
private IntPtr hwnd;
private IntPtr oldParent;
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
if (hwndSource != null)
{
hwnd = hwndSource.Handle;
oldParent = SetParent(hwnd, (IntPtr)HWND_MESSAGE);
Visibility = Visibility.Hidden;
}
}
private void OpenWindowMenuItem_Click(object sender, RoutedEventArgs e)
{
SetParent(hwnd, oldParent);
Show();
Activate();
}
Для меня решение установки ширины, высоты до нуля и стиля никто ничего не вышло, так как он еще показал крошечное окно с раздражающей тенью того, что, кажется, граница вокруг Окно 0x0 (протестировано в Windows 7). Поэтому я предоставляю этот альтернативный вариант.
Это, кажется, единственное 100% решение. –
Спасибо за этот замечательный совет.Это действительно помогло мне, потому что все другие решения здесь вызвали некоторые побочные эффекты, которые были не очень хорошими. Но, к сожалению, у вас тоже. У меня есть MetroWindow (с использованием Fluent Ribbon Suite). Впоследствии окно имеет типичную рамку окна, которая обычно не видна для этих MetroWindows ... Любая идея, как это решить? – SharpShade
Perfect. Это просто нужно: ShowActivated = false; после видимости, потому что без него он мигает. – blez
Я уже опубликовал ответ на этот вопрос, но я нашел лучшее решение.
Если вам просто нужно, чтобы убедиться, что HWND создается, фактически не показывая окно, вы можете сделать это:
public void InitHwnd()
{
var helper = new WindowInteropHelper(this);
helper.EnsureHandle();
}
(на самом деле метод EnsureHandle
не был доступен, когда вопрос был размещен, он был введен в .NET 4.0)
красиво сделано Томас – tofutim
это, вероятно, должно быть принятым ответом сейчас, или я должен обновить свой ответ, чтобы включить это также? не уверен, что уважаемая практика касается различий в версиях каркаса. –
@PatrickKlug, я тоже не знаю ... Вы можете включить это в свой ответ или просто указать мой ответ, в зависимости от того, что вы считаете лучшим. –
Я создал метод расширения для отображения невидимого окна, следующие вызовы Show
будут вести себя нормально.
public static class WindowHelper
{
public static void ShowInvisible(this Window window)
{
// saving original settings
bool needToShowInTaskbar = window.ShowInTaskbar;
WindowState initialWindowState = window.WindowState;
// making window invisible
window.ShowInTaskbar = false;
window.WindowState = WindowState.Minimized;
// showing and hiding window
window.Show();
window.Hide();
// restoring original settings
window.ShowInTaskbar = needToShowInTaskbar;
window.WindowState = initialWindowState;
}
}
- 1. Предварительная загрузка окна WPF
- 2. Создание окна в Pygame без отображения его
- 3. Загрузка URL из WebView без его отображения
- 4. Окно печати WPF без отображения его
- 5. Преобразование экрана в координаты WPF без отображения окна
- 6. Возможно ли запустить приложение командной строки без отображения его окна?
- 7. Загрузка содержимого XAML без нового окна
- 8. WPF: печать FlowDocument без диалогового окна печати
- 9. ASP.NET - открыть файл без отображения диалогового окна
- 10. tkinter - установить геометрию без отображения окна
- 11. Android: Asynctask без отображения диалогового окна
- 12. Как запустить сценарий PowerShell без отображения окна?
- 13. Закрытие приложения без отображения окна консоли
- 14. Миниатюра панели задач Windows7 без отображения окна
- 15. Запуск вино без отображения окна GUI
- 16. Закрытие окна с его операциями в WPF
- 17. автоматическое открытие нового окна без таймера WPF
- 18. Показать Загрузка окна jQuery
- 19. Понять события окна WPF
- 20. Загрузка значков из заданного пути для отображения в окне WPF
- 21. Получить титул веб-сайта без отображения его
- 22. Обновить тип отображения ElasticSearch без его удаления
- 23. Как использовать OpenGL без его отображения?
- 24. PHP Включить файл без отображения его содержимого
- 25. Снимок экрана с изображением без его отображения
- 26. Остановка окна Tkinter без его закрытия
- 27. Как изменить прямоугольник окна без его перерисовки
- 28. Java - Как сохранить его без консольного окна
- 29. C++ Перемещение окна без изменения его размера
- 30. WPF: выбранные элементы ListView после отображения диалогового окна
Да, это работает, спасибо. Установка WindowState даже не требуется. Кроме того, я установил содержимое окна в XAML, но это не важно. Другое дело, что WindowStartupLocation = CenterScreen работает неправильно, но это легко исправить. – svick
удалил установщик WindowState ... спасибо, что позволил мне узнать. –
Я бы добавил 'ResizeMode = ResizeMode.NoResize', потому что он удаляет границу окна для изменения размера. – schnaader