2013-07-15 3 views
6

Я разрабатываю собственное окно в WPF, и я пытаюсь реализовать функцию изменения размера, которую я использовал ранее в WinForms. По какой-то причине возвращаемое значение моего WndProc не дает мне надлежащего результата.WPF Borderless window resize

У меня есть класс NativeMethods для всех моих WNDPROC сообщений и результатов:

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

А вот код позади моего окна:

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

Я ожидал, что курсор изменится на " изменить размер стрелки вниз »и функциональность изменения размера, чтобы работать так же, как в моем проекте WinForms. Я установил точки останова, и возврат HTBOTTOM срабатывает, когда курсор находится в ожидаемом месте. В XAML у меня ResizeMode установлен в CanResize, а WindowStyle - None. Что я делаю не так?

+1

Почему бы не использовать 'ResizeMode = "CanResizeWithGrip"'? Вы пытаетесь добиться этого эффекта (просто для его изменения вокруг окна без «Grip»)? –

+1

Потому что я все еще хочу иметь возможность изменять размер окна с любого угла или стороны, как обычная функциональность. Я понял вопрос, и я отправляю ответ сейчас. –

ответ

2

Ну, это была глупая ошибка. Я забыл добавить handled = true;, прежде чем я вернул результат. Теперь окно функционирует нормально. В качестве примечания, если вы установите ResizeMode в NoResize, этот код не будет работать вообще.

11

Возможно, проще назначить WindowChrome. В соответствии с вашим комментарием вы должны иметь возможность изменять размер со всех сторон, а также с помощью grip.You можете сделать все это, установив WindowStyle в None и ResizeMode в CanResizeWithGrip или CanResize (все, что вы хотите добиться)

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

В коде необходимо установить окно Chrome для окна. Вы можете сделать это следующим образом:

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

ИЛИ Вы можете использовать сеттер для оконного стиля, как:

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

MSDN link for more information

Обратите внимание, класс WindowChrome является частью .NET 4.5. For.NET 4.0 пользователей проверить archive.msdn.microsoft.com/WPFShell

+1

Благодарим за отзыв. Я не знал о пространстве имен System.Windows.Shell, которое бы сэкономило мне немного времени. –

2

Я написал решение в другом посте, вы можете изменить размер окна, вам нужно использовать .NET 4.5 или WPFShell

Вы также можете поместить код WindowChrome непосредственно на ваш MainWindow.xaml, как это, и он отлично работает, не ставя сеттера.

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

Вы можете пойти сюда, чтобы просмотреть полный пост.

Solution

Вот до и после

The Challenge The Solution

0

Я также предоставил исходный код полностью рабочий (значительный, и т.д.) WPF без границ окна, чтобы вы могли быть заинтересованы в . Это можно найти здесь.

WPF Borderless Window issues: Aero Snap & Maximizing