C ++ / Win32 перечисляет окна, принадлежащие моему процессу, и закрывает их - PullRequest
2 голосов
/ 24 октября 2011

У меня есть приложение для Windows, в которое встроен веб-браузер (Internet Explorer).Приложение может быть закрыто от другого процесса с помощью IPC.Он работает просто отлично, за исключением ситуации, когда встроенный веб-браузер может отображать всплывающее диалоговое окно (скажем, во время сохранения содержимого).В этом случае мое приложение вылетает, когда оно пытается закрыть внешний запрос через IPC.(Внутренне он просто отправляет сообщение WM_CLOSE самому себе.)

В свете этого я подумал о том, чтобы найти способ перечислить все окна, которые принадлежат моему процессу, и сначала закрыть их, прежде чем закрыть сам мой процесс.Вопрос в том, как перечислить все окна, принадлежащие моему процессу, с целью их закрытия?

Ответы [ 2 ]

3 голосов
/ 24 октября 2011

ОК, наверное, я все понял сам.Вот если кому-то интересно:

#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 голосов
/ 24 октября 2011

Если вы хотите, чтобы ваш процесс завершился, просто позвоните ExitProcess. Неважно, какие окна могут быть открыты в это время, они все уходят.

...