Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++/Win32枚举属于我的进程的窗口&;关闭它们_C++_Winapi_Process_Hwnd_Enumerate - Fatal编程技术网

C++ C++/Win32枚举属于我的进程的窗口&;关闭它们

C++ C++/Win32枚举属于我的进程的窗口&;关闭它们,c++,winapi,process,hwnd,enumerate,C++,Winapi,Process,Hwnd,Enumerate,我有一个Windows应用程序,其中嵌入了一个web浏览器(Internet explorer)。应用程序可以通过IPC从另一个进程关闭。除了嵌入式web浏览器可能会显示一个弹出对话框窗口(例如,在保存内容时)的情况外,它工作正常。在这种情况下,当我的应用程序试图通过IPC从外部请求关闭时崩溃。(在内部,它只是将WM_CLOSE消息发布到自身。) 有鉴于此,我想想出一种方法来枚举属于我的进程的所有窗口,并在关闭进程之前先关闭它们。问题是,如何枚举属于我的进程的所有窗口以关闭它们?如果希望进程退出

我有一个Windows应用程序,其中嵌入了一个web浏览器(Internet explorer)。应用程序可以通过IPC从另一个进程关闭。除了嵌入式web浏览器可能会显示一个弹出对话框窗口(例如,在保存内容时)的情况外,它工作正常。在这种情况下,当我的应用程序试图通过IPC从外部请求关闭时崩溃。(在内部,它只是将WM_CLOSE消息发布到自身。)


有鉴于此,我想想出一种方法来枚举属于我的进程的所有窗口,并在关闭进程之前先关闭它们。问题是,如何枚举属于我的进程的所有窗口以关闭它们?

如果希望进程退出,只需调用
ExitProcess
。不管当时打开的是什么窗口,它们都会消失。

好吧,我想是我自己弄的。如果有人感兴趣,这里有:

#define SIZEOF(f) (sizeof(f) / sizeof(f[0]))
typedef struct _ENUM_POPUPS_INFO{
    DWORD dwProcID;
    HWND hThisWnd;
    int nNextHWNDIndex;
    HWND hFoundHWNDs[256];
}ENUM_POPUPS_INFO;

void CloseAllOpenPopups(HWND hWnd, int dwmsWait)
{
    //'hWnd' = our main window handle (we won't close it)
    //'dwmsWait' = maximum wait time in milliseconds, or -1 to wait for as long as needed
    ENUM_POPUPS_INFO epi = {0};
    BOOL bR;
    int i, iIteration;
    HWND hWndRoot, hWndActivePopup;

    DWORD dwmsTickBegin = GetTickCount();

    for(iIteration = 0;; iIteration = 1)
    {
        //Get our process ID
        memset(&epi, 0, sizeof(epi));
        epi.hThisWnd = hWnd;
        epi.dwProcID = GetCurrentProcessId();

        bR = EnumWindows(EnumPopupWindowsProc, (LPARAM)&epi);

        //Did we get any
        if(epi.nNextHWNDIndex == 0)
            break;

        //Wait on a second and later iteration
        if(iIteration > 0)
        {
            if(dwmsWait != -1)
            {
                DWORD dwmsTick = GetTickCount();
                int nmsDiff = abs((long)(dwmsTick - dwmsTickBegin));
                if(nmsDiff >= dwmsWait)
                {
                        //Timed out
                break;
                }

                //Wait
                Sleep(min(100, dwmsWait - nmsDiff));
            }
            else
            {
                //Wait
                Sleep(100);
            }
        }

        //Go through all windows found
            for(i = 0; i < epi.nNextHWNDIndex; i++)
        {
            //Get root owner
            hWndRoot = GetAncestor(epi.hFoundHWNDs[i], GA_ROOTOWNER);
            if(!hWndRoot)
                continue;

            //Get it's active popup
            hWndActivePopup = GetLastActivePopup(hWndRoot);
            if(!hWndActivePopup)
                continue;

            //Close it
            PostMessage(hWndActivePopup, WM_CLOSE, 0, 0);
        }
    }
}    


