WPF подписывается на WM_QUERYENDSESSION перед созданием окнаC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 WPF подписывается на WM_QUERYENDSESSION перед созданием окна

Сообщение Anonymous »

У меня есть приложение WPF, в котором окно не видно на протяжении всего выполнения программы — на самом деле его экземпляр может даже не быть создан. Я хотел бы получать сообщения WM_QUERYENDSESSION и что-то делать с ними, но не могу понять, как это сделать.
Я пытался создать новый проект WPF с помощью App.xml .cs следующим образом:

Код: Выделить всё

public partial class App : Application
{
private const int WM_QUERYENDSESSION = 0x0011;
private HwndSource _hwndSource;

protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

Log.Logger = new LoggerConfiguration().WriteTo.File("D:\\Something\\Test.log").CreateLogger();
Log.Information("Starting");

CreateHiddenWindow();
}

private void CreateHiddenWindow()
{
Window hiddenWindow = new Window
{
Width = 0,
Height = 0,
ShowInTaskbar = false,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent
};

hiddenWindow.SourceInitialized += (s, e) =>
{
_hwndSource = (HwndSource)PresentationSource.FromVisual(hiddenWindow);
_hwndSource.AddHook(WndProc);
hiddenWindow.Hide();
};

hiddenWindow.Show();
}

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
Log.Information($"WndProc received message: {msg}");
if (msg == WM_QUERYENDSESSION)
{
Log.Information("WM_QUERYENDSESSION received in WndProc");
Log.Information("Handled WM_QUERYENDSESSION, flushing logs...");
Log.CloseAndFlush();

handled = true;
}
return IntPtr.Zero;
}
}
И это работает... но сначала требуется запустить скрытое окно. Я тоже пробовал:

Код: Выделить всё

public partial class App : Application
{
private const int WM_QUERYENDSESSION = 0x0011;

protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

Log.Logger = new LoggerConfiguration().WriteTo.File("D:\\Something\\Test.log").CreateLogger();
Log.Information("Starting");

ComponentDispatcher.ThreadFilterMessage += OnThreadFilterMessage;
}

private void OnThreadFilterMessage(ref MSG msg, ref bool handled)
{
Log.Information(msg.message.ToString());
if (msg.message == WM_QUERYENDSESSION)
{
Log.Information("WM_QUERYENDSESSION received in OnThreadFilterMessage");
Log.Information("Handled WM_QUERYENDSESSION, flushing logs...");

Log.CloseAndFlush();

handled = true;
}
}
}
Но второй способ не работает. Как я могу заставить это работать без экземпляра Window?
РЕДАКТИРОВАТЬ
По "не работает" я означает, что я получаю много сообщений, но не получаю сообщений WM_QUERYENDSESSION.

Подробнее здесь: https://stackoverflow.com/questions/787 ... is-created
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»