如何检测网页弹出的窗口并下"确定"?

随风v5 2009-04-13 07:33:24
打开网页后弹出的窗口如何检测出来,并模拟鼠标点下"确定"?找了很多资料都没有头绪,再次麻烦大家一下了,谢谢!

这个窗口如图:



相关信息:

引用
>>>> 窗口 <<<<
标题: Windows Internet Explorer
类: #32770
坐标: 353, 276
大小: 242, 121
样式: 0x94C801C5
扩展样式: 0x00010101
句柄: 0x0014090E

>>>> 控件 <<<<
类: Button
枚举: 1
类别名: Button1
ID: 1
文本: 确定
坐标: 41, 57
大小: 75, 21
控件坐标: 39, 15
样式: 0x50030000
扩展样式: 0x00000004
句柄: 0x001208F4

>>>> 鼠标 <<<<
坐标: 436, 377
光标 ID: 0
颜色: 0xF0F0EA

>>>> 状态栏 <<<<

>>>> 可见文本 <<<<
确定
取消
你没有登陆,需要登陆?


...全文
443 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
GWFZH 2012-07-28
  • 打赏
  • 举报
回复
该程序怎么用啊?在哪里用?vba吗?
随风v5 2009-04-13
  • 打赏
  • 举报
回复
using System.Runtime.InteropServices;

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);

[DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
private static extern void SetForegroundWindow(IntPtr hwnd);
private void Form1_Load(object sender, EventArgs e)
{

}

private void button1_Click(object sender, EventArgs e)
{

const uint BM_CLICK = 0xF5; //鼠标点击的消息,对于各种消息的数值,大家还是得去API手册

IntPtr hwndCalc = FindWindow(null, "Windows Internet Explorer"); //查找计算器的句柄

if (hwndCalc != IntPtr.Zero)
{
IntPtr hwndThree = FindWindowEx(hwndCalc, 0, null, "取消"); //获取按钮3 的句柄


SendMessage(hwndThree, BM_CLICK, 0, 0);

// System.Threading.Thread.Sleep(2000);
MessageBox.Show("你看到结果了吗?");
}
else
{
MessageBox.Show("没有启动 [程序]");
}
找到了,呵呵
快40的码农 2009-04-13
  • 打赏
  • 举报
回复
可以利用win32 API函数实现,不过有一点一定要注意:如果MessageBox的Caption为string.Empty,则比较麻烦,代码如下.
1.假设一个窗体中有如下代码:



public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
DialogResult result = MessageBox.Show(this, "test", string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (result == DialogResult.Yes)
{
this.DialogResult = DialogResult.Yes;
this.Hide();
}
else
{
this.DialogResult = DialogResult.No;
this.Hide();
}
}
}


2.如果我想测试这段代码,因为有消息框,必须点击按钮才可以让剩下的代码(红色标识)继续运行,否则代码覆盖率太低,怎么办?
3.解决方案:在vs 2008下测试通过


[TestClass]
public class UnitTest1
{
private const uint BM_CLICK = 0xF5;
private enum GetWindowCmd : uint
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}
public UnitTest1()
{
//
//TODO: 在此处添加构造函数逻辑
//
}

private TestContext testContextInstance;
private Form1 form1;
private System.Timers.Timer timer;
private IntPtr frmHandler;
/// <summary>
///获取或设置测试上下文,该上下文提供
///有关当前测试运行及其功能的信息。
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}

#region 附加测试属性
// 在运行每个测试之前,使用 TestInitialize 来运行代码
[TestInitialize()]
public void MyTestInitialize()
{
form1 = new Form1();
form1.Show();
form1.BringToFront();
}
//
// 在每个测试运行完之后,使用 TestCleanup 来运行代码
[TestCleanup()]
public void MyTestCleanup() { }
//
#endregion

[TestMethod]
public void TestMethod1()
{
//启动一个定时器,用于不断的捕获窗口
timer = new System.Timers.Timer();
timer.Interval = 100;
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();

BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
//利用反射机制调用私有方法,也就是按钮的Click方法
MethodInfo methodInfo = form1.GetType().GetMethod("button1_Click", flags, null, new Type[] { typeof(object), typeof(EventArgs) }, null);
//得到窗体的句柄
frmHandler = form1.Handle;
try
{
methodInfo.Invoke(form1, new object[] { null, null });
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
timer.Stop();
}
timer.Stop();
Assert.AreEqual(DialogResult.Yes, form1.DialogResult);

}

void timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
//取得消息框的句柄
IntPtr handler = GetWindow(frmHandler, (uint)GetWindowCmd.GW_ENABLEDPOPUP);//handler是MessageBox自己的句柄
if (handler != IntPtr.Zero)//不为零说明取得句柄成功
{
//取得消息框中的"是"按钮的句柄
handler = FindWindowEx(handler, 0, "Button", "是(&Y)");//按钮也作为了窗体处理,开始还真没想到可以这么用
//模拟点击按钮
SendMessage(handler, BM_CLICK, 0, 0);
}
}
catch { }

}

[DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);

[DllImport("user32.dll", EntryPoint = "GetWindow", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr GetWindow(IntPtr hwnd, uint uCmd);
}

随风v5 2009-04-13
  • 打赏
  • 举报
回复
AUTOIT我就知道可以,自动点没问题,但是想用C#做,找不到资料.
快40的码农 2009-04-13
  • 打赏
  • 举报
回复
既然是弹出窗口,应该就需要用户交互,好像不能自动点确定吧.
关注

110,533

社区成员

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

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

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