.NET 中 ActiveX 控件的子类化窗口过程
Posted
技术标签:
【中文标题】.NET 中 ActiveX 控件的子类化窗口过程【英文标题】:Subclassing window procedure of an ActiveX control in .NET 【发布时间】:2011-05-05 15:18:18 【问题描述】:我在我的应用程序中使用了 Flash ActiveX 控件。我想禁用它的右键菜单。由于控件没有为此提供 API,我想子类化窗口过程并拦截 WM_RBUTTONDOWN 消息。我在 Qt 下成功地做到了这一点,但我不知道如何在 C# 中做到这一点。
在我的 C++/Qt 实现中,我使用 SetWindowLong
来存储 activex 包装器的 this
指针,而该指针又具有存储原始窗口 proc 的字段。我将窗口过程设置为我的(再次使用SetWindowLong
)以及我不想处理的任何消息,我使用CallWindowProc 将其传递给原始WNDPROC。
如何在 .NET 下做到这一点?
【问题讨论】:
【参考方案1】:您可以在 C# 中以完全相同的方式执行此操作。您需要使用 P/Invoke 从托管代码调用非托管 Windows API。网上有很多文章介绍了如何使用 P/Invoke。
事实上,您可以使用NativeWindow
类以更简单的方式完成此操作,如here 所述。代码如下所示:
public class SubclassHWND : NativeWindow
protected override void WndProc(ref Message m)
// Perform whatever custom processing you must have for this message
System.Diagnostics.Debug.WriteLine(m.ToString());
// forward message to base WndProc
base.WndProc(ref m);
SubclassHWND s = new SubclassHWND();
s.AssignHandle(theWindowHandle);
//Now s should be listening to the messages of the form.
另一种使用委托代替函数指针的方法是:Marshal.GetFunctionPointerForDelegate()
【讨论】:
我真的可以将 C# 方法传递给 SetWindowLong 吗? 是的,您可以这样做,而且这样做是例行公事。 我自己进行了一次网络搜索,发现实际上可以在没有 P/Invoke 的情况下以更简单的方式实现 - 请参阅编辑。 感谢您的回答。与此同时,我想出了如何实际将 C# 方法作为函数指针传递给 winapi,我将它添加到您对未来谷歌用户的回答中(如果您不介意:))。【参考方案2】:虽然这是一个旧的,但我只是从这个链接中看到了这段代码,它非常有用。本质上,它是 ActiveX 控件本身的子类,并在此时禁用右键单击。
通过:http://www.codeproject.com/Articles/29102/How-To-Disable-FlashPlayer-AxShockwaveFlash-Right
public class IForcePlayer : AxShockwaveFlash
const int WM_RBUTTONDOWN = 0x0204;
protected override void WndProc(ref Message m)
if (m.Msg == WM_RBUTTONDOWN)
m.Result = IntPtr.Zero;
return;
base.WndProc(ref m);
【讨论】:
以上是关于.NET 中 ActiveX 控件的子类化窗口过程的主要内容,如果未能解决你的问题,请参考以下文章