C++ C++/Win32枚举属于我的进程的窗口&;关闭它们
我有一个Windows应用程序,其中嵌入了一个web浏览器(Internet explorer)。应用程序可以通过IPC从另一个进程关闭。除了嵌入式web浏览器可能会显示一个弹出对话框窗口(例如,在保存内容时)的情况外,它工作正常。在这种情况下,当我的应用程序试图通过IPC从外部请求关闭时崩溃。(在内部,它只是将WM_CLOSE消息发布到自身。)C++ C++/Win32枚举属于我的进程的窗口&;关闭它们,c++,winapi,process,hwnd,enumerate,C++,Winapi,Process,Hwnd,Enumerate,我有一个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;i谢谢,但是使用ExitProcess方法会导致非常奇怪的行为。我的窗口和IE弹出窗口一样关闭,但我仍然可以在任务栏中看到我的程序图标,其进程可以通过任务管理器看到。摆脱它们的唯一方法是通过任务管理器杀死它。@ahmd0:它不应该再列在任务管理器中了。如果您正在创建通知图标,是的,您应该首先删除该图标。但是搜索IE创建的每个弹出窗口仍然是可选的。