• C/C++ 遍历窗口标题类名


    遍历每个进程,一次查找进程下的窗口,找到窗口标题为 “” ,窗口类名为 “RunDll” 的窗口。如果找到返回 true ,没找到返回 false。

    #pragma region 依赖
    
    typedef struct EnumHWndsArg{
    	std::vector<HWND> *vecHWnds;
    	DWORD dwProcessId;
    }EnumHWndsArg, *LPEnumHWndsArg;
    
    // 判断窗口是否属于目标进程
    BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam){
    	EnumHWndsArg *pArg = (LPEnumHWndsArg)lParam;
    	DWORD  processId;
    
    	// 检索窗口线程标识符
    	GetWindowThreadProcessId(
    		hwnd,			// 窗口句柄
    		&processId		// 接收 PID 的指针
    		);
    
    	// 如果这个 HWND 属于这个 PID ,则加入到 vecHWnds 数组末尾
    	if (processId == pArg->dwProcessId){pArg->vecHWnds->push_back(hwnd);}
    
    	return TRUE;
    }
    
    // 根据 PID 获取 HWND
    void GetHWndsByProcessID(DWORD processID, std::vector<HWND> &vecHWnds){
    	EnumHWndsArg wi;
    	wi.dwProcessId = processID;
    	wi.vecHWnds = &vecHWnds;
    
    	// 枚举所有顶级窗口
    	EnumWindows(
    		lpEnumFunc,		// 回调函数指针
    		(LPARAM)&wi		// 传递给回调函数的值
    		);
    }
    
    #pragma endregion
    
    bool CSOL_dh()
    {
    	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    	PROCESSENTRY32 process = {sizeof(PROCESSENTRY32)};
    	
    	// 遍历进程
    	while (Process32Next(hProcessSnap,&process)){
    		string processName = process.szExeFile;		// 进程名
    		std::vector<HWND> vecHWnds;					// 进程下的窗体句柄数组
    		GetHWndsByProcessID(process.th32ProcessID,vecHWnds);
    		
    		// 获取 HWND 窗口标题、窗口类名
    		TCHAR szBuf_title[MAX_PATH];
    		TCHAR szBuf_class[MAX_PATH];
    		for (const HWND &h : vecHWnds){
    			GetWindowText(
    			h,					// 窗口句柄
    			szBuf_title,		// 接收窗口标题的缓冲区指针
    			MAX_PATH			// 缓冲区字节大小
    			);
    			GetClassName(
    			h,					// 窗口句柄
    			szBuf_class,		// 接收窗口类名的缓冲区指针
    			MAX_PATH			// 缓冲区字节大小
    			);
    
    			// 判断是否有符合要求的窗体
    			if(strcmp(szBuf_title,"") == 0 && strcmp(szBuf_class,"RunDLL") == 0){
    				return true;
    			}
    			
    			// 输出结果	
    			//cout << "szBuf_title = " << szBuf_title << endl;
    			//cout << "szBuf_class = " << szBuf_class << endl;
    			//cout << "--------------------------------------------" << endl;
    		}
    
    	}
    	
    	return false;
    }
    

    API——获取鼠标位置的窗口句柄

    #include <Windows.h>
    
    #define MAX_TEXT_LEN 255
    
    BOOL CALLBACK EnumChildProcess(HWND hwnd, LPARAM lParam)
    {
        if (hwnd == NULL) {
            return FALSE;
        }
        BOOL ret;
        RECT rect;
        ret = GetWindowRect(hwnd, &rect);
        if (!ret) {
            printf("GetWindowRect hwnd=%p -> fail(%ld)
    ", hwnd, GetLastError());
        }
        else {
            //printf("GetWindowRect hwnd = %p -> rect=(left=%ld, top=%ld, right=%ld, bottom=%ld)
    ", hwnd, rect.left, rect.top, rect.right, rect.bottom);
            ret = PtInRect(&rect, *(POINT *)lParam);
            if (ret) {
                printf("GetWindowRect hwnd = %p -> rect=(left=%ld, top=%ld, right=%ld, bottom=%ld)
    ", hwnd, rect.left, rect.top, rect.right, rect.bottom);
                //printf("PtInRect
    ");
    
                /*
                WINUSERAPI int WINAPI GetWindowText(
                _In_ HWND hWnd,
                _Out_writes_(nMaxCount) LPTSTR lpString,    //可能是标题名或者file:///打头的文件完整路径
                _In_ int nMaxCount
                );
                如果函数成功,返回值是拷贝的字符串的字符个数,不包括中断的空字符;如果窗口无标题栏或文本,或标题栏为空,或窗口或控制的句柄无效,则返回值为零。若想获得更多错误信息,请调用GetLastError函数。
                */
                TCHAR windowText[MAX_TEXT_LEN];
                int lenRet = GetWindowText(hwnd, windowText, MAX_TEXT_LEN);
                if (lenRet == 0 && GetLastError() != 0) {
                    //GetLastError()〖0〗-操作成功完成
                    printf("GetWindowText hwnd=%p -> fail(%ld)
    ", hwnd, GetLastError());
                }
                else {
                    _tprintf(_T("GetWindowText hwnd=%p -> windowText=%s, lenRet=%d
    "), hwnd, windowText, lenRet);
                }
    
                /*
                WINUSERAPI int WINAPI GetClassNameW(
                    _In_ HWND hWnd,
                    _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName,
                    _In_ int nMaxCount
                );
    
                如果函数成功,返回值为拷贝到指定缓冲区的字符个数:如果函数失败,返回值为0。若想获得更多错误信息,请调用GetLastError函数。
                */
                TCHAR className[MAX_TEXT_LEN];
                lenRet = GetClassName(hwnd, className, MAX_TEXT_LEN);
                if (lenRet == 0) {
                    printf("GetClassName hwnd=%p -> fail(%ld)
    ", hwnd, GetLastError());
                }
                else {
                    _tprintf(_T("GetClassName hwnd=%p -> className=%s, lenRet=%d
    "), hwnd, className, lenRet);
                }
    
                /*
                找出某个窗口的创建者(线程或进程),返回创建者的标志符
                哪个线程创建了这个窗口,返回的就是这个线程的id号 (进程只有一个线程的话,那么线程标志符与进程标志符就是指同一个标志符)
                WINUSERAPI DWORD WINAPI GetWindowThreadProcessId(
                    _In_ HWND hWnd,
                    _Out_opt_ LPDWORD lpdwProcessId //进程号的存放地址(变量地址)
                );
                返回线程号
                */
                DWORD dwProcessId;
                DWORD dwThreadId = GetWindowThreadProcessId(hwnd, &dwProcessId);
                printf("GetWindowThreadProcessId hwnd=%p -> processId=%ld, threadId=%ld
    ", hwnd, dwProcessId, dwThreadId);
    
                /*
                WINUSERAPI UINT WINAPI GetWindowModuleFileName(
                    _In_ HWND hwnd,
                    _Out_writes_to_(cchFileNameMax, return) LPTSTR pszFileName, //模块完整路径
                    _In_ UINT cchFileNameMax
                );
                返回值是复制到缓冲区的字符总数。
                */
                TCHAR fileName[MAX_PATH];
                lenRet = GetWindowModuleFileName(hwnd, fileName, MAX_PATH);
                if (lenRet == 0) {
                    //错误码〖126〗-找不到指定的模块。
                    printf("GetWindowModuleFileName hwnd=%p -> fail(%ld)
    ", hwnd, GetLastError());
                } else {
                    _tprintf(_T("GetWindowModuleFileName hwnd=%p -> fileName=%s
    "), hwnd, fileName);
                }
    
                /*
                WINUSERAPI BOOL WINAPI GetWindowInfo(
                    _In_ HWND hwnd,
                    _Inout_ PWINDOWINFO pwi
                );
    
                typedef struct tagWINDOWINFO
                {
                    DWORD cbSize;
                    RECT rcWindow;
                    RECT rcClient;
                    DWORD dwStyle;
                    DWORD dwExStyle;
                    DWORD dwWindowStatus;
                    UINT cxWindowBorders;
                    UINT cyWindowBorders;
                    ATOM atomWindowType;
                    WORD wCreatorVersion;
                } WINDOWINFO, *PWINDOWINFO, *LPWINDOWINFO;
                */
                WINDOWINFO windowInfo;
                windowInfo.cbSize = sizeof(WINDOWINFO);
                ret = GetWindowInfo(hwnd, &windowInfo);
                if (!ret) {
                    printf("GetWindowInfo hwnd=%p -> fail(%ld)
    ", hwnd, GetLastError());
                }
                else {
                    printf("GetWindowInfo hwnd=%p -> dwStyle=%ld, dwExStyle=%ld, dwWindowStatus=%ld, cxWindowBorders=%d, cyWindowBorders=%d, wCreatorVersion=%d
    ", hwnd, windowInfo.dwStyle, windowInfo.dwExStyle, windowInfo.dwWindowStatus, windowInfo.cxWindowBorders, windowInfo.cyWindowBorders, windowInfo.wCreatorVersion);
                }
                printf("
    ");
            }
        }
    
        return TRUE;
    }
    
    int main()
    {
        BOOL ret;
        while (true) {
            /*
            typedef struct tagPOINT
            {
                LONG  x;
                LONG  y;
            } POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
            */
            POINT point;
            ret = GetCursorPos(&point);
            if (!ret) {
                printf("GetCursorPos -> fail(%ld)
    ", GetLastError());
            }
            else {
                printf("GetCursorPos -> (%ld, %ld)
    ", point.x, point.y);
    
                //获取桌面句柄
                HWND desktopHwnd = GetDesktopWindow();
    
                /*
                BOOL EnumChildWindows(
                    HWND hWndParent,         // handle to parent window // 父窗口句柄
                    WNDENUMPROC lpEnumFunc,  // callback function // 回调函数的地址
                    LPARAM lParam            // application-defined value // 你自已定义的参数
                );
                直到调用到最个一个子窗口被枚举或回调函数返回一个false,否则将一直自动枚举下去。
                */
                ret = EnumChildWindows(desktopHwnd, EnumChildProcess, (LPARAM)&point);
            }
    
            /*
            WINBASEAPI VOID WINAPI Sleep(
                _In_ DWORD dwMilliseconds
            );
            Sleep会将线程挂起,把CPU让给其它线程,单位是毫秒
            */
            Sleep(20000);
        }
    
        system("pause");
        return 0;
    }
    

    版权声明: 本博客,文章与代码均为学习时整理的笔记,博客中除去明确标注有参考文献的文章,其他文章【均为原创】作品,转载请务必【添加出处】,您添加出处是我创作的动力!

    警告:如果您恶意转载本人文章,则您的整站文章,将会变为我的原创作品,请相互尊重!
  • 相关阅读:
    函数式编程笔记
    Java时间类总结
    【问题记录】MySQL中时间戳转日期格式和Java中时间戳转日期格式偶尔不一致
    Java 注解
    Java编程思想之十 内部类
    Java编程思想之九 接口
    Java编程思想之八多态
    Java编程思想之七复用类
    Java编程思想之六访问权限控制
    Java编程思想之五初始化与清理
  • 原文地址:https://www.cnblogs.com/LyShark/p/15020012.html
Copyright © 2020-2023  润新知