tee*_*nup 11 c# pinvoke winapi dllimport findwindow
我需要以编程方式处理另一个Windows应用程序,搜索谷歌我找到了一个使用DLLImport属性处理Windows计算器的示例,并在C#中将user32.dll函数导入托管应用程序.
应用程序正在运行,我正在获取主窗口的句柄,即计算器本身,但后续代码不起作用.FindWindowEx方法不返回计算器子项的句柄,如按钮和文本框.
我尝试在DLLImport上使用SetLastError = True,发现我收到错误代码127,即"找不到过程".
这是我从中获取示例应用程序的链接:
http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=14519&av=34503
如果有人知道如何解决它,请帮忙.
更新:DLLImport是:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
Run Code Online (Sandbox Code Playgroud)
不起作用的守则是:
hwnd=FindWindow(null,"Calculator"); // This is working, I am getting handle of Calculator
// The following is not working, I am getting hwndChild=0 and err = 127
hwndChild = FindWindowEx((IntPtr)hwnd,IntPtr.Zero,"Button","1");
Int32 err = Marshal.GetLastWin32Error();
Run Code Online (Sandbox Code Playgroud)
Cod*_*ray 12
您尝试的代码依赖于各个按钮的标题来识别它们.例如,它使用以下代码来获取"1"按钮的句柄:
hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "1");
Run Code Online (Sandbox Code Playgroud)
其中窗口类名称为"Button",窗口名称为"1"(如果是按钮,则与按钮本身显示的标题文本相同).
此代码在Windows XP(和以前的版本)下运行良好,其中计算器按钮用文本标题标识."1"按钮的窗口名称为"1",因此"1"显示为按钮的标题.
但是,在Windows 7下看起来情况已经发生了变化(可能在Vista下也是如此,虽然我无法验证这一点,因为我无法访问这样的系统).使用Spy ++调查计算器窗口确认"1"按钮不再具有窗口名称"1".实际上,它根本没有窗口名称; 标题为NULL.据推测,计算器的新外观要求按钮是自定义绘制的,因此不再需要字幕来指示哪个按钮对应于哪个功能.自定义绘图例程负责绘制必要的标题.
由于找不到您指定的窗口文本的按钮NULL,因此窗口句柄返回值0().
在该文档FindWindowEx的功能表示可以指定NULL的lpszWindow参数,但是这会,当然,符合所有指定类的窗口.在这种情况下可能不是你想要的,因为计算器应用程序有一堆按钮.
我不知道一个好的解决方法.计算器并非设计为以这种方式"自动化",微软从未保证它们不会改变其内部工作方式.使用这种方法来混淆其他应用程序的窗口是一种风险.
编辑:你链接到的代码在另一个相当严重的方式也是错误的,即使在早期版本的Windows上.它将hwnd变量声明为类型int,而不是类型IntPtr.由于窗口句柄是指针,因此应始终将其存储为IntPtr类型.这也修复了FindWindowEx应该发送红色标记的函数调用中的丑陋演员.
您还需要修复声明,SendMessage以便其第一个参数是类型IntPtr.
代码应该是这样编写的:
IntPtr hwnd = IntPtr.Zero;
IntPtr hwndChild = IntPtr.Zero;
//Get a handle for the Calculator Application main window
hwnd = FindWindow(null, "Calculator");
if(hwnd == IntPtr.Zero)
{
if(MessageBox.Show("Couldn't find the calculator" +
" application. Do you want to start it?",
"TestWinAPI",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
System.Diagnostics.Process.Start("Calc");
}
}
else
{
//Get a handle for the "1" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "1");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//Get a handle for the "+" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "+");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//Get a handle for the "2" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "2");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//Get a handle for the "=" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "=");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
55976 次 |
| 最近记录: |