barriers / 阅读 / 详情

在MFC编程中Invalidate(); pDoc->SetModifiedFlag(TRUE); pDoc->UpdateAllViews(this);分别是什么意思?

2023-08-07 17:41:50
共2条回复
可乐

void Invalidate( BOOL bErase = TRUE );

该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数 OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw 来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。

SetModifiedFlag(TRUE);

设置脏标记,表示你的Doc类已经修改了。

比如说你需要保存的时候,可以判断是否修改,没修改,就不需要保存等等之类的。

UpdateAllViews()

该函数是CDocument的成员函数,

因为视图窗口显示的,一般是文档数据的可视化表示,

所以当文档中的数据被修改后,需要通知所有与之相关的视图,重新绘制画面.

S笔记

就凭这些看不出问题啊

相关推荐

session.invalidate();详细解释!!!???

首先,session 的作用域是在一个会话期间,多个用户访问服务器,就会有多个session,现在,我就假设有三个用户A、B、C,他们访问服务器,分别创建了三个Session,记为S1,S2,S3.。session.invalidate(),是某一个用户调用的,比如说S1这个用户,调用了这个方法,那么,就只有s1用户的session 被删除,其他用户的session,跟s1没关系。session.invalidate(),它实际上调用的是session对象中的destroy方法,也就是说你下次要再使用session,得再重新创建。 简单的说,就是没了,而不是值为null还有一个用户,访问同一个服务器,关闭浏览器,默认情况下清除所有的session。实际上清除的是自己的这个session 而已。。。别人的session关它什么事。另外,有些情况下,登出并不一定是调用session.invalidate(),有时候,只是把绑定在session中某些数据给清空而已。session.invalidate()是不能随便调用的,一旦调用,就是所有的数据都会丢失。
2023-08-05 20:49:511

c++中 Invalidate();的问题

把invalidate那一句放到paintback后面试试。Invalidate函数是让画面失效(也就是让画面重绘)
2023-08-05 20:50:333

android中Invalidate和postInvalidate的区别

Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。 Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。   Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面。 1,利用invalidate()刷新界面   实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面刷新;而在线程中通过sendMessage发送界面更新消息。 // 在onCreate()中开启线程new Thread(new GameThread()).start();、// 实例化一个handlerHandler myHandler = new Handler() {// 接收到消息后处理public void handleMessage(Message msg) {switch (msg.what) {case Activity01.REFRESH:mGameView.invalidate(); // 刷新界面break;}super.handleMessage(msg);}};class GameThread implements Runnable {public void run() {while (!Thread.currentThread().isInterrupted()) {Message message = new Message();message.what = Activity01.REFRESH;// 发送消息Activity01.this.myHandler.sendMessage(message);try {Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}
2023-08-05 20:51:091

invalidate和postInvalidate 的区别及使用

Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。   Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面。 利用invalidate()刷新界面   实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面刷新;而在线程中通过sendMessage发送界面更新消息。Java代码 // 在onCreate()中开启线程 new Thread( new GameThread()).start();、 // 实例化一个handler Handler myHandler = new Handler() { // 接收到消息后处理 public void handleMessage(Message msg) { switch (msg.what) { case Activity01.REFRESH: mGameView.invalidate(); // 刷新界面 break ; } super .handleMessage(msg); } }; class GameThread implements Runnable { public void run() { while (!Thread.currentThread().isInterrupted()) { Message message = new Message(); message.what = Activity01.REFRESH; // 发送消息 Activity01.this .myHandler.sendMessage(message); try { Thread.sleep(100 ); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } [java] view plaincopy// 在onCreate()中开启线程 new Thread(new GameThread()).start();、 // 实例化一个handler Handler myHandler = new Handler() { // 接收到消息后处理 public void handleMessage(Message msg) { switch (msg.what) { case Activity01.REFRESH: mGameView.invalidate(); // 刷新界面 break; } super.handleMessage(msg); } }; class GameThread implements Runnable { public void run() { while (!Thread.currentThread().isInterrupted()) { Message message = new Message(); message.what = Activity01.REFRESH; // 发送消息 Activity01.this.myHandler.sendMessage(message); try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } 使用postInvalidate()刷新界面 使用postInvalidate则比较简单,不需要handler,直接在线程中调用postInvalidate即可。 Java代码 class GameThread implements Runnable { public void run() { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(100 ); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } // 使用postInvalidate可以直接在线程中更新界面 mGameView.postInvalidate(); } }
2023-08-05 20:51:211

MFC中的Invalidate、OnDraw、OnPaint函数的作用、区别和联系?

OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。当没有添加WM_PAINT消息处理时,窗口重绘时,由OnDraw来进行消息响应...当添加WM_PAINT消息处理时,窗口重绘时,WM_PAINT消息被投递,由OnPaint来进行消息响应.这时就不能隐式调用OnDraw了.必须显式调用( CDC *pDC=GetDC(); OnDraw(pDC); )..隐式调用:当由OnPaint来进行消息响应时,系统自动调用CView::OnDraw(&pDC).
2023-08-05 20:52:293

android中Invalidate和postInvalidate的区别

行不鹅黄色v你想几点巴不得
2023-08-05 20:53:142

session的removeAttribute()和invalidate()的区别

注销当然是要销毁所有session的属性,使用session.invalidate()
2023-08-05 20:53:415

onDraw调用和android中Invalidate和postInvalidate的区别

  Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。  Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。  Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面。  1,利用invalidate()刷新界面  实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面刷新;而在线程中通过sendMessage发送界面更新消息。  // 在onCreate()中开启线程  new Thread(new GameThread()).start();、  // 实例化一个handler  Handler myHandler = new Handler() {  // 接收到消息后处理  public void handleMessage(Message msg) {  switch (msg.what) {  case Activity01.REFRESH:  mGameView.invalidate(); // 刷新界面  break;  }  super.handleMessage(msg);  }  };  class GameThread implements Runnable {  public void run() {  while (!Thread.currentThread().isInterrupted()) {  Message message = new Message();  message.what = Activity01.REFRESH;  // 发送消息  Activity01.this.myHandler.sendMessage(message);  try {  Thread.sleep(100);  } catch (InterruptedException e) {  Thread.currentThread().interrupt();  }
2023-08-05 20:54:241

android addview requestlayout invalidate 能在子线程执行吗

Invalidate和postInvalidate和requestLayout都是用来刷新view控件的:主线程可以直接调用Invalidate()方法刷新。子线程可以直接调用postInvalidate()方法刷新。API的描述是这样的 : Invalidatethe whole view. If the view is visible, onDraw(Canvas) will be called at somepoint in the future. This must be called from a UI thread. To call from anon-UI thread, call postInvalidate().。当Invalidate()被调用的时候,View的OnDraw()就会被调用,Invalidate()必须是在UI线程中被调用,如果在新线程中更新视图的就调用postInvalidate()。</ol>
2023-08-05 20:54:491

request.getSession().invalidate()是干什么用的?

清除 session 中的所有信息
2023-08-05 20:55:001

invalidate执行后,为什么onDraw却不执行

view的invalidate未必一定会出发onDraw,如果高版本没有出发onDraw,可能是做了相关的优化,认为你此次的invalidate并不需要出发onDraw,或者是其他的逻辑。如果你想在搞版本也出发试试以下方法方法1:((View)view.getParnet()).invalidate();方法2:view.invalidate();view.forceLayout();view.requestLayout();
2023-08-05 20:55:171

刷新重绘是什么问题?

一、说法一Control.Refresh - does an Control.Invalidate followed by Control.Update. Refresh: 强制控件使其工作区无效并立即重绘自己和任何子控件。==Invalidate + UpdateControl.Invalidate - invalidates a specific region of the Control (defaults to entire client area) and causes a paint message to be sent to the control.Invalidate marks the control (region, or rect) as in need of repainting, but doesn"t immediately repaint (the repaint is triggered when everything else has been taken care of and the app becomes idle). Invalidate: 使控件的特定区域(可以自己设置区域,从而提高性能)无效并向控件发送绘制消息。 将控件标记为需要重绘,但是不会立即执行刷新重绘,等到系统空闲时进行重绘。Control.Update - causes the Paint event to occur immediately (Windows will normally wait until there are no other messages for the window to process, before raising the Paint event).Update causes the control to immediately repaint if any portions have been invalidated. Update: 使控件重绘其工作区内的无效区域,立即调用Paint事件。若有无效区域,Update将立即触发重绘。The paint event of course is where all the drawing of your form occurs. Note there is only one pending Paint event, if you call Invalidate 3 times, you will still only receive one Paint event.Paint: 无处不在。如果你调用3次Invalidate,但是系统将只触发一次Paint事件。 Most of the time Invalidate is sufficient, and advisable as you can do a bunch of invalidations (either explicit or implicit) and then let the control repaint itself when the app is idle. It is advisable to use Update or Refresh when you want the control to immediately repaint because the app will not be idle for a user-noticable period of time.大多数时候Invalidate已经足够了,当系统要集中进行大量的刷新重绘时,建议使用Invalidate,因为这样系统最终只进行一次刷新,提高了系统性能。如果你想立即执行刷新的时候,建议使用Refresh方法。二、说法二Refresh和 Repaint是一样的,它只是简单地调用了Repaint.Update会导致整个窗口(对于没有窗口的 TGraphicControl来说,就是它的父控件的窗口)立即处理WM_PAINT消息,即重画应该画的部分.Invalidate使控件所在窗口的控件客户区域(对于TWinControl来说就是它的客户区域,对于TGraphicControl来说就是它的父控件的窗口在它的区域范围内的部分)失效,从而产生一个WM_PAINT消息,但并不马上重绘,直到其它消息处理完或遇到一个Update的调用.Repaint是立即重绘该控件,在TWinControl中其实就是调用了Invalidate和Update,在TGraphiControl 中分不同情况作了不同处理,逻辑稍复杂一些,但功能是一样的.
2023-08-05 20:55:471

