【问题标题】:C++/Win32 enumerate windows belonging to my process & close themC++/Win32 枚举属于我的进程的窗口并关闭它们
【发布时间】:2011-10-24 00:17:39
【问题描述】:

我有一个 Windows 应用程序,其中嵌入了一个 Web 浏览器(Internet Explorer)。该应用程序可以通过 IPC 从另一个进程中关闭。它工作得很好,除了嵌入式 Web 浏览器可能显示弹出对话框窗口的情况(例如,在保存内容期间)。在这种情况下,我的应用程序在尝试通过 IPC 从外部请求关闭时崩溃。 (在内部,它只是将 WM_CLOSE 消息发布给自己。)

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

【问题讨论】:

    标签: c++ winapi process hwnd enumerate


    【解决方案1】:

    好的,我想我自己搞定了。如果有人感兴趣,请看这里:

    #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;
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢,但是使用 ExitProcess 方法会导致非常奇怪的行为。我的窗口和 IE 弹出窗口一样关闭,但我仍然在任务栏中看到我的程序图标,并且通过任务管理器可以看到它的进程。摆脱这些的唯一方法是通过任务管理器将其杀死。
      • @ahmd0:它不应该再列在任务管理器中了。如果您正在创建通知图标,是的,您应该先将其删除。但是寻找由 IE 创建的每个弹出窗口仍然是可选的。
      猜你喜欢
      • 2011-05-31
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      相关资源
      最近更新 更多