如何获取第三方软件的窗口和控件的句柄?

anabiosispe 2018-04-07 09:32:39
我已经知道的内容:
可以用以下几个windows api函数
1.IntPtr FindWindow(string lpClassName, string lpWindowName);//通过指定类名或者窗口标题,获得窗口的句柄
2.IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);//在父窗口里制定窗口名或者子窗口标题名获得子窗口的句柄
3.IntPtr GetDlgItem(IntPtr hParent, int nIDParentItem);//用父窗口句柄和控件id获取子窗口或者控件的句柄

这是我用spy++看到的主体内容的截图,就是这个DFTB的软件。



我遇到的问题,求解
1.父窗口里的一个按钮,跟一个子窗口的控件id是相同的。这样GetDlgItem函数的方法就不可行了。这个情况如何处理?
如下图所示,一个是一个子窗口Dialog的控件id,跟一个按钮M的控件id相同。



2.我尝试用IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);来获得那个Dialog子窗口的句柄,但是获得的值为空,我调用代码为:
windowHwnd是DFTB主窗口的句柄
IntPtr panelHwnd = FindWindowEx(windowHwnd, IntPtr.Zero, "#32770 (Dialog)", null);
请问这句函数是哪儿出错了呢?

...全文
3466 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_31261843 2019-04-06
  • 打赏
  • 举报
回复
可否帮我看看问题出在哪里了,知道问题的所在可否加我QQ:811102598,谢谢了
qq_31261843 2019-04-06
  • 打赏
  • 举报
回复
//一个程序获取另一个程序Edit控件的内容 //根据指定程序的标题名获取改程序窗口的句柄 HWND hWnd=::FindWindow(NULL,"zhang001"); if(hWnd) { MessageBox("get windows"); //根据窗口句柄获取EDIT控件的ID,但是这个ID是通过VS工具spy++获取的 HWND h = ::GetDlgItem(hWnd,0x3E9); if (h!=NULL) { CString str0; //要知道SendMessage用法,特别是第三个参数 //根据EDIT控件的ID获取控件内容,存放到str0中 ::SendMessage(h,WM_GETTEXT,20,(LPARAM)(LPCTSTR)str0); //将获得的内容放到本程序指定的EDIT控件中进行显示 GetDlgItem(IDC_EDIT1)->SetWindowText(str0); MessageBox(str0); } } else { MessageBox("fail!"); } 我按照这样去获取第三方软件一控件的内容,怎么读取不到呢??
toma2008 2018-05-19
  • 打赏
  • 举报
回复
有几种方法的,分享下以前抓第三方窗口控件的方法, 窗口里面可能还有窗口,一直循环下去就是了

	int hwnd_i=0;
	CString strtemp;
	char path[200];
	HWND hwnd;//=::FindWindow(NULL,"窗口标题");
	if(::FindWindow(NULL,"窗口标题")!=NULL)
	{
		hwnd=::FindWindow(NULL,"窗口标题");
	}
	else if(::FindWindow(NULL,"窗口标题")!=NULL)
	{
		hwnd=::FindWindow(NULL,"窗口标题");
	}
	HWND hwndEdit[100];
	hwndEdit[0]=NULL;
	while (hwndEdit[hwnd_i+1]=FindWindowEx(hwnd,hwndEdit[hwnd_i], NULL, NULL))
	{
			strtemp=path;
			::SendMessage(hwndEdit[hwnd_i+1],WM_GETTEXT,(sizeof(path))/sizeof(char),(LPARAM)(path));
			strtemp=path;
			if(strtemp=="xtpBarTop")
			{
				break;
			}
		hwnd_i++;
	}
	
	//
	int listnumber=0;
	HWND hwndSecond[100];
	hwndSecond[0]=NULL;
	while(hwndSecond[listnumber+1]=FindWindowEx(hwndEdit[hwnd_i+1],hwndSecond[listnumber], NULL, NULL))
	{
		GetClassName(hwndSecond[listnumber+1],path,200);
		::SendMessage(hwndSecond[listnumber+1],WM_GETTEXT,(sizeof(path))/sizeof(char),(LPARAM)(path));
		strtemp=path;//工程控件内容
		if(strtemp=="工程工具栏")
		{
			break;
		}
		listnumber++;
	}
	
	//
	HWND HWNDthird[100];
	int k=0;
	HWNDthird[k]=NULL;
	while(HWNDthird[k+1]=FindWindowEx(hwndSecond[listnumber+1],HWNDthird[k], "combobox", NULL))
	{
		GetClassName(HWNDthird[k+1],path,200);
		::SendMessage(HWNDthird[k+1],WM_GETTEXT,(sizeof(path))/sizeof(char),(LPARAM)(path));
		strpath[k]=path;
//		MessageBox(strpath[k]);
		k++;
	}
