{
CTreeCtrl::OnLButtonUp(nFlags, point);
if( m_bDragging )
{
.....
}
}
这是在一个对话框中放了一个树控件,CMyTreeCtrl是对话框生成的类。
我的程序本身就是CMyTreeCtrl::OnLButtonUp,
为什么还要在程序加上CTreeCtrl::OnLButtonUp(nFlags, point);呢?
这两个函数就是有什么区别呢?
5 个解决方案
#1
消息流
如果WM_KEYDOWM目标窗口是Control消息流向如下:下面所说的“处理了”的意思是返回true.
CWinThread::PUMPMESSAGE()从消息队列中取得WM_KEYDOWM
↓
CWinThread::PreTranslateMessage处理--->使用WalkPreTranslateTree让从该控件遍列其父窗口直到主窗口,让他们依次处理,如果其中一个处理了则结束循环。其实是分别调用他们的PreTranslateMessage
↓未处理
::TranslateMessage-->产生WM_CHAR消息放入消息队列(不考虑其他情况)
↓
::DispathMessage -->让该控件窗口消息函数WindowProc处理,遍列消息表找到WM_KEYDOWN的消息影射函数OnKeyDown在其中处理
↓ 未处理
到该控件的DefWindowProc中作最后的处理,如记录按键的次数以供后面处理。
↓
该消息处理结束,再取的下一个消息WM_CHAR
↓
CWinThread::PreTranslateMessage处理-->和上面处理WM_KEYDOWM一样
可以在CAppDlg::PreTranslateMessage()、CDebugEdit::PreTranslateMessage()、CDebugEdit::WindowProc()、CDebugEdit::OnChar()、CDebugEdit::DefWindowProc()处理输入字符,但后面的必须保证前面消息流正常运行,正确处理之后保证返回true
如果你使用在CDebugEdit::OnKeyDown()中使用MessageBox作提示的话,这里就有个问题了。你会先得到CDebugEdit::OnChar()中的MessageBox提示。这是因为当产生一个MessageBox时会有一个消息循环并且从消息循环中取得下一个消息,也就是刚刚由TranslateMessage产生的WM_CHAR(因为消息是FIFO的,WM_CREATE还在后面呢)。当然该MessageBox不会处理这个消息,所以就到了CDebugEdit::OnChar()中,就弹出了一个MessageBox。
同样道理也接受不到WM_KEYUP,因为该消息是产生MessageBox时发出的。这时的焦点窗口是该MessageBox的确定按纽。
你可以把这行去掉,消息就不会流向你的基类了。
如果WM_KEYDOWM目标窗口是Control消息流向如下:下面所说的“处理了”的意思是返回true.
CWinThread::PUMPMESSAGE()从消息队列中取得WM_KEYDOWM
↓
CWinThread::PreTranslateMessage处理--->使用WalkPreTranslateTree让从该控件遍列其父窗口直到主窗口,让他们依次处理,如果其中一个处理了则结束循环。其实是分别调用他们的PreTranslateMessage
↓未处理
::TranslateMessage-->产生WM_CHAR消息放入消息队列(不考虑其他情况)
↓
::DispathMessage -->让该控件窗口消息函数WindowProc处理,遍列消息表找到WM_KEYDOWN的消息影射函数OnKeyDown在其中处理
↓ 未处理
到该控件的DefWindowProc中作最后的处理,如记录按键的次数以供后面处理。
↓
该消息处理结束,再取的下一个消息WM_CHAR
↓
CWinThread::PreTranslateMessage处理-->和上面处理WM_KEYDOWM一样
可以在CAppDlg::PreTranslateMessage()、CDebugEdit::PreTranslateMessage()、CDebugEdit::WindowProc()、CDebugEdit::OnChar()、CDebugEdit::DefWindowProc()处理输入字符,但后面的必须保证前面消息流正常运行,正确处理之后保证返回true
如果你使用在CDebugEdit::OnKeyDown()中使用MessageBox作提示的话,这里就有个问题了。你会先得到CDebugEdit::OnChar()中的MessageBox提示。这是因为当产生一个MessageBox时会有一个消息循环并且从消息循环中取得下一个消息,也就是刚刚由TranslateMessage产生的WM_CHAR(因为消息是FIFO的,WM_CREATE还在后面呢)。当然该MessageBox不会处理这个消息,所以就到了CDebugEdit::OnChar()中,就弹出了一个MessageBox。
同样道理也接受不到WM_KEYUP,因为该消息是产生MessageBox时发出的。这时的焦点窗口是该MessageBox的确定按纽。
你可以把这行去掉,消息就不会流向你的基类了。
#2
有些工作是需要由父类来完成的。
#3
因为你的CMyTreeCtrl是继承自CTreeCtrl,如果不调用基类的OnLButtonUp,完全自己处理,你的TreeCtrl的行为就有可能会不是正常的TreeCtrl应有的行为,所以一般总是先调用基类的函数作基本处理,然后再加入自己特殊的代码。
#4
打个比方!
老师这个职位的主要工作就教学生,这是制度上的规定(制度就是ApplicationFrameWork)
但是学校为了灵活,从老师这个职位中派生出校长来,他在教学生的同时还有责任去管理其它老师和整个学校。那么:
Class 校长类 : public 老师类
{
....
};
void 校长类::命令(...)
{
老师类::命令(...);//先做好基础工作。
if( m_bDragging )//再进行其它和校长这一职务相当的特殊工作。
{
.....
}
}
老师这个职位的主要工作就教学生,这是制度上的规定(制度就是ApplicationFrameWork)
但是学校为了灵活,从老师这个职位中派生出校长来,他在教学生的同时还有责任去管理其它老师和整个学校。那么:
Class 校长类 : public 老师类
{
....
};
void 校长类::命令(...)
{
老师类::命令(...);//先做好基础工作。
if( m_bDragging )//再进行其它和校长这一职务相当的特殊工作。
{
.....
}
}
#5
比哈很恰当,不会是老师吧?
#1
消息流
如果WM_KEYDOWM目标窗口是Control消息流向如下:下面所说的“处理了”的意思是返回true.
CWinThread::PUMPMESSAGE()从消息队列中取得WM_KEYDOWM
↓
CWinThread::PreTranslateMessage处理--->使用WalkPreTranslateTree让从该控件遍列其父窗口直到主窗口,让他们依次处理,如果其中一个处理了则结束循环。其实是分别调用他们的PreTranslateMessage
↓未处理
::TranslateMessage-->产生WM_CHAR消息放入消息队列(不考虑其他情况)
↓
::DispathMessage -->让该控件窗口消息函数WindowProc处理,遍列消息表找到WM_KEYDOWN的消息影射函数OnKeyDown在其中处理
↓ 未处理
到该控件的DefWindowProc中作最后的处理,如记录按键的次数以供后面处理。
↓
该消息处理结束,再取的下一个消息WM_CHAR
↓
CWinThread::PreTranslateMessage处理-->和上面处理WM_KEYDOWM一样
可以在CAppDlg::PreTranslateMessage()、CDebugEdit::PreTranslateMessage()、CDebugEdit::WindowProc()、CDebugEdit::OnChar()、CDebugEdit::DefWindowProc()处理输入字符,但后面的必须保证前面消息流正常运行,正确处理之后保证返回true
如果你使用在CDebugEdit::OnKeyDown()中使用MessageBox作提示的话,这里就有个问题了。你会先得到CDebugEdit::OnChar()中的MessageBox提示。这是因为当产生一个MessageBox时会有一个消息循环并且从消息循环中取得下一个消息,也就是刚刚由TranslateMessage产生的WM_CHAR(因为消息是FIFO的,WM_CREATE还在后面呢)。当然该MessageBox不会处理这个消息,所以就到了CDebugEdit::OnChar()中,就弹出了一个MessageBox。
同样道理也接受不到WM_KEYUP,因为该消息是产生MessageBox时发出的。这时的焦点窗口是该MessageBox的确定按纽。
你可以把这行去掉,消息就不会流向你的基类了。
如果WM_KEYDOWM目标窗口是Control消息流向如下:下面所说的“处理了”的意思是返回true.
CWinThread::PUMPMESSAGE()从消息队列中取得WM_KEYDOWM
↓
CWinThread::PreTranslateMessage处理--->使用WalkPreTranslateTree让从该控件遍列其父窗口直到主窗口,让他们依次处理,如果其中一个处理了则结束循环。其实是分别调用他们的PreTranslateMessage
↓未处理
::TranslateMessage-->产生WM_CHAR消息放入消息队列(不考虑其他情况)
↓
::DispathMessage -->让该控件窗口消息函数WindowProc处理,遍列消息表找到WM_KEYDOWN的消息影射函数OnKeyDown在其中处理
↓ 未处理
到该控件的DefWindowProc中作最后的处理,如记录按键的次数以供后面处理。
↓
该消息处理结束,再取的下一个消息WM_CHAR
↓
CWinThread::PreTranslateMessage处理-->和上面处理WM_KEYDOWM一样
可以在CAppDlg::PreTranslateMessage()、CDebugEdit::PreTranslateMessage()、CDebugEdit::WindowProc()、CDebugEdit::OnChar()、CDebugEdit::DefWindowProc()处理输入字符,但后面的必须保证前面消息流正常运行,正确处理之后保证返回true
如果你使用在CDebugEdit::OnKeyDown()中使用MessageBox作提示的话,这里就有个问题了。你会先得到CDebugEdit::OnChar()中的MessageBox提示。这是因为当产生一个MessageBox时会有一个消息循环并且从消息循环中取得下一个消息,也就是刚刚由TranslateMessage产生的WM_CHAR(因为消息是FIFO的,WM_CREATE还在后面呢)。当然该MessageBox不会处理这个消息,所以就到了CDebugEdit::OnChar()中,就弹出了一个MessageBox。
同样道理也接受不到WM_KEYUP,因为该消息是产生MessageBox时发出的。这时的焦点窗口是该MessageBox的确定按纽。
你可以把这行去掉,消息就不会流向你的基类了。
#2
有些工作是需要由父类来完成的。
#3
因为你的CMyTreeCtrl是继承自CTreeCtrl,如果不调用基类的OnLButtonUp,完全自己处理,你的TreeCtrl的行为就有可能会不是正常的TreeCtrl应有的行为,所以一般总是先调用基类的函数作基本处理,然后再加入自己特殊的代码。
#4
打个比方!
老师这个职位的主要工作就教学生,这是制度上的规定(制度就是ApplicationFrameWork)
但是学校为了灵活,从老师这个职位中派生出校长来,他在教学生的同时还有责任去管理其它老师和整个学校。那么:
Class 校长类 : public 老师类
{
....
};
void 校长类::命令(...)
{
老师类::命令(...);//先做好基础工作。
if( m_bDragging )//再进行其它和校长这一职务相当的特殊工作。
{
.....
}
}
老师这个职位的主要工作就教学生,这是制度上的规定(制度就是ApplicationFrameWork)
但是学校为了灵活,从老师这个职位中派生出校长来,他在教学生的同时还有责任去管理其它老师和整个学校。那么:
Class 校长类 : public 老师类
{
....
};
void 校长类::命令(...)
{
老师类::命令(...);//先做好基础工作。
if( m_bDragging )//再进行其它和校长这一职务相当的特殊工作。
{
.....
}
}
#5
比哈很恰当,不会是老师吧?