关闭窗口不会最小化我刚刚启动的进程的窗口

CloseWindow doesn't minimize window from the process I just launched

本文关键字:窗口 进程 启动 最小化      更新时间:2023-10-16

好吧,我想在启动窗口后最小化窗口,但它没有生效,我不知道我做错了什么。你能指出下面代码中的错误吗?

除了打开一个窗口之外,什么也没发生。

HWND  g_hwnd;
int  g_nFound;
BOOL CALLBACK FindHwndFromPID(HWND hwnd, LPARAM lParam);
HWND GetHwndFromPID(DWORD dwProcessId)
{
g_hwnd = NULL;
g_nFound = 0;
EnumWindows(FindHwndFromPID, (LPARAM)dwProcessId);
if (g_hwnd)  // we found one...
    return (g_hwnd);
// nothing found :-(
return (NULL);
}
BOOL CALLBACK FindHwndFromPID(HWND hwnd, LPARAM lParam)
{
DWORD   dwPID2Find = (DWORD)lParam;
DWORD   dwPID = 0;
if (GetWindowThreadProcessId(hwnd, &dwPID))
{
    if (dwPID == dwPID2Find)
    {
        g_hwnd = hwnd;

        return  (FALSE);
    }
}
return  (TRUE);
}

 int main
 {
     ..../
 if (!CreateProcessA(NULL,     // No module name (use command line)
     command_line.GetBuffer(),
     NULL,           // Process handle not inheritable
     NULL,           // Thread handle not inhberitable
     FALSE,          // Set handle inheritance to FALSE
     0,              // No creation flags
     NULL,           // Use parent's environment block
     NULL,           // Use parent's starting directory 
     &si,            // Pointer to STARTUPINFO structure
     &pi)           // Pointer to PROCESS_INFORMATION structure
     )
 {
     //... error handling
     return 0;
 }
 WaitForInputIdle(pi.hProcess, 1000);
 HWND hwnds = GetHwndFromPID(pi.dwProcessId);
 printf("Process Handle %d, hwnd id: %p ",pi.dwProcessId, hwnds);
 CloseWindow(hwnds);

该代码应该最小化窗口,但我不知道为什么它没有。

你这样做

的方式是错误的。 要求生成进程最初最小化运行的官方和文档方法是在调用CreateProcess()时使用STARTUPINFO结构,例如:

int main()
{
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cbSize = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_MINIMIZE;
    //...
    if (!CreateProcessA(..., &si, ...))
    {
        //... error handling
        return 0;
    }
    //...
    return 0;
}

创业信息结构

wShowWindow
如果 dwFlags 指定STARTF_USESHOWWINDOW,则此成员可以是可在 ShowWindow 函数的 nCmdShow 参数中指定的任何值,但 SW_SHOWDEFAULT 除外。否则,将忽略此成员。

对于 GUI 进程,第一次调用 ShowWindow 时,将忽略其 nCmdShow 参数,wShowWindow 指定默认值。在对 ShowWindow 的后续调用中,如果 ShowWindow 的 nCmdShow 参数设置为 SW_SHOWDEFAULT,则使用 wShowWindow 成员。

显示窗口功能

nCmdShow [in]
类型:整数

控制窗口的显示方式。如果启动应用程序的程序提供 STARTUPINFO 结构,则应用程序首次调用 ShowWindow 时将忽略此参数。否则,首次调用 ShowWindow 时,该值应为 WinMain 函数在其 nCmdShow 参数中获取的值。

应用程序第一次调用 ShowWindow 时,应使用 WinMain 函数的 nCmdShow 参数作为其 nCmdShow 参数。对 ShowWindow 的后续调用必须使用给定列表中的值之一,而不是由 WinMain 函数的 nCmdShow 参数指定的值。

如讨论 nCmdShow 参数中所述,如果启动应用程序的程序在结构中指定了启动信息,则在第一次调用 ShowWindow 时将忽略 nCmdShow 值。在这种情况下,ShowWindow 使用 STARTUPINFO 结构中指定的信息来显示窗口。在后续调用中,应用程序必须调用 ShowWindow,并将 nCmdShow 设置为 SW_SHOWDEFAULT 才能使用启动该应用程序的程序提供的启动信息。此行为设计用于以下情况:

• 应用程序通过调用设置WS_VISIBLE标志的 CreateWindow 来创建其主窗口。

• 应用程序通过在清除WS_VISIBLE标志的情况下调用 CreateWindow 来创建其主窗口,然后调用 ShowWindow,并将SW_SHOW标志设置为可见。

因为应用程序窗口可能不属于启动的进程,而是属于它的子进程,所以你必须通过在比较中包含父进程来更深入地FindHwndFromPID

此外,我们自己也不会指望WaitForInputIdle(),您必须给创建的进程足够的时间来完全初始化。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tlhelp32.h>
HWND  g_hwnd;
int  g_nFound;
BOOL CALLBACK FindHwndFromPID(HWND hwnd, LPARAM lParam);
/*___________________________________________________________________________________________________
*/
HWND GetHwndFromPID(DWORD dwProcessId)
{
    g_hwnd = NULL;
    g_nFound = 0;
    EnumWindows(FindHwndFromPID, (LPARAM)dwProcessId);
    if (g_hwnd)  // we found one...
        return (g_hwnd);
    // nothing found :-(
    return (NULL);
}
/*___________________________________________________________________________________________________
*/
DWORD GetParentProcess(DWORD pid){
    PROCESSENTRY32 p32={sizeof(PROCESSENTRY32)};
    DWORD ParentPID=0;
    HANDLE hSnapShot =  CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0 );
    if(Process32First(hSnapShot,&p32)){
        do{
            if(p32.th32ProcessID==pid){
                ParentPID = p32.th32ParentProcessID;
                break;
            }
        }while(Process32Next(hSnapShot,&p32));
    }
    CloseHandle(hSnapShot);
    return ParentPID;
}
/*___________________________________________________________________________________________________
*/
int __stdcall WindowText(HWND hWnd,LPSTR lpString,int nMaxCount){
    int ret;
    ret=SendMessage(hWnd,WM_GETTEXTLENGTH,0,0);
    if(ret){
        ret=SendMessage(hWnd,WM_GETTEXT,nMaxCount,(LPARAM)lpString);
    }
    return ret;
}
/*___________________________________________________________________________________________________
*/
BOOL CALLBACK FindHwndFromPID(HWND hwnd, LPARAM lParam){
    DWORD   dwPID2Find = (DWORD)lParam;
    DWORD   dwPID = 0;
    if(GetWindowLong(hwnd,GWLP_HWNDPARENT) || !IsWindowVisible(hwnd))
        return 1;
    if (GetWindowThreadProcessId(hwnd, &dwPID)){
        if ((dwPID == dwPID2Find) || ( GetParentProcess(dwPID) == dwPID2Find)){
            g_hwnd = hwnd;
            return  (FALSE);
        }
    }
    return  (TRUE);
}
/*___________________________________________________________________________________________________
*/
int main(){
    PROCESS_INFORMATION pi;
    STARTUPINFO si={sizeof(si)};
    TCHAR exename[]=TEXT("write.exe"); // writable buffer (for Unicode bug.)
    if (!CreateProcess(NULL,exename,NULL,    NULL,FALSE, 0,     NULL,NULL,&si,     &pi)){
        return 0;
    }

   //WaitForInputIdle(pi.hProcess, 1000); // this alown will not always work (process may have children)
   // give enough time to process to fully initialize
   // put all in a loop until you
   // get the window handle or timeout.
HWND hwnds = GetHwndFromPID(pi.dwProcessId);
for( int i=0 ;i<1000;i++ ){
    if(hwnds)
        break;
    Sleep(10); 
    hwnds = GetHwndFromPID(pi.dwProcessId);
}
    printf("Process Handle %d, hwnd id: %p ",pi.dwProcessId, hwnds);
    CloseWindow(hwnds);

    return 0;
}