赵4老师 2018-04-15
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
仅供参考:
HWND MyFindListViewWindow()
{
    const int MyMaxParentWinCount = 2;
    // 父窗口类名数组
    char *A_szClassName[MyMaxParentWinCount] = {
        //"PTA_HaFas_Frame4194304",
        "#32770",
        "PTA_HaFas_A_OList"
    };
    // 父窗口标题数组
    char *A_szWinName[MyMaxParentWinCount] = {
        //"HAFAS",
        "Arrival/Departure table",
        "HCONLIST.BMP"
    };
    // 首先求得顶级父窗口
    HWND hMainWin = FindWindow(A_szClassName[0], A_szWinName[0]);
    if (NULL==hMainWin) {
        return NULL;
    }
    // 逐次用FindWindowEx函数求出各级子窗口
    HWND hNextChildWin=NULL;

    HWND hLastWin=NULL;
    for (int i=1; i<MyMaxParentWinCount; i++) {
        if (1==i) {
            hLastWin = hMainWin = FindWindowEx(hMainWin,NULL         ,A_szClassName[i],A_szWinName[i]);
        } else if (2==i) {
            hNextChildWin = FindWindowEx(hMainWin,hNextChildWin,A_szClassName[i],A_szWinName[i]);
            hLastWin=hNextChildWin;
        } else {
            hLastWin = FindWindowEx(hLastWin,NULL         ,A_szClassName[i],A_szWinName[i]);
        }
    }
    return hLastWin;
}
正解! 千句讨论和解释,比不上一行例子代码。
schlafenhamster 2018-04-15
  • 打赏
  • 举报
回复
GetDlgItem 先有 对话框 , 找 对话框 里 的 子窗口, 与 对话框 ID 无关!
anabiosispe 2018-04-15
  • 打赏
  • 举报
回复
引用 15 楼 schlafenhamster 的回复:
都是0x68呀 ,即 104
这样用GetDlgItem这个函数就没法正确获取到控件句柄了,只能用枚举子控件了
schlafenhamster 2018-04-15
  • 打赏
  • 举报
回复
都是0x68呀 ,即 104
schlafenhamster 2018-04-15
  • 打赏
  • 举报
