2013-06-25 8 views
5

Próbuję zachować jedno konkretne okno WPF w centrum uwagi, co oznacza, że ​​nie powinien zmieniać stylu okna po utracie fokusa (np. Jak standardowy pasek zadań systemu Windows). Aby to osiągnąć, podłączam się do WndProc, aby sprawdzić, czy WM_NCACTIVATE lub WM_ACTIVATE jest ustawiony na false (wParam == 0), a następnie oznaczyć wiadomość jako handled = true;, aby zablokować okno z nieaktywnością. Oto przykładowy kod:Obsługa WM_NCACTIVATE w oknie startowym blokuje wszystkie pozostałe okna.

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; 
} 

Jednak robiąc to, wszystkie pozostałe okna WPF, które są tworzone z poziomu tego okna głównego

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

nigdy stawać i choć są one widoczne, okno robi nie reaguje na dane wprowadzane przez użytkownika zarówno w obszarze roboczym, jak i na przycisk minimalizacji, maksymalizacji i zamykania systemu Windows. Oczywiście robię coś złego, więc wszelkie rady lub wskazówki, jak to zrobić we właściwy sposób?

+0

Kod prostu nie robi tego, co masz nadzieję, że tak. Zapobiega wyświetlaniu wiadomości tylko przez WPF. Okno jest nadal aktywne, ale WPF go nie zna. Więc staje się beznadziejnie zdezorientowany. Zapobieganie dezaktywacji okna wymaga znacznie większej broni, której nie ma WPF. –

+0

Tak, właśnie tego się spodziewałem. Więc jaki byłby lepszy sposób podejścia do tego? – dsfgsho

+0

Podejście * co *? Pasek zadań nie ma "stylu", więc nie jest jasne, jaki problem próbujesz rozwiązać. WPF nie obsługuje bezpośrednio tworzenia pasków zadań, można go utworzyć przez odskokiwanie SHAppBarMessage(). To dobrze się czyta. –

Odpowiedz

4

Rozwiązaniem utrzymywania wizualny styl okna WPF na aktywny nawet jeśli okno traci ostrość jest do obsługi WM_NCACTIVATE takiego:

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); 
Powiązane problemy