模拟对另一进程的窗口按钮的点击

 

1、

在自动化测试中经常要模拟窗口按钮的点击。

参考文章:http://blog.csdn.net/blackboyofsnp/article/details/3372719

有时我们需要这么做, 手动模拟按钮按下的事件, 让程序做出与按钮真的按下时一样的响应.

   设按钮ID为ID_BTN_OK, 当前Dialog窗口.
   实际上系统并不能区分按钮是真的按下了(如用鼠标点击), 还是一个我们自己用代码模拟出的一种"假象".
它所需要知道的只是哪个窗口(按钮也是一种窗口)发生了哪一种事件, 然后在消息循环中处理它. 系统怎么才
能知道这些呢? 当然靠的是消息(message), 我们 只需按照Windows或者MFC的标准格式把相应的信息传给系统,
系统就会"上当"了.
   向系统传递消息可以用SendMessage或PostMessage(可能还有其他很多函数哦), 但SendMessage执行后系统
会一直等待, 直到要发送的消息被处理掉. 而PostMessage可不管那么多, 发送消息后立即返回程序流程. 当
按钮按下的响应函数中有很大一个循环时, 用SendMessage会出现许多问题, 尤其是要在程序初始化阶段模拟时,
会导致窗体无法完成初始化. 所以我们用PostMessage(). 它的原型为:
BOOL PostMessage(          HWND hWnd,
    UINT Msg,
    WPARAM wParam,
     LPARAM lParam
);


这样写;  

PostMessage(WM_COMMAND, MAKEWPARAM(ID_BTN_OK, BN_CLICKED), NULL);

这里, WM_COMMAND是要发送的消息, MAKEWPARAM宏是为了组成一个WPARAM,WM_COMMAND消息的WPARAM的低字为控件ID,高字为识别码, 最后一个参数LPARAM可为NULL.相关定义可查看MSDN.

  这样我们就把必需的信息格式化好发送给系统了. 当系统在消息循环中收到该消息时, 就知道哦, 你要引发控件ID_BTN_OK
的事件BN_CLICKED, 好的我帮你处理. 于是我们就惊喜地看到按钮看起来真的按下去了, 并执行了和真正按下去时一样的代码.

 

看评论说不管用,我又试验了一下。新建一个对话框工程,在对话框上添加一个按钮,ID为IDC_BTN_TEST,单击它,为它添加ON_BN_CLICKED消息响应函数:

void CtestDlg::OnBnClickedBtnTest()
{
    AfxMessageBox(_T("OK"));
}

然后在对话框的OnInitDialog()函数的return TRUE前加上:

PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BTN_TEST, BN_CLICKED), NULL);

好了,再运行程序,会弹出个消息框 “OK”,说明模拟正确。

 

 2 C#调用迅雷的时候 自动模拟点击”下载按钮” 关闭弹出窗口

网上 关于 “不弹出《建立任务》的对话框的方法 在迅雷5.9貌似不适用了” 那么我改了一下网上的“监听方式”来进行模拟点击

#region Dll Import 需要导入的api 声明。
 
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName,
      string lpWindowName);
 
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent,
      IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
 
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd,
      int Msg, IntPtr wParam, string lParam);
        const int WM_GETTEXT = 0x000D;
        const int WM_SETTEXT = 0x000C;
        const int WM_CLICK = 0x00F5;
        #endregion
        //关消息的方法
        private void ClosePopWindow(object obj)
        {
            //这些用spy++可以看到
            string lpszParentClass = "#32770"; //整个窗口的类名
            string lpszParentWindow = "建立新的下载任务"; //窗口标题
            string lpszClass_Submit = "Button"; //需要查找的Button的类名
            string lpszName_Submit = "立即下载"; //需要查找的Button的标题          
 
            IntPtr ParenthWnd = new IntPtr(0);
            IntPtr EdithWnd = new IntPtr(0);
            int i = 0;
            while (true)
            {
                //查到窗体,得到整个窗体
                ParenthWnd = FindWindow(lpszParentClass, lpszParentWindow);
                //判断这个窗体是否有效
                if (!ParenthWnd.Equals(IntPtr.Zero))
                {
 
                    //得到第一级子窗口
                    EdithWnd = FindWindowEx(ParenthWnd,
                        new IntPtr(0), "#32770", "");
                    //Console.WriteLine("第一级-"+EdithWnd.ToString());
                    //得到Button这个子窗体,并触发它的Click事件
                    EdithWnd = FindWindowEx(EdithWnd,
                        new IntPtr(0), lpszClass_Submit, lpszName_Submit);
                    //Console.WriteLine("第二级-" + EdithWnd.ToString());
                    if (!EdithWnd.Equals(IntPtr.Zero))
                    {
                        SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
                    }
                    return;
                }
                Thread.Sleep(1000);
                i++;
                //  Console.WriteLine("第"+i.ToString()+"次检查"); 5秒都没显示出来就推出循环
                if (i > 15)
                {
                    //break;
                }
            }
        } 
 
//需要导入如下类库
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32;
 
//在迅雷提交前添加一个方法
ThreadPool.QueueUserWorkItem(new WaitCallback(ClosePopWindow));


 3、