invalidation与update的区别?

一、说法一Control.Refresh - does an Control.Invalidate followed by Control.Update. Refresh: 强制控件使其工作区无效并立即重绘自己和任何子控件。==Invalidate + UpdateControl.Invalidate - invalidates a specific region of the Control (defaults to entire client area) and causes a paint message to be sent to the control.Invalidate marks the control (region, or rect) as in need of repainting, but doesn"t immediately repaint (the repaint is triggered when everything else has been taken care of and the app becomes idle). Invalidate: 使控件的特定区域(可以自己设置区域,从而提高性能)无效并向控件发送绘制消息。 将控件标记为需要重绘,但是不会立即执行刷新重绘,等到系统空闲时进行重绘。Control.Update - causes the Paint event to occur immediately (Windows will normally wait until there are no other messages for the window to process, before raising the Paint event).Update causes the control to immediately repaint if any portions have been invalidated. Update: 使控件重绘其工作区内的无效区域,立即调用Paint事件。若有无效区域,Update将立即触发重绘。The paint event of course is where all the drawing of your form occurs. Note there is only one pending Paint event, if you call Invalidate 3 times, you will still only receive one Paint event.Paint: 无处不在。如果你调用3次Invalidate,但是系统将只触发一次Paint事件。 Most of the time Invalidate is sufficient, and advisable as you can do a bunch of invalidations (either explicit or implicit) and then let the control repaint itself when the app is idle. It is advisable to use Update or Refresh when you want the control to immediately repaint because the app will not be idle for a user-noticable period of time.大多数时候Invalidate已经足够了,当系统要集中进行大量的刷新重绘时,建议使用Invalidate,因为这样系统最终只进行一次刷新,提高了系统性能。如果你想立即执行刷新的时候,建议使用Refresh方法。二、说法二Refresh和 Repaint是一样的,它只是简单地调用了Repaint.Update会导致整个窗口(对于没有窗口的 TGraphicControl来说,就是它的父控件的窗口)立即处理WM_PAINT消息,即重画应该画的部分.Invalidate使控件所在窗口的控件客户区域(对于TWinControl来说就是它的客户区域,对于TGraphicControl来说就是它的父控件的窗口在它的区域范围内的部分)失效,从而产生一个WM_PAINT消息,但并不马上重绘,直到其它消息处理完或遇到一个Update的调用.Repaint是立即重绘该控件,在TWinControl中其实就是调用了Invalidate和Update,在TGraphiControl 中分不同情况作了不同处理,逻辑稍复杂一些,但功能是一样的.
2023-08-05 20:55:551

如何在促发onpaint函数时重绘区域的背景不变

一、Invalidate介绍void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。二、与UpdateWindow( )的区别UpdateWindow( )的作用是使窗口立即重绘。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘。OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。为什么需要OnDraw呢,是为了让OnDraw一个函数服务于不同的绘图环境,比如显示器,打印机,绘图仪 ,mfc在调用OnDraw之前会把适当的CDC对象传给OnDraw函数。这样窗口的打印功能就可以和显示共用一个函数。
2023-08-05 20:56:041

Android 如何判断一个View重绘或加载完成?

onfinishInflate 重绘可以在ondraw里
2023-08-05 20:56:162

request.getSession().invalidate() 能否释放内存?

这个会使得整个客户端对应的Session失效,里面的所有东西都会清空了,同时也释放了资源。但是你所描述的需求应该不是让客户端对应的Session失效,而是通过Session传递数据后,释放传递数据所占用的资源,应该是你在getAttribute后通过request.getSession().remove方法删除你传递的对象就可以了,不必要让整个Session失效。
2023-08-05 20:56:342

invalidate会调用onmeasure吗

加其他view导致该view的位置发生变化的时候都会调用该view的onMeasure方法。
2023-08-05 20:57:021

param is invalidate是什么意思

param is invalidate是“参数无效”的意思。
2023-08-05 20:57:141

后台执行session.invalidate()后, 怎么在js中判断该session已经销毁,从而强制退出访问