回复
如 void CTestDlg::OnFind() { float sNum; // TODO: Add your control notification handler code here pWndDlg=FindWindow("#32770","原始数据输入对话框"); if(pWndDlg==0) { AfxMessageBox("原始数据输入对话框"); return; } pWndEdit1000=pWndDlg->GetDlgItem(0x03E8);// 流量控件的 ID 0x003E8
anabiosispe 2018-04-14
  • 打赏
  • 举报
回复
引用 13 楼 schlafenhamster 的回复:
“你看我spy截图,确实控件id一样” 哪个 ? 对话框 68 (104)? 与按钮 ‘M’ ? 对话框 ID 通常 在 100 左右 按钮 ID 在 1000 以上。 因为 ‘M'’ 在 对话框 104 内 ,所以 响应 OnButtonM 没问题的 , 不过自己 修改 按钮 ID 时 应该 大于 1000,
我看按钮M和对话框的Control Id都是0x68呀
schlafenhamster 2018-04-14
  • 打赏
  • 举报
回复
“你看我spy截图,确实控件id一样” 哪个 ? 对话框 68 (104)? 与按钮 ‘M’ ? 对话框 ID 通常 在 100 左右 按钮 ID 在 1000 以上。 因为 ‘M'’ 在 对话框 104 内 ,所以 响应 OnButtonM 没问题的 , 不过自己 修改 按钮 ID 时 应该 大于 1000,
anabiosispe 2018-04-14
  • 打赏
  • 举报
回复
引用 4 楼 zgl7903 的回复:
试试 FindWindowExW(windowHwnd, NULL, L"#32770 (Dialog)", NULL);
不是这样的,是那个类型名错了,是#32770,不是#32770 (Dialog)。spy显示问题
zgl7903 2018-04-12
  • 打赏
  • 举报
回复
控件ID一样 但是控件类不一样 GetClassName 再区分
anabiosispe 2018-04-12
  • 打赏
  • 举报
回复
引用 7 楼 zwfgdlc 的回复:
控件ID都一样,消息循环那怎么搞
不知道啊,但是你看我spy截图,确实控件id一样啊
anabiosispe 2018-04-12
  • 打赏
  • 举报
回复
引用 8 楼 schlafenhamster 的回复:
spy里会显示后面的(Dialog),spy 自己加上的 //#32768 The class for a menu. //#32769 The class for the desktop window. //#32770 The class for a dialog box. //#32771 The class for the task switch window. //#32772 The class for icon titles.
嗯,你说的对的,我枚举控件,打印出类型名后,发现这个问题了
赵4老师 2018-04-10
  • 打赏
  • 举报
回复
提醒:Spy++有类似源代码。 MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix, MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 先下载安装MSDN98,再参考MSDN98\SAMPLES\VC98\SDK\SDKTOOLS\SPY\*.*
schlafenhamster 2018-04-10
  • 打赏
  • 举报
回复
spy里会显示后面的(Dialog),spy 自己加上的 //#32768 The class for a menu. //#32769 The class for the desktop window. //#32770 The class for a dialog box. //#32771 The class for the task switch window. //#32772 The class for icon titles.
zwfgdlc 2018-04-10
  • 打赏
  • 举报
回复
控件ID都一样,消息循环那怎么搞
汪宁宇 2018-04-09
  • 打赏
  • 举报
回复
引用 楼主 txfast 的回复:
我已经知道的内容: 可以用以下几个windows api函数 1.IntPtr FindWindow(string lpClassName, string lpWindowName);//通过指定类名或者窗口标题,获得窗口的句柄 2.IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);//在父窗口里制定窗口名或者子窗口标题名获得子窗口的句柄 3.IntPtr GetDlgItem(IntPtr hParent, int nIDParentItem);//用父窗口句柄和控件id获取子窗口或者控件的句柄 这是我用spy++看到的主体内容的截图,就是这个DFTB的软件。 我遇到的问题,求解 1.父窗口里的一个按钮,跟一个子窗口的控件id是相同的。这样GetDlgItem函数的方法就不可行了。这个情况如何处理? 如下图所示,一个是一个子窗口Dialog的控件id,跟一个按钮M的控件id相同。 2.我尝试用IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);来获得那个Dialog子窗口的句柄,但是获得的值为空,我调用代码为: windowHwnd是DFTB主窗口的句柄 IntPtr panelHwnd = FindWindowEx(windowHwnd, IntPtr.Zero, "#32770 (Dialog)", null); 请问这句函数是哪儿出错了呢?
先用hParent = FindWindow()获取主窗口的句柄,再FindWindowEx(hParent, ... 查找子窗口
anabiosispe 2018-04-09
  • 打赏
  • 举报
回复
引用 1 楼 caozhy 的回复:
用enumchildwindows遍历,找到符合条件的(比如根据窗口类、位置、标题) 或者用findchildwindow,传入窗口标题(比如“m“)找到按钮。而子对话框没有标题。
谢谢,FindWindowEx找不到那个#32770 (Dialog)子窗口的问题我找到了,类型名是只有#32770,没有后面的(Dialog)。虽然我不知道为啥spy里会显示后面的(Dialog)
zgl7903 2018-04-09
  • 打赏
  • 举报
回复
试试 FindWindowExW(windowHwnd, NULL, L"#32770 (Dialog)", NULL);
加载更多回复(2)
我将带领大家来系统学习Windows的窗口编程,包括消息、窗口、GDI绘图、游戏开发等。本课程比较基础,非常适合初学者入门,读者可以边学习边实践。具体的章节目录和课程内容如下所示:---------------------------------------------Windows游戏编程系列之1:GUI界面编程及游戏入门实战1、Windows创建第一个窗口 WinMain入口函数 5进行Windows编程的调试手法 6窗口从哪里来? 7窗口编程的步骤 7窗口编程需要的主要结构 8窗口编程需要的主要API 92、Windows的窗口过程与消息机制 如何留住窗口? 121)Windows的消息与消息循环 142)消息处理函数与常用消息 17)Windows的窗口过程函数 19 3、GDI编程之设备上下文 1)GDI的通用编程框架 222)GDI的绘图步骤 253)GDI获取设备句柄 254、GDI编程之绘制几何图形 画点、线 28颜色COLORREF 29矩形 29画圆、饼图、弦图 305、GDI编程之自定义画笔画刷画笔简介 32画刷简介 33画笔案例 33画刷案例 346、GDI编程之绘制文字 DrawText函数 35TextOut 函数 (wingdi.h) 36CreateFont函数 37绘制文本案例 377、GDI编程之绘制位图 位图简介 381)在资源中添加位图资源 392)从资源中加载位图: LoadBitmap 393)创建一个与当前DC相匹配的DC(内存DC) 394)将bitmap放入匹配的DC中:SelectObject 405)成像(1:1 比例 ) 406)取出位图 407)释放位图 418)释放匹配的DC 41绘制位图案例 41   8、Windows鼠标键盘消息 一、键盘消息 421、键盘消息 422、消息参数: 423、消息的使用: 424、键盘消息的案例代码 43二、鼠标消息 441、基本鼠标消息 442、双击消息 443、滚轮消息 454、不响应双击消息 45 9、Windows定时器消息 定时器消息介绍 47创建定时器 47关闭定时器 47定时器消息案例代码 4810、GDI游戏之跳舞动画 11、GDI游戏之走路动画 12、GDI贪吃蛇游戏实战  

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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