续:关于控件截获消息的问题

sarmoo 2003-01-22 11:37:22
请各位大侠指点:

我做了一个控件,要求它能够截获所在的Form上的键盘消息,
(即此Form上的所有键盘输入都要先经过我的控件,无论焦点在Form上的哪个控件)
如果键盘消息是控件自己定义过的,则控件首先进行处理,然后可以将消息接着传递下去,也可以就此停止消息的传递;没有定义过的则直接继续传递下去。
请问该怎么实现这个功能?

(注:只截获本Form上的消息,不可以多管闲事)
...全文
73 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuspcn 2003-08-12
  • 打赏
  • 举报
回复
mark
cherno 2003-04-10
  • 打赏
  • 举报
回复
回复人: HellMaster(李晋) ( ) 信誉:100 2003-01-22 17:54:00 得分:0


你不用知道包含控件的窗体是谁,你只要知道Form.ActiveForm有没有你的控件就可以了:
foreach (Control ctl in Form.ActiveForm.Controls)
{
if (ctl is 你的控件所属的类名)//如if (ctl is TextBox)
//下面写你的处理代码
}


————

好像有个ParentForm属性吧?
大健 2003-01-23
  • 打赏
  • 举报
回复
学习
0313700000 2003-01-23
  • 打赏
  • 举报
回复
mark
sarmoo 2003-01-23
  • 打赏
  • 举报
回复
高手!果然是高手!! 呵呵!
Tangheng2002 2003-01-23
  • 打赏
  • 举报
回复
HellMaster(李晋)
聪明!高!
sarmoo 2003-01-22
  • 打赏
  • 举报
回复
现在的问题是:
当我的焦点移到别的Form上的时候,这个钩子还在乱抢消息,
应该什么时候加载钩子,什么时候除掉它呢?
GiantHard 2003-01-22
  • 打赏
  • 举报
回复
用 AddMessageFilter

public class KeyBoardMessageFilter : IMessageFilter
{
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 256)
{
m_objC.HandleKeyPress(Convert.ToChar(m.WParam.ToInt64()));
}
return false;
}
}

//Form初始化代码中加上
Application.AddMessageFilter(new KeyBoardMessageFilter());
xuzhenhua21 2003-01-22
  • 打赏
  • 举报
回复
厉害呀,很有水平,
HellMaster 2003-01-22
  • 打赏
  • 举报
回复
你不用知道包含控件的窗体是谁,你只要知道Form.ActiveForm有没有你的控件就可以了:
foreach (Control ctl in Form.ActiveForm.Controls)
{
if (ctl is 你的控件所属的类名)//如if (ctl is TextBox)
//下面写你的处理代码
}
WSDOTNET 2003-01-22
  • 打赏
  • 举报
回复
自己也得多琢磨琢磨。
sarmoo 2003-01-22
  • 打赏
  • 举报
回复
sunwindone(周日华) :
其实我也很郁闷,我做的是一个ToolBar,系统都给了,还作什么作?!
不过我的功能应该比他强一点,当然是如果我做的好的话。
系统的ToolBar没有截获消息功能,而我要让我的这个能首先响应快捷键!
做好了就万事大吉了,上帝保佑我吧!
还望大家多支持!!
在这里先谢谢李晋兄一直的热心帮助,不过我的问题好像没完没了,你不要烦呀! :)
sarmoo 2003-01-22
  • 打赏
  • 举报
回复
哦,对了,ActiveForm是静态属性!:p
咦,不对呀,我记得静态的东西都是直接由类引用呀?

另外,我现在不知道我的这个控件被放到哪里去了,(所以我不知道包含控件的窗体是谁)我现在想找到它,可我不知道怎样用this.Parent,也许是this.Parent.Parent……
还有m.HWnd是指发消息的控件吗?不是窗体吗?
sunwindone 2003-01-22
  • 打赏
  • 举报
回复
在form上面可以直接截取键盘消息,不管你的焦点在该form的哪个控件上,
你为什么还要做一个这样的控件呢?

郁闷ing.......
HellMaster 2003-01-22
  • 打赏
  • 举报
回复
frmHold是你的窗体的名字呀
ActiveForm是属于整个应用程序的,你用别的窗口也是一样的
你看我上面的程序,
我先判断当前的活动窗口是不是frmHold
然后再判断截获消息的控件是不是textbox1
和你说的要求是一样的
sarmoo 2003-01-22
  • 打赏
  • 举报
回复
李兄:
你的这个程序我试过了,可还有不明白的地方:
1、首先你的PreFilterMessage中的frmHold是在哪声明的?
2、这个ActiveForm属性只属于Form的,我怎样从我的控件中找到这个?
(因为控件放在哪个Form或Panel不由我控制,我只能负责修理我的控件)
3、我只想我控件所在的Form有截获消息功能,该如何判断?

不好意思,还得让您多费心,呵呵 :)
HellMaster 2003-01-22
  • 打赏
  • 举报
回复
//================clsHold.cs================
using System;
using System.Windows.Forms;

namespace cmnTest
{
/// <summary>
/// clsHold 的摘要说明。
/// </summary>
public class clsHold:IMessageFilter
{
bool rtnValue=false;
const int WM_KEYDOWN = 0x100;
const int VK_DELETE=0x2E;

public clsHold()
{
//
// TODO: 在此处添加构造函数逻辑
//
}

public bool PreFilterMessage(ref Message m)
{
if(m.Msg == WM_KEYDOWN)
{
try
{
if (frmHold.ActiveForm is frmHold)
if (m.HWnd==((frmHold)frmHold.ActiveForm).textBox1.Handle)
if ((int)m.WParam==VK_DELETE)
((frmHold)frmHold.ActiveForm).textBox1.Text+="D";
}
catch
{}
//MessageBox.Show(m.WParam.ToString());
rtnValue=true;
}
else
rtnValue=false;

return rtnValue;
}
}
}

//=======================frmHold.cs=============================
private void frmHold_Load(object sender, System.EventArgs e)
{
Application.AddMessageFilter(new clsHold());
}
HellMaster 2003-01-22
  • 打赏
  • 举报
回复
好了

下面的程序是这样的

建一个Form(frmHold),上面放两个TextBox:textBox1,textBox2
当在textBox1中按delete的时候在textBox1的Text中加个"D"
怎么样,可以满足你的要求吧
HellMaster 2003-01-22
  • 打赏
  • 举报
回复
要不我再给你做一个示例好了
稍等 。。。。
sarmoo 2003-01-22
  • 打赏
  • 举报
回复
李兄:呵呵,谢谢你的回答!
可我还不知道怎么找到控件所在的Form的Handle,我的控件的Parent也许是Panel...
还请多多指教!!
加载更多回复(1)

110,499

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