从IntPtr句柄获取控制/Form对象

3
我尝试使用以下代码从显示的Word应用程序窗口获取托管控件:
Process[] processes = null;
processes = Process.GetProcessesByName("WINWORD");
Process wordProc = processes[0];
Control wordControl = Control.FromHandle(wordProc.MainWindowHandle);

不幸的是,wordControl始终为null... 据我所知,如果未找到与句柄相关联的控件,则FromHandle返回null。但实际上,我认为应该有一个相关的控件,因为我可以在屏幕上看到该窗口。

因此,我的问题是,当我尝试获取句柄或控件时,是否做错了什么可怕的事情。 或者,由于.NET / Windows环境中某些未知的原因,我的一般方法可能无法工作。


实际上,供您参考:MainWindorHandle 返回一个适当的句柄。 - inva
2个回答

2
您正在尝试的操作是不可能的。您无法将在其自己的进程中运行的Word实例强制转换为C# WinForms控件 - 这将是完全不安全的。
根据您想要做什么,有两种方法可供选择:
  • 如果您想影响现有Word实例的行为,则可以使用SendMessage()和其他各种User32.DLL函数向其发送一些消息。使用Pinvoke / DLL Import来完成此操作。

  • 如果您想在自己编写的应用程序中使用Word功能(例如创建Word文档),则使用Word互操作库

编辑

如果您有兴趣处理现有Word实例中的键事件,则可以使用低级键盘钩子处理键事件,并指定您感兴趣的Word处理程序的句柄。


谢谢Richard。我希望不是这种情况,但无论如何,我实际上正在尝试捕获已打开的Word文档的键按下事件(winAPI)。执行此操作的代码是Word的插件。您有什么想法可以实现这一点吗? - inva
你的意思是想在Word中处理任何按键按下事件吗? - Rich
是的,我想至少在第一次尝试时考虑每个按键按下。 - inva
我比较熟悉VB6(即COM模型),而不是C#/.Net,但IAccessible --> IDispatch --> COM对象 --> 具有覆盖事件的命名对象的方法是否可行?在处理进程外的Office互操作时,这为我提供了相当多的灵活性... - tobriand

1

Control.FromHandle要求您传递托管控件的句柄,而不是win32窗口的MainWindowHandle...


这里的“托管控件”是什么意思?我原以为 Word 应用程序形式可能是一个托管控件。但实际上,我只得到了正在运行进程的句柄 - 我想那不是托管控件的全部内容,对吧? - inva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接