2017-07-20 8 views
2

私は、このコードは、Windows-XP OSを除くすべてのOSで正常に動作WindowsFormsでのカスタムコントロールの枠線の描画方法は?

protected override void WndProc(ref Message msg) 
    { 
     switch (msg.Msg) 
     { 
      case NativeMethods.WM_NCPAINT: 
      case NativeMethods.WM_SIZE: 
       base.WndProc(ref msg); 
       this.WmNcPaint(ref msg); 
       break; 
      default: 
       base.WndProc(ref msg); 
       break; 
     } 
    } 


    /// <summary></summary> 
    /// <param name="msg"/> 
    private void WmNcPaint(ref Message msg) 
    { 
     this.DrawThemedBorderColor(this, ref msg); 

    } 

    private IntPtr cachedRgn = IntPtr.Zero; 

    public void DrawThemedBorderColor(Control control, ref Message msg) 
    { 
     this.cachedRgn = NCPaintHelper(control, ref msg); 
    } 


    public IntPtr NCPaintHelper(Control control, ref Message m) 
    { 
     IntPtr hdc = IntPtr.Zero; 
     Graphics g = null; 
     IntPtr hwnd = m.HWnd; 
     IntPtr remainingClipRegion = IntPtr.Zero; 

     try 
     { 
      Rectangle clipRect; 
      Rectangle desktopBounds = GetDesktopBounds(control); 
      Rectangle bounds = desktopBounds; 
      bounds.X = bounds.Y = 0; 

      hdc = NativeMethods.GetWindowDC(m.HWnd); 

      if (hdc != IntPtr.Zero) 
      { 
       if (m.WParam.ToInt64() == 1 || m.WParam == IntPtr.Zero) 
       { 
        // Since we will be painting the client rect. 
        clipRect = bounds; 
       } 
       else 
       { 
        Rectangle rect = desktopBounds; 
        Point pt = new Point(rect.Left, rect.Top); 
        NativeMethods.RECT r = new NativeMethods.RECT(); 

        NativeMethods.GetRgnBox(m.WParam, ref r); 
        clipRect = new Rectangle(r.left, r.top, r.Width, r.Height); 
        clipRect.Intersect(rect); 
        clipRect.Offset(-pt.X, -pt.Y); 
       } 

       g = Graphics.FromHdc(hdc); 
       g.SetClip(clipRect, System.Drawing.Drawing2D.CombineMode.Replace); 
       g.Clip = new Region(clipRect); 
       PaintEventArgs pe = new PaintEventArgs(g, clipRect); 
       remainingClipRegion = NonClientPaint(pe, bounds, desktopBounds); 

       // When wParam is 1, the entire window frame needs to be updated. 
       if (m.WParam.ToInt64() == 1 || m.WParam == IntPtr.Zero) 
       { 
        // No existing clipping region, just replace it. 
        m.WParam = IntPtr.Add(IntPtr.Zero, 2);// remainingClipRegion; 
       } 
      } 
     } 
     finally 
     { 
      if (g != null) 
      { 
       g.Dispose(); 
      } 
      if (hdc != IntPtr.Zero) 
      { 
       NativeMethods.ReleaseDC(hwnd, hdc); 
      } 
     } 

     return IntPtr.Zero; 
    } 

    IntPtr NonClientPaint(PaintEventArgs e, Rectangle displayRect, Rectangle windowRectInScreen) 
    { 
     Graphics g = e.Graphics; 
     Rectangle bounds = displayRect; 
     // Draw border with themed border color. 
     // Draw lines, don't fill a rectangle. 
     using(Pen pen = new Pen(Color.Red)) 
     { 
      g.DrawLine(pen, bounds.Location, new Point(bounds.Right, bounds.Y)); 
      g.DrawLine(pen, bounds.Location, new Point(bounds.X, bounds.Height)); 
      g.DrawLine(pen, new Point(bounds.X, bounds.Height - 1), new Point(bounds.Right - 1, bounds.Height - 1)); 
      g.DrawLine(pen, new Point(bounds.Right - 1, bounds.Y), new Point(bounds.Right - 1, bounds.Height - 1)); 
     } 

     return NativeMethods.CreateRectRgn(0, 0, 0, 0); //windowRectInScreen.Left + 1, windowRectInScreen.Top + 1, windowRectInScreen.Right - 1, windowRectInScreen.Bottom - 1); 
    } 


    protected override CreateParams CreateParams 
    { 
     get 
     { 
      var cp = base.CreateParams; 

      switch (this.borderStyle) 
      { 
       case BorderStyle.Fixed3D: 
        cp.ExStyle |= 0x200; // WS_EX_DLGFRAME 
        break; 
       case BorderStyle.FixedSingle: 
        cp.Style |= 0x800000; // WS_BORDER 
        break; 
      } 
      return cp; 
     } 
    } 

、コードの下に使用して私のカスタムコントロールの境界線を描かに試してみました。 XPでは、境界線が部分的に描かれています。サンプル・リンク

enter image description here

、以下に添付のスクリーンショットとサンプルのリンクを参照してください:https://drive.google.com/open?id=0B6mYuvHmZAe-ay01ZTlvaGxSODA

私は私のカスタムコントロールのために描かれたカスタムの境界線に何をしないのです、私たちに知らせてください。

おかげで、

答えて

0

あなたが境界線をペイントするトラブルの多くを通過しているかのように思えます。私はあなたの勝利XPの問題に役立つが、それは試してみる価値がある可能性が肯定的ではない。ここで私のカスタムUserControlsの外縁に境界線を描きたいときに何をするのですか

public partial class MyUserControl : UserControl 
{ 
    public MyUserControl() 
    { 
     InitializeComponent(); 
     MyInitializeComponent(); 
    } 

    private void MyInitializeComponent() 
    { 
     this.Paint += MyUserControl_Paint; 
    } 

    private void MyUserControl_Paint(object sender, PaintEventArgs e) 
    { 
     // Draw a border around the outside border of the control 
     var pen = new Pen(Color.Black, 2f); 
     e.Graphics.DrawRectangle(pen, this.ClientRectangle); 
    } 
} 
関連する問題