#include <iostream>
#include <fstream>
#include <math.h>
#include <cctype>
#include <string>
#include <windows.h>

using namespace std;

int main()
{
    //cout << "Hello world!" << endl;
    HWND hwnd = FindWindow( 0, "文件窗口"  );


    //HWND hWnd2 =  GetDlgItem( hwnd, 1001);

    char* strs = new char[ 255 ];
    HWND hWnd2 = ::FindWindowEx(hwnd,NULL,"Button",NULL);

    while ( hWnd2 )
    {
        GetWindowText( hWnd2, strs, 255 );


        cout << strs << endl;



       /* if ( strcasecmp( strs, "确定" ) == 0 ) {
            break;
        }*/

        hWnd2 = FindWindowEx( hwnd, hWnd2, "Button", NULL );
    }




    UINT nCtrlID = ::GetDlgCtrlID(hWnd2);
    ::PostMessage(hWnd2, WM_COMMAND, (WPARAM)(BN_CLICKED << 16 | nCtrlID), (LPARAM)hWnd2);
    ::PostMessage(hWnd2,WM_MOUSEMOVE, MK_LBUTTON, MAKELONG(0,0) );
    ::PostMessage(hWnd2,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(0,0));
    ::PostMessage(hWnd2,WM_LBUTTONUP,MK_LBUTTON,MAKELPARAM(0,0));

    return 0;
}


 

4、往编辑框中写入文件(可实现)

SetWindowText

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现了如下四种调度算法的模拟: (1)时间片轮转调度 (2)优先数调度 (3)最短进程优先 (4)最短剩余时间优先 模拟过程使用了JProgressBar作为进程状态条,更为直观地观察到每个进程的执行状态。 程序用户说明: 1、在上图标号1处输入要创建随机进程的个数,仅可输入正数,非正数会有相关提示。然后点击标号2处的“创建进程按钮,随进创建的进程显示在程序界面的中央窗口,如标号3所示。 2、创建好随机进程后,在标号4的单选框选择将要模拟执行的调度算法,然后点击标号5处的“开始模拟”,程序开始执行。标号3的列表会显示相应的调度变化。 3、模拟过程中,可以继续添加新的进程,操作同上。 4、 一个算法模拟执行完毕之后,可以点击标号6的“复位”按钮,可以重置列表的内容为程序模拟运行前的内容。复位成功后,可以继续选择其他调度算法进行模拟。 5、标号7显示为程序模拟过程中的时间,从1秒开始累计。 6、点击标号8的“清空”按钮,可以清空类别的进程,以便程序的下次执行。 题目要求: 题目四 单处理器系统的进程调度 一 、 课 程 设 计 目 的 1. 加深对进程概念的理解, 明确进程程序的区别。 2. 深入了解系统如何组织进程、 创建进程。 3. 进一步 认识如何实现处理器调度。 二 、 课 程 设 计 内 容 编写程序完成单处理器系统中的进程调度, 要求实现时间片轮转、 优先数、 最短进程优 先和最短剩余时间优先四种调度算法。 实验具体包括: 首先确定进程控制块的内容, 进程控 制块的组成方式; 然后完成进程创建原语和进程调度原语; 最后编写主函数对所作工作进行 测试。 模拟程序只对你所设置的“ 虚拟 PCB” 进行相应的调度模拟操作, 即每发生“ 调度” 时, 显示出当前运行进程的“ 进程标识符”、“ 优先数”、“ 剩余运行时间” 等, 而不需要对系 统中真正的 PCB 等数据进行修改。
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
要在C++程序中启动一个.exe程序并对其进行操作,包括点击窗口中的按钮,你可以使用Windows API和消息循环来实现。 以下是一个示例代码,演示如何使用C++启动一个.exe程序模拟点击窗口中的按钮: ```cpp #include <windows.h> int main() { // 启动目标.exe程序 STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); if (!CreateProcess(NULL, "path_to_exe_file.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { printf("启动进程失败!\n"); return 1; } // 等待进程启动完成 WaitForInputIdle(pi.hProcess, INFINITE); // 查找目标窗口 HWND targetWindow = FindWindow(NULL, "窗口标题"); if (targetWindow == NULL) { printf("找不到目标窗口!\n"); return 1; } // 模拟点击按钮(假设按钮的ID是IDC_BUTTON) HWND button = GetDlgItem(targetWindow, IDC_BUTTON); PostMessage(button, BM_CLICK, 0, 0); // 关闭进程和线程的句柄 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; } ``` 在上述代码中,将`path_to_exe_file.exe`替换为你要启动的`.exe`文件的路径。然后使用`FindWindow`函数来查找目标窗口,将"窗口标题"替换为实际窗口的标题。使用`GetDlgItem`函数来获取按钮的句柄,将`IDC_BUTTON`替换为实际按钮的ID。最后,使用`PostMessage`函数发送`BM_CLICK`消息模拟点击按钮。 请确保目标程序窗口标题和按钮ID是正确的,并且了解目标程序窗口结构和消息处理方式,以便正确模拟操作。具体的操作可能因目标程序的不同而有所差异,你可能需要根据实际情况进行调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值