2013-07-15 13 views
6

Sto progettando la mia finestra personalizzata in WPF e ho cercato di implementare la funzionalità di ridimensionamento che ho usato in precedenza in WinForms. Per qualche motivo il valore di ritorno del mio WndProc non mi sta dando il risultato corretto.Ridimensionamento della finestra senza bordi WPF

Ho una classe NativeMethods per tutti i miei messaggi WNDPROC e risultati:

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

Ed ecco il codice sottostante per la mia finestra:

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

mi aspettavo il cursore per passare alla " ridimensiona la freccia in giù "e la funzionalità di ridimensionamento funziona come nel mio progetto WinForms. Ho impostato i breakpoint e il ritorno HTBOTTOM si attiva quando il cursore si trova nella posizione prevista. In XAML ho impostato ResizeMode su CanResize e WindowStyle su None. Che cosa sto facendo di sbagliato?

+1

Perché non usare 'ResizeMode = "CanResizeWithGrip"'? Stai cercando di ottenere questo effetto (solo per ridimensionarlo intorno alla finestra senza 'Grip')? –

+1

Perché voglio ancora poter ridimensionare la finestra da qualsiasi angolo o lato come la normale funzionalità. Ho capito il problema e sto postando la risposta ora. –

risposta

2

Beh, questo è stato uno stupido errore. Ho dimenticato di aggiungere handled = true; prima di restituire il risultato. Ora la finestra funziona normalmente. Come nota, se si imposta ResizeMode su NoResize, questo codice non funzionerà affatto.

11

Forse è più semplice assegnare WindowChrome.As per il tuo commento devi essere in grado di ridimensionare da tutti i lati e utilizzare il grip. Puoi fare tutto questo impostando WindowStyle su None e ResizeMode su CanResizeWithGrip o CanResize (tutto ciò che si desidera acheive)

<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"> 

Nel codice behid è necessario impostare la finestra di Chrome per la finestra. Si può fare in questo modo:

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

O È possibile utilizzare setter per lo stile finestra come:

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

MSDN link for more information

Si prega di notare classe WindowChrome è una parte di .NET 4.5 Quadro. For.NET 4,0 utenti estrarre archive.msdn.microsoft.com/WPFShell

+1

Grazie per la risposta. Non conoscevo lo spazio dei nomi System.Windows.Shell che mi avrebbe risparmiato un bel po 'di tempo. –

2

ho scritto una soluzione in un altro post, è possibile ridimensionare la finestra, è necessario utilizzare .NET 4.5 o WPFShell

Si può anche mettere il codice WindowChrome direttamente sul il tuo MainWindow.xaml piace così, e funziona perfettamente senza mettere un setter.

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

Si può andare qui per visualizzare la carica completa.

Solution

Ecco la prima e dopo

The Challenge The Solution