是的,session.invalidate()这个方法就是把session里的所有的东西都清除掉,所以sessison整个都销毁了
2023-08-05 20:57:362

为啥我用session.invalidate()不能实现安全退出呢?意思是点击界面左上角的后退按钮还能回去

为了更为有效地阐述实现方案,本文将从展示一个示例应用logoutSampleJSP1中碰到的问题开始。这个示例代表了许多没有正确解决退出过程的Web应用。logoutSampleJSP1包含了下述jsp页面:login.jsp, home.jsp, secure1.jsp, secure2.jsp, logout.jsp, loginAction.jsp, and logoutAction.jsp。其中页面home.jsp, secure1.jsp, secure2.jsp, 和logout.jsp是不允许未经认证的用户访问的,也就是说,这些页面包含了重要信息,在用户登陆之前或者退出之后都不应该出现在浏览器中。login.jsp包含了用于用户输入用户名和密码的form。logout.jsp页包含了要求用户确认是否退出的form。loginAction.jsp和logoutAction.jsp作为控制器分别包含了登陆和退出代码。
2023-08-05 20:58:031

C# 使用bitmap绘图,base.Invalidate()重画,有残影怎么办

这个要用到缓冲区的技术,就是你要定义一个缓冲区,然后图是画在缓冲区上的,画完之后,再把缓冲区的图绘制到你的当前工作区。
2023-08-05 20:58:161

VB 中InvalidateEventHandler是什么意思?

InvalidateEventHandler委托创建InvalidateEventHandler委托时,标识将处理事件的方法。若要使该事件与事件处理程序相关联,请将该委托的一个实例添加到事件中。除非移除了该委托,否则每当发生该事件时就调用事件处理程序。有关用委托处理事件的更多信息给分~
2023-08-05 20:58:281

VC中 InvalidateRect,RedrawWindow和UpdateWindow的区别

InvalidateRect是将客户区标记为无效,并产生WM_PAINT消息,Windows会将WM_PAINT消息放入队列,等待窗口过程的处理,然后操作系统将WM_PAINT当作是低优先级消息,如果后面有其他的动作要处理,则可能会出现空白的区域需要等待一段时间才被刷新。UpdateWindow则将导致操作系统立即用WM_PAINT调用窗口过程,而不进入队列,使窗口得到立即的刷新。窗口过程完成刷新后立即退出,Windows将控制返回给UpdateWindow之后的语句。RedrawWindow()则是具有Invalidate()和UpdateWindow()的双特性。声明窗口的状态为无效,并立即更新窗口,立即调用WM_PAINT消息处理。InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效InvalidateRect函数中的参数TRUE表示系统会在你画之前用背景色将所选区域覆盖一次,默认背景色为白色,可以通过设置BRUSH来改变背景色。Invalidate()之后:...OnPaint()->OnPrepareDC()->OnDraw()所以只是刷新在OnPaint()和OnDraw()函数中的绘图语句。其它地方没有影响。Invalidate标记一个需要重绘的无效区域,并不意味着调用该函数后就立刻进行重绘。类似于PostMessage(WM_PAINT),需要处理到WM_PAINT消息时才真正重绘。以为您Invalidate之后还有其他的语句正在执行,程序没有机会去处理WM_PAINT消息,但当函数执行完毕后,消息处理才得以进行。Invalidate只是放一个WM_PAINT消息在队列里,不做别的,所以只有当当前函数返回后,进入消息循环,取出WM_PAINT,才执行PAINT,所以不管Invalidate放哪里,都是最后的。UpdateWindow只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WM_PAINT如果希望立即刷新无效区域,可以在调用InvalidateRect之后调用UpdateWindow,如果客户区的任一部分无效,则 UpdateWindow将导致Windows用WM_PAINT消息调用窗口过程(如果整个客户区有效,则不调用窗口过程)。这一WM_PAINT消息不进入消息队列,直接由WINDOWS调用窗口过程。窗口过程完成刷新以后立刻退出,WINDOWS将控制返回给程序中UpdateWindow调用之后的语句。(windows程序设计第5版 P98)
2023-08-05 20:58:521

基于对话框的mfc,在OnInitDialog()中加入Invalidate(FALSE); UpdateWindow(); 为什么不响应onpaint()

