title: Hooking into Windows message loop in WPF window adds white border on the inside
body: <p>I am trying to create a WPF window with <code>WindowStyle="None"</code> (for custom buttons and no title) that cannot be resized.  Setting <code>ResizeMode</code> to <code>NoResize</code> removes the aero border, which I want to keep. </p>
  
  <p>I could set the min/max size properties and be done with it, except that: </p>
  
  <ol>
  <li>The resize cursors are still visible, and </li>
  <li>The window is displayed in response to a user action and fits to its contents.  It displays an image, so the size changes.</li>
  </ol>
  
  <p>So, I have a simple scheme that gets me 99% of the way there:</p>
  
  <pre><code>public class BorderedWindowNoResize : Window
  {
      [DllImport( "DwmApi.dll" )]
      public static extern int DwmExtendFrameIntoClientArea(
          IntPtr hwnd,
          ref MARGINS pMarInset );
  
      [DllImport( "user32.dll", CharSet = CharSet.Auto )]
      public static extern IntPtr DefWindowProc(
          IntPtr hWnd,
          int msg,
          IntPtr wParam,
          IntPtr lParam );
  
      public BorderedWindowNoResize()
      {           
          Loaded += BorderedWindowNoResize_Loaded;
      }
  
      private void BorderedWindowNoResize_Loaded( object sender, RoutedEventArgs e )
      {           
          IntPtr mainWindowPtr = new WindowInteropHelper( this ).Handle;
          HwndSource mainWindowSrc = HwndSource.FromHwnd( mainWindowPtr );            
          mainWindowSrc.AddHook( WndProc );
      }
  
      private IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
      {           
          var htLocation = DefWindowProc( hwnd, msg, wParam, lParam ).ToInt32();
  
          if( msg == (uint)WM.NCHITTEST )
          {
              handled = true;
              switch( htLocation )
              {
                  case (int)HitTestResult.HTBOTTOM:
                  case (int)HitTestResult.HTBOTTOMLEFT:
                  case (int)HitTestResult.HTBOTTOMRIGHT:
                  case (int)HitTestResult.HTLEFT:
                  case (int)HitTestResult.HTRIGHT:
                  case (int)HitTestResult.HTTOP:
                  case (int)HitTestResult.HTTOPLEFT:
                  case (int)HitTestResult.HTTOPRIGHT:
                      htLocation = (int)HitTestResult.HTBORDER;
                      break;
              }               
          }
  
          return new IntPtr( htLocation );
      }
  }
  </code></pre>
  
  <p>Basically;</p>
  
  <ol>
  <li>Override the window procedure.</li>
  <li>Call the default window procedure. </li>
  <li>If the message it is <code>WM_NCHITTEST</code>, check for the border results.</li>
  <li>If it is a border, return the regular <code>HTBORDER</code>.</li>
  </ol>
  
  <p>This works as far as allowing me to keep the aero window border and hiding the resize cursor(s), but it adds a ~5 pixel white border to the inside of my window.  </p>
  
  <p>In fact, even if I return the default windows procedure result at the top of <code>WndPrc</code> and do nothing else the border is <em>still</em> there.  I need a different background color on my window, so this won't work for me.</p>
  
  <p>Any ideas?  Thanks in advance as always.</p>