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

本文目录
- 基于对话框的mfc,在OnInitDialog()中加入Invalidate(FALSE); UpdateWindow(); 为什么不响应onpaint()
- 【VC++】Invalidate的参数True与False到底有什么区别
- android 是怎么通过在XML中配置的控件属性得到具体的view对象
基于对话框的mfc,在OnInitDialog()中加入Invalidate(FALSE); UpdateWindow(); 为什么不响应onpaint()
MFC标准对话框中,OnInitDialog是对话框初始化函数,在调用这个函数之后,MFC框架会自动触发重绘,调用OnPaint,而在之前的任何触发,也必须在初始化完成之后,也就是OnInitDialog执行完成之后。
你所说的不响应具体是什么现象,如果说,是OnPaint里面的断点在调试中从不触发,那么是WM_PAINT消息响应有问题,如果说,是在调用函数的时候不进入断点,那么这是正常的,所有的触发重绘都不是立刻执行,而是在消息空闲时执行的,也就是必须等待上一个消息结束。
【VC++】Invalidate的参数True与False到底有什么区别
Invalidate 简单的认为可以使客户区域重新绘制,参数为false的时候,只重新绘制客户区域,比如一个控件什么的。如果参数为True,除了绘制客户区,还要重新绘制背景。
android 是怎么通过在XML中配置的控件属性得到具体的view对象
我可能表达的不是很清楚,那就拿个具体的例子来说明吧
比如说,在Activity中我们需要用到一个ProgressBar控件,我们一般先在layout下的main.xml中进行配置
Xml代码
《ProgressBar
android:id="@+id/pb1"
android:layout_width="fill_parent"
android:layout_height="20dip"
《span style="color: #ff0000;"》 android:indeterminateOnly="false"《/span》
android:layout_gravity="center_vertical"
android:progressDrawable="@android:drawable/progress_horizontal"
android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"
android:minHeight="20dip"
android:maxHeight="20dip"
/》
我们看 android:indeterminateOnly="false" 这行代码的
一般我们如果要将在代码中创建一个ProgressBar,但是不通过配置文件得到。
代码如下:
Java代码
ProgressBar mProgressBar=new ProgressBar(context);
《span style="color: #ff0000;"》mProgressBar.setIndeterminate(false); 《/span》
mProgressBar.setProgressDrawable(getResources().getDrawable
(android.R.drawable.progress_horizontal));
mProgressBar.setIndeterminateDrawable(getResources().getDrawable
(android.R.drawable.progress_indeterminate_horizontal));
本来我们是希望创建一个普通的能显示进度的横条ProgressBar
但是我们发现progressBar中的进度无法更新。
我们来看进度更新的源代码setProgress():
Java代码
@android.view.RemotableViewMethod
synchronized void setProgress(int progress, boolean fromUser) {
《span style="color: #ff0000;"》 if (mIndeterminate) {
return;
}《/span》
if (progress 《 0) {
progress = 0;
}
if (progress 》 mMax) {
progress = mMax;
}
if (progress != mProgress) {
mProgress = progress;
refreshProgress(R.id.progress, mProgress, fromUser);
}
}
关键是: if (mIndeterminate) { return; }
原来mIndeterminate 的值为true的话,函数直接返回了,也就是我们不能设置progressBar的进度(mProgress)
现在我们的任务是将mIndeterminate 属性设置为false
但是我们发现 mProgressBar.setIndeterminate(false); 这行代码并没有设置mIndeterminate 属性为false
我们看ProgressBar中的源代码:
Java代码
@android.view.RemotableViewMethod
public synchronized void setIndeterminate(boolean indeterminate) {
《span style="color: #ff0000;"》 if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) {《/span》
mIndeterminate = indeterminate;
if (indeterminate) {
// swap between indeterminate and regular backgrounds
mCurrentDrawable = mIndeterminateDrawable;
startAnimation();
} else {
mCurrentDrawable = mProgressDrawable;
stopAnimation();
}
}
}
看这行代码: if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) {
我们发现当mOnlyIndeterminate 和mIndeterminate 之前都为true时,我们并不能将mIndeterminate 从true改变为false
google后,有人通过反射机制将ProgressBar中的mOnlyIndeterminate 设置为false(具体请看:关于使用代码来创建ProgressBar )
我现在我就在想 既然 ProgressBar中的mOnlyIndeterminate 和mIndeterminate属性都是private,而且都不能通过get和set方法来对其进行操作,那么 android 通过在XML中配置的控件属性,是怎么被转换成真正的java类呢?
求大神解惑!
问题补充
over140 写道
你应该看一下他源码里关于这个的构造函数部分的代码,注意父类里面可能也有代码,他并不是转换成java类,只是读取从XML属性读取想要的参数。
你指的是ProgressBar类中的构造函数吗? 我之前就仔细看了这些东西
ProgressBar中构造函数源码:
Java代码
/**
* Create a new progress bar with range 0...100 and initial progress of 0.
* @param context the application environment
*/
public ProgressBar(Context context) {
this(context, null);
}
public ProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.progressBarStyle);
}
public ProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mUiThreadId = Thread.currentThread().getId();
initProgressBar();
TypedArray a =
context.obtainStyledAttributes(attrs, R.styleable.ProgressBar, defStyle, 0);
mNoInvalidate = true;
Drawable drawable = a.getDrawable(R.styleable.ProgressBar_progressDrawable);
if (drawable != null) {
drawable = tileify(drawable, false);
setProgressDrawable(drawable);
}
mDuration = a.getInt(R.styleable.ProgressBar_indeterminateDuration, mDuration);
mMinWidth = a.getDimensionPixelSize(R.styleable.ProgressBar_minWidth, mMinWidth);
mMaxWidth = a.getDimensionPixelSize(R.styleable.ProgressBar_maxWidth, mMaxWidth);
mMinHeight = a.getDimensionPixelSize(R.styleable.ProgressBar_minHeight, mMinHeight);
mMaxHeight = a.getDimensionPixelSize(R.styleable.ProgressBar_maxHeight, mMaxHeight);
mBehavior = a.getInt(R.styleable.ProgressBar_indeterminateBehavior, mBehavior);
final int resID = a.getResourceId(
com.android.internal.R.styleable.ProgressBar_interpolator,
android.R.anim.linear_interpolator); // default to linear interpolator
if (resID 》 0) {
setInterpolator(context, resID);
}
setMax(a.getInt(R.styleable.ProgressBar_max, mMax));
setProgress(a.getInt(R.styleable.ProgressBar_progress, mProgress));
setSecondaryProgress(
a.getInt(R.styleable.ProgressBar_secondaryProgress, mSecondaryProgress));
drawable = a.getDrawable(R.styleable.ProgressBar_indeterminateDrawable);
if (drawable != null) {
drawable = tileifyIndeterminate(drawable);
setIndeterminateDrawable(drawable);
}
mOnlyIndeterminate = a.getBoolean(
R.styleable.ProgressBar_indeterminateOnly, mOnlyIndeterminate);
mNoInvalidate = false;
setIndeterminate(mOnlyIndeterminate || a.getBoolean(
R.styleable.ProgressBar_indeterminate, mIndeterminate));
a.recycle();
}
看以上代码,发现ProgressBar类并没有使用其父类的构造方法, 它的三个构造方法最终都需要进入到第三个构造方法内,
再看这一句
Java代码
initProgressBar();
其中具体源码如下:
Java代码
private void initProgressBar() {
mMax = 100;
mProgress = 0;
mSecondaryProgress = 0;
mIndeterminate = false;
mOnlyIndeterminate = false;
mDuration = 4000;
mBehavior = AlphaAnimation.RESTART;
mMinWidth = 24;
mMaxWidth = 48;
mMinHeight = 24;
mMaxHeight = 48;
}
看 这两句:
Java代码
mIndeterminate = false;
mOnlyIndeterminate = false;
奇怪 在这个初始化ProgressBar的过程中,明明将mIndeterminate和mOnlyIndeterminate属性设置为false
但是我们初始化后的进度条,显示后同样是不会进度的(图如下)
也就是说 mIndeterminate属性依然是true(具体请看ProgressBar中的setProgress()方法)
继续看构造方法中的其他内容时,发现关键所在:
Java代码
mOnlyIndeterminate = a.getBoolean(
R.styleable.ProgressBar_indeterminateOnly, mOnlyIndeterminate);
mNoInvalidate = false;
setIndeterminate(mOnlyIndeterminate || a.getBoolean(
R.styleable.ProgressBar_indeterminate, mIndeterminate));
这两句将mOnlydeterminate和mIndeterminate属性都设置为true,
看到这里,发现这两句都用到 a 这个对象,a 具体是什么呢?
Java代码
TypedArray a =
context.obtainStyledAttributes(attrs, R.styleable.ProgressBar, defStyle, 0);
那我们能不能通过改变传入 构造函数 的参数 来使 a 发生相应的变化,进而使mOnlyIndeterminate和mIndeterminate属性设置为 true 呢?
再往下深入,发现看的我那是一头雾水,完全找不到方向,所以只得放弃这个猜想。
到最后,我发现 如果要通过正常的java访问机制(当然排除使用反射机制),来操作mOnlyIndeterminate和mIndeterminate属性是不可能的,
你说: 他并不是转换成java类,只是读取从XML属性读取想要的参数。
我们一般是通过findViewById()来根据layout中的XML文件设置的控件属性得到 具体的View控件对象(关于转换成java类,我错了,其实我想说的是怎么得到的这个对象),
这个过程是不是也是通过反射机制来完成的?假如是的话,能给我提供些具体过程的资料呢?

更多文章:
全球新冠肺炎疫情背景下航运发展(盐田港复苏日志:半年历劫从“低谷”到“爆仓” 疫情之后巨轮如何越洋航行)
2026年9月7日 17:10
matlab求解带字母参数方程组(我想matlab求一个关于x,y的方程组 ab c d f e h m n 都是参数)
2026年9月7日 16:30
oracle中的循环语句(下面哪个不是oracle程序设计中的循环语句 a for)
2026年9月7日 15:30
电脑里2个系统怎么删除一个(电脑开机显示有两个系统,如何删除一个)
2026年9月7日 12:20
scrollthrough意思(“scroll”是什么意思)
2026年9月7日 08:00
怎么激活keygen(注册机如何激活cad2008一个简单激活cad2008的方法)
2026年9月7日 06:30






