窗体分为两部分:客户区(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. jQuery获取和设置disabled属性、背景图片路径

    之前对于这个独特的disabled属性获取和设置很混乱,今天项目中用到了,用attr不能实现,于是多次试验得出: 获取disabled属性用prop $("#basic_key") ...

  2. Performance Counter的使用

    原文地址:http://blog.csdn.net/jiangxinyu/article/details/5480401 PerformanceCounter 基本介绍以及示例方法 一 Perform ...

  3. linux 命令拾遗

    man ascii 这个命令会打印出八进制.十六进制和十进制的ASCII码表. xxd xxd可以生成所给与文件的十六进制拷贝,也可以将编辑好的十六进制拷贝还原成二进制格式.它也可以将十六进制拷贝输出 ...

  4. HW4.14

    public class Solution { public static void main(String[] args) { int count = 0; char asciiChar; for( ...

  5. hdoj 1698 Just a Hook【线段树区间修改】

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. android4.0 FaceDetection笔记

    这几天研究了下andoid4.0.3的FaceDetection这里写一下大致的流程,方便日后查阅. 相关说明可以在这里找到: frameworks/base/docs/html/guide/topi ...

  7. Morris Traversal 二叉树遍历。

    那天做了个SWAP NODE的题,要求constant space,不得不Morris Traversal. 稍微研究了一下,真正意义上的O(1)space对二叉树进行遍历.好像是1979年的算法. ...

  8. epoll使用实例说明

    之前一直在讲如何epoll如何好用,但是并没有实例来演示epoll的使用,下面我们就看一个服务器端使用epoll监听大量并发链接的例子. 首先看一下epoll的几个函数的介绍.1.epoll_crea ...

  9. UDP 校检和和算法

    #include <Winsock2.h> #include <stdio.h> #define IP_HDRINCL 2 // Header is included with ...

  10. WCF - 消息

    SOAP SOAP是Simple Object Access Protocol(简单对象访问协议)的简称 而如今SOAP已经成为了符合W3C制定的SOAP规范的消息 允许您使用 XML 在通过低层 I ...