根据我的研究,当我在.NET中运行打开WinForm的C#可执行文件时,它们不提供从单独的c#进程访问这些WinForm对象的功能(我的意思是单独的文件),但win32 API会这样做。
然后我从API中找到了3个函数。
FindWindow();
GetWindowLong();
CallWindowProc()
我需要从上到下调用它,但后来被CallWIndowProc()
卡住了因为
我无法想象我应该为最后3个论点传递什么。
private static extern UIntPtr CallWindowProc(IntPtr a, IntPtr b, uint c, IntPtr d, IntPtr e);
c, d and e
根据文档,它应该是某种“消息”,它是int。但我在哪里可以得到这样的价值?
http://msdn.microsoft.com/en-us/library/ms633571(v=vs.85).aspx
代码:
[DllImportAttribute("User32.dll")]
private static extern IntPtr FindWindow(String ClassName, String WindowName);
[DllImportAttribute("User32.dll")]
private static extern long GetWindowLong(IntPtr a, int b);
[DllImportAttribute("User32.dll")]
private static extern UIntPtr CallWindowProc(IntPtr a, IntPtr b, uint c, IntPtr d, IntPtr e);
[STAThread]
static void Main(string[] args)
{
IntPtr lResult;
uint lMsg = 0;
IntPtr HWND = FindWindow("WindowsFormsApplication1.Form1", "Form1");
int GWL_WNDPROC = -4;
long WNDPROC = GetWindowLong(HWND, GWL_WNDPROC);
lResult = CallWindowProc(WNDPROC, HWND, lMsg, 0, 0);
}
澄清
好的..我应该说清楚..我的目标是针对正在执行的WebForm运行以下代码块。 (我是WatiN)
var t = new Thread(() =>
{
Settings.AutoStartDialogWatcher = false;
var ie = new IE(form1.webBrowser1.ActiveXInstance);
ie.GoTo("http://www.google.com");
ie.TextField(Find.ByClass("lst")).TypeText("this is awesome!!");
ie.Button(Find.ByName("btnG")).Click();
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
答案 0 :(得分:2)
您尝试发送给callWinProc的消息是什么?
参数是
nProc是SubClassWindow()(源窗口)之前返回的值。
hWnd是子类化窗口的句柄(目标窗口)。
nMsg是消息(WINDOWS.CH中定义的WM_ *值之一,基本上类似于事件或消息,如click是一条消息)。有关完整的系统消息,请参阅http://msdn.microsoft.com/en-us/library/ms644927(v=vs.85).aspx#system_defined
wParam取决于nMsg。点击,需要左键或右键点击
lParam取决于nMsg。点击它将位置作为lparam
你可以看到每条消息的wparam和lparam defination。
答案 1 :(得分:2)
看起来你正试图从不同的线程/进程调用窗口的窗口proc。我假设这是因为你正在使用FindWindow,我无法看到你创建窗口的位置。如果你正在做的事情,CallWindowProc将无法工作,因为你不能从创建窗口的线程之外的线程调用窗口proc。你需要的是SendMessage,它接受相同的最后四个参数(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) - 解释它们你需要知道你发送的是什么消息。
答案 2 :(得分:1)
我建议使用本机方法中的参数名称只是为了清晰。您可以从pinvoke.net获取这些pinvoke签名,这样您就不必一直独自完成。这些消息在头文件中定义并记录在msdn中。如果你是win32和/或C#的新用户,那么它的安静很难以正确的方式使用正确的信息。
如果要拦截表单的Windows消息,则需要一个Windows消息钩子,但这在.Net中不起作用。您还可以阅读涵盖此主题的this article。
也许您应该尝试为您的问题找到完全不同的解决方案。其他IPC方法等。
编辑:表单的CLR类型(WindowsFormsApplication1.Form1)不是你必须放在FindWindow中的类名,FindWindow是一个非托管的api,不知道CLR类型系统。试试Spy ++来调查你PC上的一些窗口。