在消息映射中加入WM_PAINT这个宏BEGIN_MESSAGE_MAP(CestClientDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT()END_MESSAGE_MAP()
2023-08-05 20:59:042

什么原因会引发displayeventreceiver一直在运行

们先看收到VSync事件是如何处理的,再看底层是怎样向上层通知VSync事件。1.SurfaceFlinger如何处理Vsync事件在SurfaceFlinger定义了一个消息队列的成员变量:mutableMessageQueue mEventQueue;MessageQueue是一个消息处理类,专门处理如下三种消息:INVALIDATE, REFRESH, TRANSACTION。这三个消息都与UI更新相关。SurfaceFlinger在自己的主线程中等待上述消息的到来,以便进行相应的处理,代码如下(后面我们会看到,VSync事件会触发上述消息):[cpp] view plain copy bool SurfaceFlinger::threadLoop() {waitForEvent();return true; } 其中waitForEvent又调用的MessageQueue的waitMessage函数:[cpp] view plain copy void SurfaceFlinger::waitForEvent() {mEventQueue.waitMessage(); } 所以SurfaceFlinger依赖MessageQueue截获上述消息,那又是通过怎样的流程向MessageQueue发送上述消息呢?换句话说,MessageQueue又是如何接收到上述三个消息的呢?而这一切又是与EventThread类相关。通过查看MessageQueue的定义,可以看到,它定义了一个EventThread的成员变量,并通过setEventThread初始化,代码如下:[cpp] view plain copy void MessageQueue::setEventThread(const sp<EventThread>& eventThread) {mEventThread = eventThread;mEvents = eventThread->createEventConnection();mEventTube = mEvents->getDataChannel();mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,MessageQueue::cb_eventReceiver, this); } 通过此接口,不仅获取了一个EventThread实例的引用,同时,通过EventThread创建一个IDisplayEventConnection对象,它代表了接收显示事件(主要是VSync事件以及HotPlug事件)的一个远程连接接收端,并通过Looper对象监听发生在此对象上的显示事件。在EventThread的线程循环中,等待VSync事件的发生,代码如下:[cpp] view plain copy bool EventThread::threadLoop() {DisplayEventReceiver::Event event;Vector< sp<EventThread::Connection> > signalConnections;signalConnections = waitForEvent(&event);// dispatch events to listeners...const size_t count = signalConnections.size();for (size_t i=0 ; i<count ; i++) {const sp<Connection>& conn(signalConnections[i]);// now see if we still need to report this eventstatus_t err = conn->postEvent(event);…}return true; } 在waitForEvent中,检测VSync事件,Connection::postEvent(DisplayEventReceiver::sendEvents)则将检测到的VSync事件发送给监听者。前面提到,通过Looper对象监听发生的VSync事件,它会调用回调函数MessageQueue::cb_eventReceiver,它实际会调用MessageQueue::eventReceiver,代码如下:[cpp] view plain copy int MessageQueue::eventReceiver(int fd, int events) {ssize_t n;DisplayEventReceiver::Event buffer[8];while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {for (int i=0 ; i<n ; i++) {if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { #if INVALIDATE_ON_VSYNCmHandler->dispatchInvalidate(); #elsemHandler->dispatchRefresh(); #endifbreak;}}}return 1; } 对于VSync事件的处理,会调用MessageQueue::Handler::dispatchInvalidate()或MessageQueue::Handler::dispatchRefresh(),代码如下:[cpp] view plain copy void MessageQueue::Handler::dispatchRefresh() {if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));} }void MessageQueue::Handler::dispatchInvalidate() {if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));} } 最终在如下消息处理函数中,对VSync事件进行处理:[cpp] view plain copy void MessageQueue::Handler::handleMessage(const Message& message) {switch (message.what) {case INVALIDATE:android_atomic_and(~eventMaskInvalidate, &mEventMask);mQueue.mFlinger->onMessageReceived(message.what);break;case REFRESH:android_atomic_and(~eventMaskRefresh, &mEventMask);mQueue.mFlinger->onMessageReceived(message.what);break;case TRANSACTION:android_atomic_and(~eventMaskTransaction, &mEventMask);mQueue.mFlinger->onMessageReceived(message.what);break;} } 如上代码所示,实际上会执行SurfaceFlinger类里定义的回调函数,在那里面对开头提到的三种消息进行真正的处理,即对VSync事件的响应最终转变成对上述三种消息进行处理。2.VSync事件产生流程分析上述分析了,从等待接收VSync事件到最后处理VSync事件的过程。下面我们要看下VSync事件是如何产生的,即是如何通知SurfaceFlinger::waitEvent返回的。众所周知,VSync事件一般由硬件周期性产生,如果没有相应的硬件产生VSync事件,则通过软件模拟。下面主要看下从硬件产生VSync事件到触发MessageQueue处理VSync事件的过程。首先,看下HWComposer的定义:[cpp] view plain copy class HWComposer { public:class EventHandler {friend class HWComposer;virtual void onVSyncReceived(int disp, nsecs_t timestamp) = 0;virtual void onHotplugReceived(int disp, bool connected) = 0;protected:virtual ~EventHandler() {}};enum {MAX_DISPLAYS = HWC_NUM_DISPLAY_TYPES + 1};HWComposer(const sp<SurfaceFlinger>& flinger,EventHandler& handler);… } 可以看到,HWComposer::EventHandler定义了通知VSync事件的回调接口。而SurfaceFlinger是实现了上述接口。所以问题变成,当底层硬件发生VSync事件时,会回调一个EventHandler对象的onVSyncReceived函数。实际上,在HWComposer的构造函数中,注册了底层hwcomposer硬件发送VSync事件的回调函数,首先,在SurfaceFlinger的readyToRun函数中,新建了一个HWComposer对象:[cpp] view plain copy // Initialize the H/W composer object. There may or may not be an// actual hardware composer underneath.mHwc = new HWComposer(this,*static_cast<HWComposer::EventHandler *>(this)); 接着在HWComposer的构造函数中,注册了hwcomposer回报VSync事件时调用的回调函数:[cpp] view plain copy HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger,EventHandler& handler): mFlinger(flinger),mFbDev(0), mHwc(0), mNumDisplays(1),mCBContext(new cb_context),mEventHandler(handler),mVSyncCount(0), mDebugForceFakeVSync(false) {…bool needVSyncThread = true;// Note: some devices may insist that the FB HAL be opened before HWC.int fberr = loadFbHalModule();loadHwcModule();…if (mHwc) {ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,(hwcApiVersion(mHwc) >> 24) & 0xff,(hwcApiVersion(mHwc) >> 16) & 0xff);if (mHwc->registerProcs) {mCBContext->hwc = this;mCBContext->procs.invalidate = &hook_invalidate;mCBContext->procs.vsync = &hook_vsync;if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))mCBContext->procs.hotplug = &hook_hotplug;elsemCBContext->procs.hotplug = NULL;memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));mHwc->registerProcs(mHwc, &mCBContext->procs);}// don"t need a vsync thread if we have a hardware composerneedVSyncThread = false;// always turn vsync off when we starteventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);// the number of displays we actually have depends on the// hw composer versionif (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_EXP)) {// 1.?? adds support for virtual displaysmNumDisplays = MAX_DISPLAYS;} else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {// 1.1 adds support for multiple displaysmNumDisplays = NUM_PHYSICAL_DISPLAYS;} else {mNumDisplays = 1;}}…if (needVSyncThread) {// we don"t have VSYNC support, we need to fake itmVSyncThread = new VSyncThread(*this);} }
2023-08-05 20:59:131

一个英语句子不太懂

联系这篇文章
2023-08-05 20:59:323

认可 不认可的英文是什么?

acknowledgedo not acknowledge
2023-08-05 20:59:566

退出登录的时候清空session

session.invalidate();这个是对的。详细看api!
2023-08-05 21:01:076

VC写的一个窗口问题InvalidateRect无效

调用Invalidaterec会使整个窗口无效,导致重回这时需要处理WM_PAINT消息,在这个消息里面进行绘图操作,你把WM_SIZE里面TextOut那一段移动到WM_PAINT里面就可以
2023-08-05 21:01:211

验证响应中是否至少有一个会话标识未更新

我的系统在做AppScan安全扫描时,爆出一个高危漏洞:会话标识未更新。提供的解决办法是,在用户登录时始终使用新的会话。 我仔细查看了我的系统。原来在用户进入登录页面,但还未登录时,就已经产生了一个session,用户输入信息,登录以后,session的id不会改变,也就是说还是以前的那个session(事实上session也确实不会改变,因为没有建立新session,原来的session也没有被销毁)。 后来我做了如下改变。在我的登录servlet里面将用户刚进入登录页面的那个session用invalidate()销毁掉,在用户信息匹配成功后,再建立一个新session,将用户信息放到session中去。本来以为这种做法应该可以解决问题了,但是再扫描发现问题还存在。再一查看,发现新建立的session与原来被销毁的session的id居然还是一样的。真是搞不懂了! 系统背景:j2ee,jboss 以下是我的登录servlet的代码:···HttpSession session = request.getSession(false);System.out.println(session.getId());if(session!=null){ session.invalidate();}/***接下来是对用户进行认证的代码***/······/***用户认证代码结束***/HttpSession session1 = request.getSession(true);System.out.println(session1.getId());session1.setAttribute("",***); 后来我找了好久才发现,之所以将会话invalidate没有用,是因为invalidate方法不是真正的将session销毁,只是将session中的内容清空,所以当我invalidate以后再新建session,新建的session其实不是新的,是将之前的session重新启用了。于是session的id不变就不奇怪了。 要怎么才能真正的将session销毁掉呢?看看下面的办法: 在登录页面上加上一段代码:request.getSession().invalidate();//清空sessionCookie cookie = request.getCookies()[0];//获取cookiecookie.setMaxAge(0);//让cookie过期然后用户再输入信息登录时,就会产生一个新的session了。 虽然我的系统里面没有使用cookie,但是只要是web系统就离不开cookie。系统里面没有使用cookie是我没有用cookie来保存数据、标示用户等等。但是服务器跟踪会话状态就是用的cookie。既然cookie是服务器用来跟踪会话状态的,那么如果cookie过期了,会怎么样?--不用解释了吧。回答了这个问题,怎么让会话真正被销毁也就不难回答了。 我在登陆页面上加的那段代码的作用就是,将用户进入登陆页面时所产生的会话也就是session清空,然后让跟踪这个会话的cookie过期,这样服务器就不再掌握有关这个会话的任何信息了。要想与服务器继续通信,就要产生一个新的会话才行。于是会话标示就更新了!
2023-08-05 21:01:291

C#这段代码的作用

这段代码的作用是:当鼠标滚轮滚动时,重新显示richTextBox1的内容(比如向下滚动,就显示下面的文本)。richTextBox1.Invalidate();重绘richTextBox1。
2023-08-05 21:01:381

android 如何让view在不调用invalidate时不自动ondraw

加钱换高配手机吧。 底配的怎么用都是卡
2023-08-05 21:01:522

透明static文本框有文字重叠,调用InvalidateRect刷新的话又会有闪烁

要是aspnet的话 直接加AJAX控件就好啦 可以设置定时自动刷新显示对话的文本框~
2023-08-05 21:02:003

C++中关于函数InvalidateRect的疑问

首先说一点,InvalidateRect是Windows系统提供的API函数,不是C++的,而且Win32函数都是用C语言实现的,像MFC,ATL只是用C++来把这些东西封装一下。C++只是一种语言,一个工具,能提供函数的只有库和系统平台。InvalidateRect的确会给窗口发送一个WM_PAINT消息以让指定的RECT重绘,不过它是将消息发送给窗口的消息队列,而UpdateWindow是直接将消息发送给窗口过程。
2023-08-05 21:02:081

session.invalidate()导致jsp都不能使用session了

建立新的session,session不是cookie
2023-08-05 21:02:261

C# 一个关于Graphics类的问题

你把 e.Graphics.DrawImage(bitmap, 0, 0); 这句话拿到button2_Click事件方法里试试
2023-08-05 21:02:332

MFC中ProcessMessage()函数有什么作用?

while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){//调用窗口对应的消息处理函数TranslateMessage (&msg); DispatchMessage (&msg);}而这个PeekMessage是从当前线程的消息队列获取消息。你程序中如果使用PostMessage则可以把消息放入消息队列,但是要等待上一条消息被处理完,如果使用SendMessage,就不用放入消息队列,直接响应,而MFC内部控制界面,如你的Invalidate();会PostMesage ,所以,你当前函数没退出,那就不能响应消息,于是,如果你在循环时MSG msg; if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){TranslateMessage (&msg); DispatchMessage (&msg);}那就可以从消息队列处理消息,那就不会阻塞程序正常运行。
2023-08-05 21:02:443

C#中的onpaint函数怎么用的

不用代码演示,原理很简单的。System.Windows.Forms.Form类中有一个Invalidate()方法成员,它把客户窗口区域标记为无效,并保引发Paint事件。Invalidate()有几个重载方法,可以给它传送一个矩形参数(Rectangle类型),指定(使用页面坐标)需要重新绘制的窗口区域;如果不提供它任何参数,就把整个客户区域标记为无效;如果绘制区域不是矩形,可以向它传递区域参数(Region类型),Region和Rectangle不同是可以对多个Region做交并差操作,生成复杂的无效区域。在编程中,根据需要绘图的区域,首先生成这块区域的对象,以该对象作为参数调用Invalidate()方法,就可以引发Paint事件了,这块区域在Paint看来就变成无效区域了。至于绘图是Paint事件处理干的事。对Paint事件编程,首先根据Paint事件参数获取无效区域,然后在无效区域中按要求绘制就可以了。
2023-08-05 21:02:591

InvalidateRect()的最后一个参数是表示擦除背景,还是只是在PAINTSTRUCT中留下标记。

1表示擦除背景,0表示保留背景
2023-08-05 21:03:062

Java,我做一个web项目的注销,怎么清除session里的值,

用session的removeAttribute("uiUsers");方法试试嘿嘿,不好用的话跟我说声,我再给你看看
2023-08-05 21:03:165

用InvalidateRect部分重绘桌面

代码中RECT的引用有问题,以下是我写的示例代码~ 重点在于RECT的定义与C#中的Rectangle不同。 至于传空指针为什么导致全屏刷新,在API中零一般表示更新桌面窗口。using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Threading; using System.Drawing; namespace test { class Program { public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern IntPtr GetDesktopWindow(); [DllImport("user32.dll", EntryPoint = "GetDCEx", CharSet = CharSet.Auto, ExactSpelling = true)] private static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, int flags); [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern bool RedrawWindow(IntPtr hwnd,ref RECT rcUpdate, IntPtr hrgnUpdate, int flags); static void Main(string[] args) { while (true) { RECT trect; trect.Left = 150; trect.Right = 450; trect.Top = 150; trect.Bottom = 450; RedrawWindow(GetDesktopWindow(), ref trect, IntPtr.Zero, 0x85); IntPtr desk = GetDesktopWindow(); IntPtr deskDC = GetDCEx(desk, IntPtr.Zero, 0x403); Graphics g = Graphics.FromHdc(deskDC); g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Red)), new Rectangle(100, 100, 400, 400)); Thread.Sleep(1000); } } } }
2023-08-05 21:03:301

自定义View面试总结

不负责任系列 本文只针对继承View的方式,另两种自行学习。 可能多次触发,在measure的过程中注意MeasureSpec,specMode、specSize 讲到LinearLayout、RelativeLayout源码 表示父布局希望子布局的大小应该是由specSize的值来决定的,系统默认会按照这个规则来设置子布局的大小,开发人员当然也可以按照自己的意愿设置成任意的大小。 表示子布局最多只能是specSize中指定的大小,开发人员应该尽可能小得去设置这个布局,并且保证不会超过specSize。系统默认会按照这个规则来设置子布局的大小,开发人员当然也可以按照自己的意愿设置成任意的大小。 表示开发人员可以将布局按照自己的意愿设置成任意的大小,没有任何限制。这种情况比较少见,不太会用到。 上图表摘自 https://blog.csdn.net/singwhatiwanna/article/details/38426471 在ViewGroup中,只触发一次,决定子View的位置 绘制内容,Canvas.drawxxx(),paint 处理点击事件 Android视图树的根节点是DecorView,而它是FrameLayout的子类,所以就会让其子视图绘制两次,所以onMeasure函数会先被调用两次。 invalidate方法会执行draw过程,重绘View树。 当改变view的显隐性、背景、状态(focus/enable)等,这些都属于appearance范畴,都会引起invalidate操作。需要更新界面显示,就可以直接调用invalidate方法。 注意: 在子线程中被调用,刷新UI。 当View的宽高,发生了变化,不再适合现在的区域,调用requestLayout方法重新对View布局。 当View执行requestLayout方法,会向上递归到顶级父View中,再执行这个顶级父View的requestLayout,所以其他View的onMeasure,onLayout也可能会被调用。 3
2023-08-05 21:03:371

请问C#中的paint事件是怎么实现的?

Refresh()
2023-08-05 21:03:484

MFC中SetTimer()的用法???

其他函数看不到啊!switch都带上break和default:
2023-08-05 21:04:097

JAVA出错了,不知道原因,谁给看看!

Can"t call invalidate() when session is no longer valid.
2023-08-05 21:04:262

关于MFC画图闪烁的问题

奉劝最好别用mfc的图像绘制,很麻烦 我记得用MemDC 可以解决闪烁问题, 但是效果也并不好..所以我奉劝你使用OpenGl来绘制 ,或者采用QT ,wxwidget 等库.MFC 已经过时了,画啥都麻烦
2023-08-05 21:04:344

Graphics.DrawImage() 控件闪烁问题

1.使用DoubleBuffer2.创建一个Image,然后先把内容绘制好,再把这个Image画上去比较好,而不要直接画在界面上
2023-08-05 21:04:422

用MFC开发单文档程序,用到了OnMouseMove消息,但是这个函数里的InvalidateRect一开始无效

你用到OnMouseMove函数,就要对它重载,当系统响应鼠标移动消息时,会调用你重载的函数,所以你按钮消息中需要加入InvalidateRect
2023-08-05 21:04:492

VC最小化能够正常重画,但是把窗口拖到边界重画就失败了,这是为何啊?

把窗口拖到边界是什么意思,拖到边界为什么就应该重绘,重绘发生在窗口被重新显示时候发生,这样的重绘是自动的,有可能是全部,有可能是部分。
2023-08-05 21:04:573

vc++里面自动重绘的问题

执行了Invalidate()、UpdateWindow()后,系统自动调用OnPaint函数,你把这两个函数写在OnPaint函数里,这不是死循环了吗。。Invalidate()、UpdateWindow()可以在改变参数的地方调用。
2023-08-05 21:05:056