zoukankan      html  css  js  c++  java
  • C# 绘制窗体客户非客户区要用WM_PAINT和WM_NCPAINT

    窗体分为两部分:客户区(Client area)和非客户区(Non-Client area) 
    WM_PAINT消息、OnPaint()方法、GetDC()API函数都是处理窗体客户区绘制的 
      
    而标题栏处于非客户区中,所以WM_PAINT消息、OnPaint()方法、GetDC()API函数都用不上 
      
    GetWindowDC()是获得整个窗体的画布句柄(Device Context翻译为:设备清单,我习惯称为画布句柄),包括非客户区 
      
    GDI的绘制都离不开DC,因为操作系统必须知道你要在什么地方绘制图形 
      
    当其他窗体遮挡或者移开,系统都会重新绘制窗体。这时就会发出WM_PAINT和WM_NCPAINT消息通知窗体重绘界面。 
      
    收到WM_NCPAINT消息(非客户区绘制消息)说明非客户区正需要重新绘制 
      
    重载WndProc()方法(窗体消息处理过程),处理WM_NCPAINT等消息即可.... 
      
    “基本的步骤” 就是:截获WM_NCPAINT消息、得到窗体完整画布句柄、在完整画布上绘制图形。 
        WM_NCPAINT WM_NCCALCSIZE WM_NCACTIVATE WM_NCHITTEST
    建议楼主搜索关键词:“C# WM_NCPAINT WndProc Graphics”得到更多的参考资料 

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    [DllImport   ( "User32.dll ")] 
      
    private   static   extern   IntPtr   GetWindowDC(IntPtr   hwnd); 
      
    [DllImport   ( "User32.dll ")] 
      
    private   static   extern   int   ReleaseDC(IntPtr   hwnd,   IntPtr   hdc); 
      
    [DllImport   ( "Kernel32.dll ")] 
      
    private   static   extern   int   GetLastError(); 
      
    //标题栏按钮的矩形区域。 
      
    Rectangle   m_rect   =   new   Rectangle(205,   6,   20,   20); 
      
    protected   override   void   WndProc(ref   Message   m) 
      
    { 
      
    base.WndProc(ref   m); 
      
    switch(m.Msg) 
      
    { 
      
    case   0x86://WM_NCACTIVATE 
      
    goto   case   0x85; 
      
    case   0x85://WM_NCPAINT 
      
    { 
      
    IntPtr   hDC   =   GetWindowDC(m.HWnd); 
      
    //把DC转换为.NET的Graphics就可以很方便地使用Framework提供的绘图功能了 
      
    Graphics   gs   =   Graphics.FromHdc(hDC); 
      
    gs.FillRectangle(new   LinearGradientBrush(m_rect,   Color.Pink,   Color.Purple,   LinearGradientMode.BackwardDiagonal),   m_rect); 
      
    StringFormat   strFmt   =   new   StringFormat(); 
      
    strFmt.Alignment   =   StringAlignment.Center; 
      
    strFmt.LineAlignment   =   StringAlignment.Center; 
      
    gs.DrawString( "√ ",   this.Font,   Brushes.BlanchedAlmond,   m_rect,   strFmt); 
      
    gs.Dispose(); 
      
    //释放GDI资源 
      
    ReleaseDC(m.HWnd,   hDC); 
      
    break; 
      
    } 
      
    case   0xA1://WM_NCLBUTTONDOWN 
      
    { 
      
    Point   mousePoint   =   new   Point((int)m.LParam); 
      
    mousePoint.Offset(-this.Left,   -this.Top); 
      
    if(m_rect.Contains(mousePoint)) 
      
    { 
      
    MessageBox.Show( "hello "); 
      
    } 
      
    break; 
      
    } 
      
    } 
      
    } 
      
    //在窗口大小改变时及时更新按钮的区域。 
      
    private   void   Form1_SizeChanged(object   sender,   System.EventArgs   e) 
      
    { 
      
    m_rect.X   =   this.Bounds.Width   -   95; 
      
    m_rect.Y   =   6; 
      
    m_rect.Width   =   m_rect.Height   =   20; 
      
    } 
      
    } 
      
    }
    

      

  • 相关阅读:
    理解 RESTful:理论与最佳实践
    Shiro 性能优化:解决 Session 频繁读写问题
    单点登录的三种实现方式
    理解 Spring(二):AOP 的概念与实现原理
    理解 Spring(一):Spring 与 IoC
    MFC查内存泄漏方法
    024 --- 第28章 访问者模式
    023 --- 第27章 解释器模式
    022 --- 第26章 享元模式
    021 --- 第25章 中介者模式
  • 原文地址:https://www.cnblogs.com/d3inc/p/3799839.html
Copyright © 2011-2022 走看看