BOOL CALLBACK EnumPopupWindowsProc(HWND hWnd, LPARAM lParam)
{
    ENUM_POPUPS_INFO* pEPI = (ENUM_POPUPS_INFO*)lParam;

    //Get process ID of the window
    DWORD dwProcID = 0;
    GetWindowThreadProcessId(hWnd, &dwProcID);

    //We need this window only if it's our process
    if(dwProcID == pEPI->dwProcID &&
        pEPI->hThisWnd != hWnd &&
        ((GetWindowLongPtr(hWnd, GWL_STYLE) & (WS_VISIBLE | WS_POPUP | WS_CAPTION)) == (WS_VISIBLE | WS_POPUP | WS_CAPTION)))
    {
        if(pEPI->nNextHWNDIndex >= SIZEOF(pEPI->hFoundHWNDs))
        {
            //Stop, we're full
            return FALSE;
        }

        //Add it
        pEPI->hFoundHWNDs[pEPI->nNextHWNDIndex] = hWnd;
        pEPI->nNextHWNDIndex++;
    }

    return TRUE;
}
定义SIZEOF(f)(SIZEOF(f)/SIZEOF(f[0])) typedef结构\u枚举\u弹出窗口\u信息{ 德沃德·德普罗西德; HWND-hThisWnd; int nNextHWNDIndex; HWND-hFoundHWNDs[256]; }枚举弹出窗口信息; void closeAllopen弹出窗口(HWND HWND、int dwmsWait) { //“hWnd”=我们的主窗口句柄(我们不会关闭它) //“dwmsWait”=以毫秒为单位的最大等待时间,或-1等待所需的时间 枚举弹出窗口信息epi={0}; 布尔布尔; 内部迭代; HWND hWndRoot,hWndActivePopup; DWORD dwmsTickBegin=GetTickCount(); 对于(迭代=0;迭代=1) { //获取我们的进程ID memset(&epi,0,sizeof(epi)); epi.hThisWnd=hWnd; epi.dwProcID=GetCurrentProcessId(); bR=EnumWindows(EnumPopupWindowsProc,(LPARAM)和epi); //我们收到了吗 如果(epi.nnexthwnindex==0) 打破 //等待第二次和以后的迭代 如果(迭代>0) { 如果(dwmsWait!=-1) { DWORD dwmsTick=GetTickCount(); int nmsDiff=abs((长)(dwmsTick-dwmsTickBegin)); 如果(nmsDiff>=dwmsWait) { //超时 打破 } //等等 睡眠(分钟(100,dwmsWait-nmsDiff)); } 其他的 { //等等 睡眠(100); } } //检查所有发现的窗户 对于(i=0;idwProcID&& pEPI->hThisWnd!=hWnd&& ((GetWindowLongPtr(hWnd,GWL_样式)和(WS_可见| WS_弹出| WS_标题))==(WS_可见| WS_弹出| WS_标题))) { 如果(pEPI->nNextHwnIndex>=SIZEOF(pEPI->hFoundHWNDs)) { //停,我们已经客满了 返回FALSE; } //加上 pEPI->hFoundHWNDs[pEPI->NNextHwnIndex]=hWnd; pEPI->NNexthwnindex++; } 返回TRUE; }
谢谢,但是使用ExitProcess方法会导致非常奇怪的行为。我的窗口和IE弹出窗口一样关闭,但我仍然可以在任务栏中看到我的程序图标,其进程可以通过任务管理器看到。摆脱它们的唯一方法是通过任务管理器杀死它。@ahmd0:它不应该再列在任务管理器中了。如果您正在创建通知图标,是的,您应该首先删除该图标。但是搜索IE创建的每个弹出窗口仍然是可选的。