2013-07-15 21 views
6

Projektuję własne okno niestandardowe w WPF i próbuję zaimplementować funkcję zmiany rozmiaru, którą stosowałem wcześniej w WinForm. Z jakiegoś powodu wartość zwracana przez mój WndProc nie daje mi właściwego wyniku.WPF Zmiana rozmiaru okna bez obramowania

Mam klasy NativeMethods dla wszystkich moich wiadomości WndProc i wyników:

public class NativeMethods 
{ 
    public const int WM_NCHITTEST = 0x84; 
    public const int HTCAPTION  = 2; 
    public const int HTLEFT  = 10; 
    public const int HTRIGHT  = 11; 
    public const int HTTOP   = 12; 
    public const int HTTOPLEFT  = 13; 
    public const int HTTOPRIGHT = 14; 
    public const int HTBOTTOM  = 15; 
    public const int HTBOTTOMLEFT = 16; 
    public const int HTBOTTOMRIGHT = 17; 
} 

A oto kod tyłu za moim oknem:

public partial class MainWindow : Window 
{ 
    const int GripSize = 16; 
    const int BorderSize = 7; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 
     IntPtr windowHandle = new WindowInteropHelper(this).Handle; 
     HwndSource windowSource = HwndSource.FromHwnd(windowHandle); 
     windowSource.AddHook(WndProc); 
    } 

    private IntPtr WndProc(IntPtr hwnd, int msg, 
     IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == NativeMethods.WM_NCHITTEST) 
     { 
      int x = lParam.ToInt32() <<16>> 16, y = lParam.ToInt32() >> 16; 
      Point pos = PointFromScreen(new Point(x, y)); 

      if (pos.X > GripSize && 
       pos.X < ActualWidth - GripSize && 
       pos.Y >= ActualHeight - BorderSize) 
      { 
       return (IntPtr)NativeMethods.HTBOTTOM; // This doesn't work? 
      } 

      // Top, Left, Right, Corners, Etc. 
     } 

     return IntPtr.Zero; 
    } 
} 

Spodziewałem kursor zmieni się na " zmniejsz rozmiar strzałki w dół "i zmieniaj funkcjonalność tak, jak w moim projekcie WinForms. Ustawiłem punkty przerwania i powrót HTBOTTOM uruchamia się, gdy kursor znajduje się w oczekiwanym miejscu. W XAML mam ResizeMode ustawiony na CanResize, a WindowStyle na None. Co ja robię źle?

+1

Dlaczego nie użyć 'ResizeMode = "CanResizeWithGrip"'? Próbujesz osiągnąć ten efekt (wystarczy zmienić rozmiar okna bez "Grip")? –

+1

Ponieważ nadal chcę mieć możliwość zmiany rozmiaru okna z dowolnego rogu lub strony, tak jak normalna funkcjonalność. Rozgryzłem problem i teraz zamieszczam odpowiedź. –

Odpowiedz

2

To był głupi błąd. Zapomniałem dodać handled = true;, zanim zwróciłem wynik. Teraz okno działa normalnie. Uwaga: jeśli ustawisz ResizeMode na NoResize, ten kod nie będzie działał w ogóle.

11

Być może łatwiej jest przypisać WindowChrome.As na komentarz musi być w stanie zmienić rozmiar ze wszystkich stron, jak również za pomocą grip.Możesz to wszystko, ustawiając WindowStyle na None i ResizeMode na CanResizeWithGrip lub CanResize (cokolwiek chcesz osiągnąć)

<Window x:Class="MVVMProtoType.View.Test.Test" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Title="Test" Height="300" Width="300" WindowStyle="None" AllowsTransparency="False" ResizeMode="CanResizeWithGrip"> 

W kodzie zachowaj musisz ustawić okno Chrome dla tego okna. Można to zrobić tak:

WindowChrome.SetWindowChrome(this, new WindowChrome()); 

LUB Można użyć setter okienne stylu jak:

<Setter Property="WindowChrome.WindowChrome"> 
     <Setter.Value> 
      <WindowChrome CornerRadius="0" GlassFrameThickness="1" UseAeroCaptionButtons="False"/> 
     </Setter.Value> 
</Setter> 

MSDN link for more information

Uwaga klasę WindowChrome jest częścią .NET 4.5 Ramy. For.NET 4,0 użytkownicy sprawdzeniu archive.msdn.microsoft.com/WPFShell

+1

Dziękuję za odpowiedź. Nie wiedziałem o przestrzeni nazw System.Windows.Shell, która zaoszczędziłaby mi sporo czasu. –

2

napisałem rozwiązanie w innym poście, można zmienić rozmiar okna, trzeba użyć .NET 4.5 lub WPFShell

Można również umieścić kod WindowChrome bezpośrednio na twój MainWindow.xaml w ten sposób i działa idealnie bez ustawiania setera.

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:Concursos" 
    mc:Ignorable="d" 
    Title="Concuros" Height="350" Width="525" 
    WindowStyle="None" 
    WindowState="Normal" 
    ResizeMode="CanResize" 
    > 
<WindowChrome.WindowChrome> 
    <WindowChrome 
     CaptionHeight="0" 
     ResizeBorderThickness="5" /> 
</WindowChrome.WindowChrome> 

    <Grid> 

    <YOUR CODE HERE 

</Grid> 

Możesz iść tutaj, aby zobaczyć cały post.

Solution

Oto przed i po

The Challenge The Solution

Powiązane problemy