• 截图时窗口自动识别


    这两天做的截图自动识别窗口。最终要求效果:将当前鼠标所在的窗口用颜色框框起来,单击后选中该区域。
    实现步骤:
    利用EnumWindows函数遍历了桌面上的所有窗口,用这个函数遍历完得到上百个窗口,自己总共才开了三、四个窗口,竟然能遍历到这么多,只能进行筛选,将不需要的窗口进行过滤。

    //在主函数中调用该函数
    EnumWindows(EnumWindowsProc, NULL);
    
    BOOL  CaptureWindow::EnumWindowsProc(HWND hWnd, LPARAM lParam)
    {
    LONG gwl_style = GetWindowLong(hWnd, GWL_STYLE);
    	if (!(gwl_style & WS_POPUP)&&GetParent(hWnd) == NULL && IsWindowVisible(hWnd)&&IsWindowEnabled(hWnd)) 
    	{
    	    //可以对过滤后所得到的窗口进行处理
    	    //、、、
    	    //
    	    EnumChildWindows(hWnd, EnumChildWindowsProc, NULL); //获取父窗口的所有子窗口	
    	}
    	return true;
    	}
    
    BOOL CaptureWindow::EnumChildWindowsProc(HWND hWnd, LPARAM lParam)
    {
    	LONG gwl_style = GetWindowLong(hWnd, GWL_STYLE);
    	if (!(gwl_style & WS_POPUP) && GetParent(hWnd) == NULL && IsWindowVisible(hWnd) && IsWindowEnabled(hWnd))
    	{
    		WCHAR WindowTitle[100] = { 0 };
    		::GetWindowText(hWnd, WindowTitle, 100);//获取句柄对应的窗体名字
    		HWND hq = FindWindowEx(hWnd, NULL, NULL, WindowTitle);//根据窗体名字找到对应句柄,这里重复了,只是熟悉一下这个函数
    		if (hq == NULL) { return TRUE; }
    		RECT rect;
    		GetWindowRect(hq, &rect);//获取该句柄所掌控的区域
    		//这里可以做一些自己需要的操作
    		return true;
    		}
    		//这里也可以做一些操作
    		return true;
    		}
    

    EnumWindows函数会遍历桌面上所有的窗口,当回调函数EnumWindowsProc返回false时,终止遍历,返回true继续遍历剩下的。当找到你需要的窗口,可以返回false,降低函数复杂度,顺带减少点运行时间。因为我需要获取所有的窗口,最后根据鼠标位置来匹配句柄所在的区域,所以返回我都是用的true。
    获取到桌面上我们看的见的窗口句柄及其对应的区域后,获取鼠标当前位置,遍历句柄,确定当前鼠标在哪个句柄掌控的区域中,利用GetCursorPos(p),此处的p为POINT类型。然后调用下述函数:

    HCR CaptureWindow::getRect(const POINT  pt)
    {
    	HCR rect = 0;
    	vector<Handle_Correspondence_Region>::iterator it = Handle_Correspondence_Region_vector.begin();
    	for (it; it != Handle_Correspondence_Region_vector.end(); it++)
    	{
    		if (it->left <= pt.x&&it->right >= pt.x&&it->top <= pt.y&&it->bottom >= pt.y)
    		{
    			return *it;
    		}
    	}
    
    	return rect;
    
    }
    

    HCR是自己定义的一个结构体:

    typedef struct Handle_Correspondence_Region
    {
    	Handle_Correspondence_Region(int p = 0) { hwd = NULL; };
    	HWND hwd;
    	long int left;
    	long int right;
    	long int top;
    	long int bottom;
    	long int wide;
    	long int high;
    	bool operator <(const Handle_Correspondence_Region &m)const {
    		return (wide*high) < (m.wide*m.high);
    	}
    	bool operator == (const Handle_Correspondence_Region &eq) const {
    		return ((left == eq.left) && (right == eq.right) && (top == eq.top) && (bottom == eq.bottom));
    	}
    }HCR;
    

    到这就已经能根据鼠标位置返回所在区域了,接下来开始绘制就可以啦~
    这里自己搞了个坑,本身通过枚举桌面上所有的窗口时,就是按Z-order的顺序,按序存储好了,刚开始不知道,还对枚举的窗口进行了排序和筛选,想着肯定是窗口小的在上面,遍历的时候从小到大,结果造成窗口被覆盖,鼠标放在被覆盖的窗口位置时,还能显示。(刚开始想着遍历筛选主要是发现枚举出来的窗口数量比较大,而且存在着重复)。
    解决方法:枚举出来的窗口不要进行排序,它本省就是按Z-order的顺序遍历出来的。

    这里再贴一个Z-order讲解的博客
    https://blog.csdn.net/henter/article/details/51314475

  • 相关阅读:
    C# 字段 属性 方法 三霸主齐上阵
    C# 项目之总结,浓缩才是精华
    C# 语法 重中之重
    岁月流逝,C#成为我们IT精英永恒不变的经典
    pv:快餐厅4类职员正确并发运行的程序——用pv实现有向图的前驱关系哦!
    pv错题:用pv操作实现旅客,汽车之间的同步关系——北航2018考研计算机!!!!!!!!我还很不熟练,奋斗吧少年!!!!!!
    windows 的 DMA
    pv打卡:生产者消费者问题扩展——>南航2002pv习题哦
    冷门的OS知识:中断——这个我多大熟练qwq!
    Unix混合索引结构_文件系统_文件的组织_文件的物理结构_多级索引文件——>相关的小计算题!!!!!!重点重点重点!!!!!!
  • 原文地址:https://www.cnblogs.com/ymd12103410/p/11240772.html
Copyright © 2020-2023  润新知