精华内容
下载资源
问答
  • 对话框的OnPaint函数的两种写法的区别

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

    也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                   

    作者:朱金灿
    来源:http://blog.csdn.net/clever101/


              下面是对话框的OnPaint函数(就是WM_PAINT消息的响应函数)的两种写法。


    写法一:


    1. void CMyDlg::OnPaint()  
    2. {  
    3.     CDC *pDC = GetDC();  
    4.     // 我的绘制代码  
    5.     MyDrawFunction(pDC);  
    6.     ReleaseDC(pDC);  
    7. }  
    void CMyDlg::OnPaint(){    CDC *pDC = GetDC();    // 我的绘制代码    MyDrawFunction(pDC);    ReleaseDC(pDC);} 


    写法二:


     

    1. void CMyDlg::OnPaint()  
    2. {  
    3.      CPaintDC  dc(this);  
    4.     // 我的绘制代码  
    5.     MyDrawFunction(&dc);  
    6. }   
    void CMyDlg::OnPaint(){     CPaintDC  dc(this);    // 我的绘制代码    MyDrawFunction(&dc);} 


          开始以为这两种写法并无区别。今天偶然发现了这个区别。这个区别大家也可测试一下。建一个基于对话框的工程。然后添加下面绘图代码:


    1. void CColorPaletteDlg::DrawLine(CDC *pDC)  
    2. {  
    3.      assert(NULL!=pDC);  
    4.       Gdiplus::Pen red  (Color(255, 255, 0, 0),2.0f);  
    5.      Gdiplus::Graphics graphics(pDC->GetSafeHdc());  
    6.        
    7.      graphics.DrawLine(&red, 0, 0, 100,100);    
    8. }  
    void CColorPaletteDlg::DrawLine(CDC *pDC){     assert(NULL!=pDC);   Gdiplus::Pen red  (Color(255, 255, 0, 0),2.0f);     Gdiplus::Graphics graphics(pDC->GetSafeHdc());       graphics.DrawLine(&red, 0, 0, 100,100);  } 



    然后把它放在两个不同的OnPaint函数里调用,如下:


    1. void CColorPaletteDlg::OnPaint()  
    2. {  
    3.      CDC *pDC = GetDC();  
    4.      DrawLine(pDC);  
    5.      ReleaseDC(pDC);  
    6. }  
    void CColorPaletteDlg::OnPaint(){     CDC *pDC = GetDC();     DrawLine(pDC);     ReleaseDC(pDC);} 


    或是:


    1. void CColorPaletteDlg::OnPaint()  
    2. {  
    3.      CPaintDC  dc(this);  
    4.      DrawLine(&dc);  
    5. }  
    void CColorPaletteDlg::OnPaint(){     CPaintDC  dc(this);     DrawLine(&dc);} 


          一开始启动程序二者并无区别,但是在切换到其它程序窗口,比如打开一个txt文件再打开这个程序,你就会发现区别,写法一的效果会变为如下:


    GetDC


    写法二的效果如下:


    CPaintDC



         注意写法二能正常显示下面两个按钮。


         让我们看看MSDN对CPaintDC是如何解释的?


             CPaintDC objects encapsulate the common idiom of Windows, calling the BeginPaint function, then drawing in the device context, then calling the EndPaint function. The CPaintDC constructor calls BeginPaint for you, and the destructor calls EndPaint. The simplified process is to create the CDC object, draw, and destroy the CDC object. In the framework, much of even this process is automated. In particular, your OnDraw function is passed a CPaintDC already prepared (via OnPrepareDC), and you simply draw into it. It is destroyed by the framework and the underlying device context is released to Windows upon return from the call to your OnDraw function.


          CClientDC objects encapsulate working with a device context that represents only the client area of a window. The CClientDC constructor calls the GetDC function, and the destructor calls the ReleaseDC function.CWindowDC objects encapsulate a device context that represents the whole window, including its frame.


               大致的翻译是:CPaintDC对象封装了Windows的,调用BeginPaint函数,然后在设备上下文上绘图,然后调用EndPaint函数的常见用法。该CPaintDC构造函数调用BeginPaint函数,在析构函数调用EndPaint。简化的处理过程就是创造CDC对象,绘制,并摧毁了CDC对象。在框架内,即使是这个过程的大部分是自动的。特别是,你的OnDraw函数传递一个CPaintDC已经准备通过OnPrepareDC(),你通过它进行简单的绘图。它是由框架销毁和从调用您的OnDraw函数返回到基本设备上下文被释放后回Windows。(这一句的翻译有问题)


           CClientDC对象封装与一个设备上下文,表示只有一个窗口的客户区。该CClientDC构造函数调用GetDC的功能,析构函数调用ReleaseDC function.CWindowDC对象封装了表示整个窗口(包括它的框架)的设备上下文。


            也就是说,第二种写法比第一种写法做的工作要多。在此多谢VC知识库的benben、bl、sjdev等诸位大侠。








               

    给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

    这里写图片描述
    你好! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

    新的改变

    我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

    1. 全新的界面设计 ,将会带来全新的写作体验;
    2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
    3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
    4. 全新的 KaTeX数学公式 语法;
    5. 增加了支持甘特图的mermaid语法1 功能;
    6. 增加了 多屏幕编辑 Markdown文章功能;
    7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
    8. 增加了 检查列表 功能。

    功能快捷键

    撤销:Ctrl/Command + Z
    重做:Ctrl/Command + Y
    加粗:Ctrl/Command + B
    斜体:Ctrl/Command + I
    标题:Ctrl/Command + Shift + H
    无序列表:Ctrl/Command + Shift + U
    有序列表:Ctrl/Command + Shift + O
    检查列表:Ctrl/Command + Shift + C
    插入代码:Ctrl/Command + Shift + K
    插入链接:Ctrl/Command + Shift + L
    插入图片:Ctrl/Command + Shift + G

    合理的创建标题,有助于目录的生成

    直接输入1次#,并按下space后,将生成1级标题。
    输入2次#,并按下space后,将生成2级标题。
    以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

    如何改变文本的样式

    强调文本 强调文本

    加粗文本 加粗文本

    标记文本

    删除文本

    引用文本

    H2O is是液体。

    210 运算结果是 1024.

    插入链接与图片

    链接: link.

    图片: Alt

    带尺寸的图片: Alt

    当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

    如何插入一段漂亮的代码片

    博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

    // An highlighted block var foo = 'bar'; 

    生成一个适合你的列表

    • 项目
      • 项目
        • 项目
    1. 项目1
    2. 项目2
    3. 项目3
    • 计划任务
    • 完成任务

    创建一个表格

    一个简单的表格是这么创建的:

    项目Value
    电脑$1600
    手机$12
    导管$1

    设定内容居中、居左、居右

    使用:---------:居中
    使用:----------居左
    使用----------:居右

    第一列第二列第三列
    第一列文本居中第二列文本居右第三列文本居左

    SmartyPants

    SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

    TYPEASCIIHTML
    Single backticks'Isn't this fun?'‘Isn’t this fun?’
    Quotes"Isn't this fun?"“Isn’t this fun?”
    Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

    创建一个自定义列表

    Markdown
    Text-to- HTML conversion tool
    Authors
    John
    Luke

    如何创建一个注脚

    一个具有注脚的文本。2

    注释也是必不可少的

    Markdown将文本转换为 HTML

    KaTeX数学公式

    您可以使用渲染LaTeX数学表达式 KaTeX:

    Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

    Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

    你可以找到更多关于的信息 LaTeX 数学表达式here.

    新的甘特图功能,丰富你的文章

    gantt
            dateFormat  YYYY-MM-DD
            title Adding GANTT diagram functionality to mermaid
            section 现有任务
            已完成               :done,    des1, 2014-01-06,2014-01-08
            进行中               :active,  des2, 2014-01-09, 3d
            计划一               :         des3, after des2, 5d
            计划二               :         des4, after des3, 5d
    
    • 关于 甘特图 语法,参考 这儿,

    UML 图表

    可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图::

    张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

    这将产生一个流程图。:

    链接
    长方形
    圆角长方形
    菱形
    • 关于 Mermaid 语法,参考 这儿,

    FLowchart流程图

    我们依旧会支持flowchart的流程图:

    • 关于 Flowchart流程图 语法,参考 这儿.

    导出与导入

    导出

    如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

    导入

    如果你想加载一篇你写过的.md文件或者.html文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
    继续你的创作。


    1. mermaid语法说明 ↩︎

    2. 注脚的解释 ↩︎

    展开全文
  • MFC的Ondraw和OnPaint函数的作用

    千次阅读 2018-06-23 16:39:51
     该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中...

    CWnd::Invalidate

    voidInvalidate( BOOL bErase = TRUE );

      该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。 
      它和 UpdateWindow( )区别在于: 
      UpdateWindow()的作用是使窗口立即重绘。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘。

     

    CWnd::OnPaint
    afx_msg void OnPaint(); 
      说明: 
      当Windows或应用程序请求重画应用程序窗口的一部分时,框架调用这个成员函数。WM_PAINT在调用UpdateWindow或RedrawWindow成员函数时发出。当设置了RDW_INTERNALPAINT标志并调用RedrawWindow成员函数时,窗口可能会接收到内部重画消息。在这种情况下,窗口可能没有更新区域。应用程序必须调用GetUpdateRect成员函数以确定窗口是否具有更新区域。如果GetUpdateRect返回0,则应用程序不应调用BeginPaint和EndPaint成员函数。 
      应用程序负责检查是否需要内部重画或更新,这可通过查看每条WM_PAINT消息的内部数据结构来完成,因为一条WM_PAINT可能是由于一个无效区域或由于使用RDW_INTERNALPAINT标志调用了RedrawWindow成员函数而引起的。 
      Windows只发送一次内部WM_PAINT消息。在通过UpdateWindow成员函数向窗口发送了内部WM_PAINT消息以后,将不会再向窗口发送其它WM_PAINT消息,直到再次使用RDW_INTERNALPAINT标志调用了RedrawWindow成员函数。

     

    OnDraw与OnPaint有什么区别?
    OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。

    OnPaint()是CWnd的类成员,负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,没有响应消息的功能.当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows发送WM_PAINT消息。该视图的OnPaint处理函数通过创建CPaintDC类的DC对象来响应该消息并调用视图的OnDraw成员函数.OnPaint最后也要调用OnDraw,因此一般在OnDraw函数中进行绘制。
    The WM_PAINT message is sent when the UpdateWindow or RedrawWindowmember function is called.
    在OnPaint中,将调用BeginPaint,用来获得客户区的显示设备环境,并以此调用GDI函数执行绘图操作。在绘图操作完成后,将调用EndPaint以释放显示设备环境。而OnDraw在BeginPaint与EndPaint间被调用。

    1)在mfc结构里OnPaint是CWnd的成员函数. OnDraw是CView的成员函数.
    2)OnPaint()调用OnDraw(),OnPrint也会调用OnDraw(),所以OnDraw()是显示和打印的共同操作。

    OnPaint是WM_PAINT消息引发的重绘消息处理函数,在OnPaint中会调用OnDraw来进行绘图。OnPaint中首先构造一个CPaintDC类得实例,然后一这个实例为参数来调用虚函数OnPrepareDC来进行一些绘制前的一些处理,比设置映射模式,最后调用OnDraw。而OnDraw和OnPrepareDC不是消息处理函数。所以在不是因为重绘消息所引发的OnPaint导致OnDraw被调用时,比如在OnLButtonDown等消息处理函数中绘图时,要先自己调用OnPrepareDC。 
    至于CPaintDC和CClientDC根本是两回事情CPaintDC是一个设备环境类,在OnPaint中作为参数传递给OnPrepareDC来作设备环境的设置。真正和CClientDC具有可比性的是CWindowDC,他们一个是描述客户区域,一个是描述整个屏幕。
    如果是对CVIEW或从CVIEW类派生的窗口绘图时应该用OnDraw。


    OnDraw()和OnPaint()的区别:
    首先:我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC成的程序代码时,在视图类只有OnDraw没有OnPaint的原因。而在基于对话框的程序中,只有OnPaint。
    其次:我们在第《每天跟我学MFC》3的开始部分已经说到了。要想在屏幕上绘图或显示图形,首先需要建立设备环境DC。其实DC是一个数据结构,它包含输出设备(不单指你17寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。MFC提供了CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows将 WM_PAINT 消息发送给它。该视图的OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。

    OnDraw中可以绘制用户区域。OnPaint中只是当窗口无效时重绘不会保留CClientDC绘制的内容。

    这两个函数有区别也有联系:

    1、区别:OnDraw是一个纯虚函数,定义为virtual void OnDraw(CDC* pDC ) =0; 而OnPaint是一个消息响应函数,它响应了WM_PANIT消息,也是是窗口重绘消息。

    2、联系:我们一般在视类中作图的时候,往往不直接响应WM_PANIT消息,而是重载OnDraw纯虚函数,这是因为在CVIEW类中的WM_PANIT消息响应函数中调用了OnDraw函数,如果在CMYVIEW类中响应了WM_PAINT消息,不显式地调用OnDraw函数的话,是不会在窗口重绘的时候调用OnDraw函数的。

    应用程序中几乎所有的绘图都在视图的 OnDraw成员函数中发生,必须在视图类中重写该成员函数。(鼠标绘图是个特例,这在通过视图解释用户输入中讨论。)


    OnDraw重写:
    通过调用您提供的文档成员函数获取数据。
    通过调用框架传递给 OnDraw 的设备上下文对象的成员函数来显示数据。
    当文档的数据以某种方式更改后,必须重绘视图以反映该更改。默认的 OnUpdate实现使视图的整个工作区无效。当视图变得无效时,Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint处理函数通过创建 CPaintDC 类的设备上下文对象来响应该消息并调用视图的 OnDraw 成员函数。

    当没有添加WM_PAINT消息处理时,窗口重绘时,由OnDraw来进行消息响应...当添加WM_PAINT消息处理时,窗口重绘时,WM_PAINT消息被投递,由OnPaint来进行消息响应.这时就不能隐式调用OnDraw了.必须显式调用(  CDC *pDC=GetDC(); OnDraw(pDC);  )..
    隐式调用:当由OnPaint来进行消息响应时,系统自动调用CView::OnDraw(&pDC).


    想象一下,窗口显示的内容和打印的内容是差不多的,所以,一般情况下,统一由OnDraw来画。窗口前景需要刷新时,系统会会调用到OnPaint,而OnPaint一般情况下是对DC作一些初始化操作后,调用OnDraw()。


    OnEraseBkGnd(),是窗口背景需要刷新时由系统调用的。明显的一个例子是设置窗口的背景颜色(你可以把这放在OnPaint中去做,但是会使产生闪烁的现象)。  
    至于怎么界定背景和前景,那要具体问题具体分析了,一般情况下,你还是很容易区别的吧。


    的确,OnPaint()用来响应WM_PAINT消息,视类的OnPaint()内部根据是打印还是屏幕绘制分别以不同的参数调用OnDraw()虚函数。所以在OnDraw()里你可以区别对待打印和屏幕绘制。
    其实,MFC在进行打印前后还做了很多工作,调用了很多虚函数,比如OnPreparePrint()等。


    对于OnDraw() 
    This method is called by the framework to render an image of thedocument. The framework calls this method to perform screendisplay, printing, and print preview, and it passes a differentdevice context in each case. There is no defaultimplementation.


    ///CView默认的标准的重画函数
    void CView::OnPaint() //见VIEWCORE.CPP
    {

    CPaintDCdc(this);
    OnPrepareDC(&dc);
    OnDraw(&dc);   //调用了OnDraw
    }
    ///CView默认的标准的OnPrint函数
    void CView::OnPrint(CDC* pDC, CPrintInfo*)
    {
    ASSERT_VALID(pDC);
    OnDraw(pDC);   // CallDraw
    }

    既然OnPaint最后也要调用OnDraw,因此我们一般会在OnDraw函数中进行绘制。下面是一个典型的程序。
    ///视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。
    void CMyView::OnDraw( CDC* pDC )
    {

    CMyDoc*pDoc = GetDocument();
    CString s = pDoc->GetData();
    GetClientRect( &rect ); // Returns a CString CRectrect;
    pDC->SetTextAlign( TA_BASELINE | TA_CENTER);
    pDC->TextOut( rect.right / 2, rect.bottom / 2, s,s.GetLength() );
    }
    最后:现在大家明白这哥俩之间的关系了吧。因此我们一般用OnPaint维护窗口的客户区(例如我们的窗口客户区加一个背景图片),用OnDraw维护视图的客户区(例如我们通过鼠标在视图中画图)。当然你也可以不按照上面规律来,只要达到目的并且没有问题,怎么干都成。补充:我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口,具体的请参考MSDN吧。


    展开全文
  • 创建静态文本框之后如果想要在程序段中初始话文本框中的内容可以采用CDC类中的TextOut()函数,但是如果在OnPaint()中直接书写代码会导致待输出字符被静态文本框覆盖这是因为对话框上的文本控件是在对话框显示后才...

    创建静态文本框之后如果想要在程序段中初始话文本框中的内容可以采用CDC类中的TextOut()函数,但是如果在OnPaint()中直接书写代码会导致待输出字符被静态文本框覆盖这是因为对话框上的文本控件是在对话框显示后才画上去的,所以用textout直接输出字体会被覆盖。link
    如下所示:
    程序设计界面

    void CVCDlg::OnPaint() 
    {
    	if (IsIconic())
    	{
    		CPaintDC dc(this); // device context for painting
    
    		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
    
    		// Center icon in client rectangle
    		int cxIcon = GetSystemMetrics(SM_CXICON);
    		int cyIcon = GetSystemMetrics(SM_CYICON);
    		CRect rect;
    		GetClientRect(&rect);
    		int x = (rect.Width() - cxIcon + 1) / 2;
    		int y = (rect.Height() - cyIcon + 1) / 2;
    
    		// Draw the icon
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	else
    	{
    		
    		CDialog::OnPaint();
    		StyleInit();
    	}
    
    }
    
    void CVCDlg::StyleInit()
    {
    
    	CWnd *pWnd=GetDlgItem(IDC_LABLE);
    	CRect rect;
    	CBrush brush(RGB(110,0,0));
    	pWnd->GetClientRect (rect);
    	CDC *pDC=pWnd->GetDC();
    	//pDC->SetBkMode(TRANSPARENT);
    	pDC->SelectObject(&m_myFont1);
    	pDC->SetBkColor(RGB(225,225,0));
    	pDC->TextOut (0,0,"你好会发挥发挥会发肥哈哈哈哈哈哈哈哈哈哈哈哈哈");
    	pDC->MoveTo (0,0);
    	pDC->LineTo(150,150);
    }
    
    

    以上代码运行后显示效果如下
    程序运行截图
    可以很明显看到我们想要输出的文本被我们的静态文本框遮盖住了。
    解决方法如下:
    在OnCtlColor函数中改变绘制该静态文本宽的画刷,采用透明画刷绘制静态文本框

    HBRUSH CVCDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
    {
    	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    	
    	// TODO: Change any attributes of the DC here
    	if(pWnd->GetDlgCtrlID()==IDC_LABLE)
    	{
    		pDC->SetBkMode(TRANSPARENT);
    		 CBrush   brush;
    		brush.CreateStockObject(NULL_BRUSH); //这里采用了空画刷,即在绘图时不采用任何画刷
    		return brush;
    	}
    	
    	
    	// TODO: Return a different brush if the default is not desired
    	return hbr;
    	
    }
    

    更改后程序运行效果
    可以看到再次显示的静态文本框不会对输出文字干预

    展开全文
  • 该方法是对原有的类进行改写,比如我们需要修改button的属性,可以对button类进行修改并继承,进行onpaint函数的重新改写。这样做的好处就是可以使得做出来的界面比较友好,在按钮的形状和颜色方面相比原来的会比较...

    在使用C#进行界面开发的过程中,做界面开发经常会用到按钮,而C#界面中的按钮形状只有矩形的,而如果我们需要其他形状的按钮的话,就需要想点儿其他办法了,一般开发自己的控件有三种方法:

    首先是复合控件,从字面上就可以理解,是在原有控件的基础上进行组合,组合后的控件就是一个全新的控件;

    其次是扩展控件,一般控件都是用一个类进行了封装,我们可以通过继承该类,然后对其进行改写,赋予其新的特性;

    最后是自定义控件,这个方法是“写我们自己的控件”,DIY的程度最高,当然对编程要求也最高,也是最灵活,最强大的方法;

     

    本文先说说第二种方法的具体实现。

    该方法是对原有的类进行改写,比如我们需要修改button的属性,可以对button类进行修改并继承,进行onpaint函数的重新改写。这样做的好处就是可以使得做出来的界面比较友好,在按钮的形状和颜色方面相比原来的会比较丰富一些。

    具体的操作过程如下:

    在VS2015下,新建类库,取名,确定。

    然后引用动态库System.Windows.Forms:

    添加如下代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
    using System.ComponentModel;
    
    namespace myNewButton
    {
        public class colorfulButton:Button
        {
            
            Rectangle r= new Rectangle(0, 0, 150, 80);
            Rectangle r2 = new Rectangle(0,0,100,50);
            private Brush _myBrush = null;
            private Color _color1 = System.Drawing.Color.FromArgb(255, 255, 192);
            private Color _color2 = System.Drawing.Color.FromArgb(0, 0, 192);
    
            [Category("设置"), Description("渐变开始颜色")]
            public Color color1
            {
                get { return _color1; }
                set { _color1 = value; }
            }
    
            [Category("设置"), Description("渐变结束颜色")]
            public Color color2
            {
                get { return _color2; }
                set { _color2 = value; }
            }
    
            public void ButtonNew()
            {
                r = new Rectangle(0, 0, 150, 80);
                _myBrush = new LinearGradientBrush(r, _color1, _color2, LinearGradientMode.Vertical);
            }
    
            public Brush MyBrush
            {
                get { return _myBrush; }
                set { _myBrush = value; }
            }
    
            protected override void OnResize(EventArgs e)
            {
                base.OnResize(e);
                r = new Rectangle(0, 0, this.Width, this.Height);
                _myBrush = new LinearGradientBrush(r, _color1, _color2, LinearGradientMode.Vertical);
            }
    
            protected override void OnMouseLeave(EventArgs e)
            {
                base.OnMouseLeave(e);
                r = new Rectangle(0, 0, this.Width, this.Height);
                _myBrush = new LinearGradientBrush(r, _color1, _color2, LinearGradientMode.Vertical);
            }
    
            protected override void OnMouseEnter(EventArgs e)
            {
                base.OnMouseEnter(e);
                r = new Rectangle(0, 0, this.Width, this.Height);
                _myBrush = new LinearGradientBrush(r, _color2, _color1, LinearGradientMode.Vertical);
            }
    
            protected override void OnPaint(PaintEventArgs pevent)
            {
                base.OnPaint(pevent);
                Graphics g = pevent.Graphics;
                _myBrush = new LinearGradientBrush(r, _color1, _color2, LinearGradientMode.Vertical);
                g.FillRectangle(_myBrush,this.ClientRectangle);
                StringFormat strF = new StringFormat();
                strF.Alignment = StringAlignment.Center;
                strF.LineAlignment = StringAlignment.Center;
                g.DrawString(this.Text, this.Font, new SolidBrush(Color.Black), this.ClientRectangle, strF);
            }      
        }
    }
    

     

    展开全文
  • 用了两年的VC,其实对OnPaint的工作原理一直都是一知半解。这两天心血来潮,到BBS上到处发帖询问,总算搞清楚了,现在总结一下。  对于窗口程序,一般有个特点:窗口大部分的区域保持不变,只有不分区域需要重新...
  • 如果参数为true则在OnPaint函数对背景先进行绘制,再对前景进行绘制; 如果参数为false则在OnPaint函数对背景不绘制,只对前景进行绘制; 绘制前景方法: void xxx::OnPaint() { CPaintDC dc(this); } 绘制...
  • 为什么我在MFC对话框中,在OnPaint函数中加入以下代码,BMP图像不能显示啊~~· BITMAP bm; CBitmap bmp; bmp.LoadBitmap(IDB_BITMAP1); CDC memdc; CDC dc; memdc.CreateCompatibleDC(&dc);/ bmp....
  • 用了两年的VC,其实对OnPaint的工作原理一直都是一知半解。这两天心血来潮,到BBS上到处发帖询问,总算搞清楚了,现在总结一下。 对于窗口程序,一般有个特点:窗口大部分的区域保持不变,只有不分区域需要重新绘制...
  • OnDraw函数和OnPaint函数

    千次阅读 2014-07-28 11:26:32
    OnDraw()和OnPaint()兄弟 经常有朋友问这样的问题: 我在视图画的图象或者文字,当窗口改变后为什么不见了? OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同? OnDraw()和OnPaint()好象兄弟俩,因为它们...
  • 在对话框里面添加WM_PAINT消息的响应函数OnPaint之后,在函数里面添加了一个CClientDC对象,然后运行之后就发现对话框直接卡死了。代码如下: void CSettingDlg::OnPaint() { CClientDC dc(this); CPen pen(m_...
  • 该视图的OnPaint处理函数通过创建CPaintDC类的DC对象来响应该消息并调用视图的OnDraw成员函数.OnPaint最后也要调用OnDraw,因此一般在OnDraw函数中进行绘制。 The WM_PAINT message is sent when the UpdateWindow ...
  • CWnd::OnPaint() 是CWnd类的成员函数,是WM_PAINT 消息的响应函数.当你调用CWnd::UpdateWindow(), CWnd::RedrawWindow()时, 或者窗口被其他窗口覆盖,改变大小等事件就会产生WM_PAINT 消息. 你可以在CWnd派生的子类中...
  • 2, 在OnInitDialog函数中添加: LONG style = GetWindowLong(GetSafeHwnd(),GWL_STYLE); style = style | WS_CLIPCHILDREN ; SetWindowLong(GetSafeHwnd(),GWL_STYLE,style); 给窗口添加一个...
  • OnPaint是对这个消息的反应函数mfc 的 CWnd::OnPaint 没做什么,只是丢给系统处理。一 :先执行OnEraseBkgnd,擦除背景(如果想自绘控件,这个函数直接return TRUE就可以了,这样就不会擦除背景,不会闪)...
  • MFC中onPaint()函数的使用

    万次阅读 2014-05-04 00:02:11
    MFC中onPaint()函数的使用 WM_PAINT是窗口每次重绘都会产生的一个消息。 OnPaint是对这个消息的反应函数 mfc 的 CWnd::OnPaint 没做什么,只是丢给系统处理。 一 : 先执行OnEraseBkgnd,擦除背景...
  • void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效,窗口的客户区无效意味着需要重绘。 例如,如果一个被其它窗口...MFC为窗口类提供了WM_PAINT的消息处理函数OnPaintOnPaint负责重绘...
  • Invalidate InvalidateRect() 等类似的函数都是提供“手动”调用OnPaint
  • WM_PAINT介绍及OnPaint()函数的作用原理

    千次阅读 2017-09-17 21:40:03
    * MFC中 OnPaint()是对这个消息的反应函数( mfc 的 CWnd::OnPaint() 没做什么,只是丢给系统处理,下面就是介绍它在系统中的处理流程)     关于 WM_PAINT 消息  系统会在多个不同的时机发送WM_PAINT消息...
  • //重写OnPaint函数来画图,最小化不消失 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics dc = e.Graphics; Pen bluePen = new Pen(Color.Blue, 3); dc.DrawRectangle...
  • wxBufferedPaintDC继承自wxBufferedDC,wxPaintDC是其私有成员变量,因此该类只能够在wxPaintEvent事件中使用,也就是只能在OnPaint( wxPaintEvent& event )函数中使用。 为了使用该类,需要包含头文件#include "wx/...
  • CWnd::Invalidate ...voidInvalidate( BOOL bErase = TRUE );... 该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住
  • 重绘函数onpaint()

    千次阅读 2013-11-28 08:57:00
    OnPaint是对这个消息的反应函数 mfc 的 CWnd::OnPaint 没做什么,只是丢给系统处理。 一:  先执行OnEraseBkgnd,擦除背景(如果想自绘控件,这个函数直接return TRUE就可以了,这样就不会擦除背景,不会闪) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,116
精华内容 6,046
关键字:

onpaint函数