窗体分为两部分:客户区(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; 

} 

} 

}

  

C# 绘制窗体客户非客户区要用WM_PAINT和WM_NCPAINT的更多相关文章

  1. 调用API函数,在窗口非客户区绘图(通过GetWindowDC获得整个窗口的DC,就可以随意作画了)

    http://hi.baidu.com/3582077/item/77d3c1ff60f9fa5ec9f33754 调用API函数,在窗口非客户区绘图 GDI+的Graphics类里有个FromHdc ...

  2. VC----SDK下对窗口非客户区的操作

    窗口分成两大部分:客户区和非客户区.非客户区再次细分:标题栏,如图片中顶部深蓝色:左边框,如图片中红色部分:上边框,如图片中绿色部分:右边框,如图片中右侧天蓝色部分:底边框,如图片中下面棕色部分. 之 ...

  3. 安全概念:DMZ(非军事化区,隔离区)

    DMZ是英文“demilitarized zone”的缩写,中文名称为“隔离区”,也称“非军事化区”.它是为了解决安装防火墙后外部网络不能访问内部网络服务器的问题,而设立的一个非安全系统与安全系统之间 ...

  4. 浅谈C#中的模式窗体和非模式窗体

    ShowDialog(); // 模式窗体 Show(); // 非模式窗体 区别: 返回值不同,DialogResult/void 模式窗体会使程序中断,直到关闭模式窗口 打开模式窗体后不能切换到应 ...

  5. Windows Mobile X图标如何销毁窗体而非隐藏

    在Windows Mobile窗体上,有“OK”和“X”两种形式按钮.1.在Form的属性里,设置“MinimizeBox=false”,则窗体显示”OK”,点击该按钮窗体销毁并退出.2.设置“Min ...

  6. Qt paintEvent绘制窗体 注意Qt::WA_PaintOutsidePaintEvent 只是适用于X11,其他系统均无效

    QPainter默认只能在paintEvent里面调用,但是: 在其他事件中绘制窗体,提示信息如下:QPainter::begin: Paint device returned engine == 0 ...

  7. 绘制窗体渐变背景的函数[delphi]

    绘制窗体渐变背景的函数,三个参数分别代表起始颜色,终止颜色,绘制方向procedure TForm1.Draw(StartColor:TColor;EndColor:TColor;Direction: ...

  8. TWinControl.WMNCPaint对非客户的绘制

    混个脸熟: procedure TWinControl.WMNCPaint(var Message: TMessage); const InnerStyles: , BDR_SUNKENINNER, ...

  9. Silverlight浮动窗体 floatablewindow 非模态对话框

    1.http://www.cnblogs.com/yinxiangpei/articles/2613913.html 说明:Silverlight的ChildWindow组件给我们的开发带来了便利,比 ...

随机推荐

  1. 报错:Cannot insert explicit value for identity column in table 't' when identity_insert is set to OFF

    通常情况下,不能向 SQL Server 自增字段插入值,如果非要这么干的话,SQL Server 就会好不客气地给你个错误警告: Server: Msg 544, Level 16, State 1 ...

  2. hdoj 5461 Largest Point

    Largest Point Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  3. windows mobile 6.5 隐藏 左下角(左上角)的开始按钮 叉号关闭按钮

    其实做起来很简单,但是国内的网站就是找不到. 1.开始按钮原来的界面是这样的: windows mobile 6.0界面: windows mobile 6.5.X界面: 修改一个windows mo ...

  4. Ajax页面跳转

    <script type="text/javascript" >    $(document).ready(function () {            $(&qu ...

  5. (3/18)重学Standford_iOS7开发_Objective-C_课程笔记

    第三课: 本节课主要是游戏实现的demo,因此我将把课程中简单的几个编程技巧提取出来,重点介绍如何自己实现作业中的要求. 纸牌游戏实现: ①游戏的进行是模型的一部分(理解什么是模型:Model = W ...

  6. asp.net采用OLEDB方式导入Excel数据时提示:未在本地计算机上注册"Microsoft.Jet.OLEDB.4.0" 提供程序"

    笔者在项目中做做了一个从Excel表格中导入数据的模块.大体上asp.net项目中导入Excel大体分成三类: 1)采用c#内置方案System.Data.OleDb(限制较小, 通用) 2)采用Ex ...

  7. MVC中一般为什么用IQueryable而不是用IList

    IList(IList<T>)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred execution)”,如果被加载的实体有关联实体(associations),此关联实 ...

  8. android账号与同步之同步实现

    上一篇博文我先介绍了账号与同步的账号管理,这篇就介绍一下还有一部分.就是android给提供的sync同步机制的使用. 事实上sync机制的使用和上一篇博文中介绍的账号管理非常类似,也是基于binde ...

  9. 经典SQL语句大全之数据开发

    数据开发 1.按姓氏笔画排序:Select * From TableName Order By CustomerName Collate Chinese_PRC_Stroke_ci_as //从少到多 ...

  10. 第一篇:杂项之pymysql连接池

    杂项之pymysql连接池   杂项之pymysql连接池 本节内容 本文的诞生 连接池及单例模式 多线程提升 协程提升 后记 1.本文的诞生 由于前几天接触了pymysql,在测试数据过程中,使用普 ...