2013-06-25 2 views
5

Я пытаюсь сохранить одно конкретное окно WPF в фокусе, что означает, что он не должен менять стиль окна при потере фокуса (например, как стандартная панель задач Windows). Для этого я подключаюсь к WndProc, чтобы проверить, установлено ли значение WM_NCACTIVATE1010 или WM_ACTIVATE на false (wParam == 0), а затем отметьте сообщение как handled = true;, чтобы заблокировать Окно от неактивности. Вот несколько примеров кода:Обработка WM_NCACTIVATE в стартовом окне блокирует все остальные окна

void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    var source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 
    if (source != null) source.AddHook(WndProc); 
} 

private const uint WM_NCACTIVATE = 0x0086; 
private const int WM_ACTIVATE = 0x0006; 
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    if (msg == WM_NCACTIVATE) 
    { 
     if (wParam == new IntPtr(0)) 
      handled = true; 
    } 
    if (msg == WM_ACTIVATE) 
    { 

     if (wParam == new IntPtr(0)) 
      handled = true; 
    } 
    return IntPtr.Zero; 
} 

Однако, делая это, все остальные WPF окна, которые создаются внутри главного окна

var f = new Window(); 
f.ShowDialog(); 

никогда не получают фокус и хотя они видимы, окно делает не реагировать на ввод пользователя как в клиентской области, так и для кнопки минимизации, максимизации и закрытия Windows. Я, очевидно, что-то делаю неправильно, поэтому любые советы или указатели на то, как это сделать правильно?

+0

код просто не делать то, что вы надеетесь, что он делает. Это просто препятствует WPF видеть сообщение. Окно все еще активировано, но WPF этого не знает. Так безнадежно запутался. Для предотвращения деактивации окна требуется гораздо большее оружие, которое не имеет WPF. –

+0

Да, это то, чего я ожидал. Итак, что было бы лучшим способом приблизиться к этому? – dsfgsho

+0

Подход * what *? На панели задач нет «стиля», поэтому совершенно непонятно, какую проблему вы пытаетесь решить. WPF напрямую не поддерживает создание панелей задач, вы создаете их, вызывая SHAppBarMessage(). Это хорошо работает. –

ответ

4

Решение сохраняя визуальный стиль окна WPF для активной, даже если окно теряет фокус, чтобы справиться с WM_NCACTIVATE так:

private const uint WM_NCACTIVATE = 0x0086; 

private IntPtr WndProc(IntPtr hwnd, int msg, 
     IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    var returnvalue = IntPtr.Zero; 
    if (msg == WM_NCACTIVATE) 
    { 
     //replace the wParam (true/false) which indicates 
      //active/inactive with always true 
     returnvalue = DefWindowProc(hwnd, WM_NCACTIVATE, 
        new IntPtr(1), new IntPtr(-1)); 
     handled = true; 
    } 
} 


[DllImport("user32.dll")] 
static extern IntPtr DefWindowProc(IntPtr hWnd, WindowsMessages uMsg, IntPtr wParam, IntPtr lParam);