none
请问如何最小化其它程序 RRS feed

  • 问题

  • 一个MFC程序,需要点击一个按钮后实现以最小化的形式启动其它的程序。我用

    ShellExecuteW(NULL, _T("open"), strPath, NULL, NULL, SW_SHOWMINIMIZED);

    有些程序可以实现最小化启动,如记事本,word等,但有些不能,如计算器。

    之后我用

    HWND hWnd = ::FindWindowW(NULL,_T("无标题 - 记事本"));

    ::ShowWindow(hWnd, SW_MINIMIZE);

    仍然不能实现最小化启动。我断点跟踪发现hWnd不为NULL,说明确实找到记事本进程了,但后一句没起作用。

    请问该如何实现这个功能啊?

    2011年7月1日 12:56

答案

  • HWND hWnd = ::FindWindowW(NULL,_T("无标题 - 记事本"));

    ::ShowWindow(hWnd, SW_MINIMIZE);

    只所以不成功是因为程序还没有完全启动成功,先休眠一段时间就可以成功了,如下

    Sleep(nSleepTimeSpan);

    HWND hWnd = ::FindWindowW(NULL,_T("无标题 - 记事本"));

    ::ShowWindow(hWnd, SW_MINIMIZE);

    问题暂时解决了,正在研究用CreateProcess()得到的PROCESS_INFORMATION完全控制启动的进程。

    • 已标记为答案 飞羽 2011年7月3日 5:58
    2011年7月3日 5:57

全部回复

  • HWND hWnd = ::FindWindow(_T("Notepad"), NULL);
     if(hWnd)
     {
      ::ShowWindow(hWnd, SW_MINIMIZE);
     }
    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    2011年7月2日 5:53
    版主
  • 我试过仍然不行。我用的win7系统,对于系统自带的记事本是没有问题的,但是计算器总是不能最小化。现在我改用

    STARTUPINFO si;

    memset(&si, 0, sizeof(STARTUPINFO));

    si.cb = sizeof(STARTUPINFO);

    si.dwFlags = STARTF_USESHOWWINDOW;

    si.wShowWindow = SW_SHOWMINIMIZED;

    PROCESS_INFORMATION pi;

    bool crRes = CreateProcess(m_appPath, NULL, NULL, NULL, false, 0, NULL, NULL, &si, &pi);

    同样的记事本最小化而计算器正常显示。我写了如下测试代码

    Sleep(5000);

    ::TerminateProcess(pi.hProcess, 0);

    用计算器做测试,启动5秒后自动关闭。而如下代码

    ::SendMessageW((HWND)pi.hProcess, WM_SIZE, SIZE_MINIMIZE, 0); ::ShowWindow((HWND)pi.hProcess, SW_MINIMIZE);

    对计算器均不起作用。难道说进程间发送最小化消息有什么特殊的用法我没注意到吗?

    • 已编辑 飞羽 2011年7月2日 7:25 格式
    2011年7月2日 7:23
  • 我用的是VC++ 2010,WIN7。
    2011年7月2日 10:49
  • pi.hProcess,

    这是什么?进程句柄不能当窗口句柄用



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    2011年7月2日 17:55
    版主
  • 已试过根据进程句柄获取窗口句柄

    HWND CProcessStart::GetWindowHandleByPID(DWORD dwProcessID)

    {

         HWND h = GetTopWindow(0);

        while ( h )

        {

            DWORD pid = 0;

            DWORD dwTheardId = GetWindowThreadProcessId( h,&pid);

            if (dwTheardId != 0)

            {

                if ( pid == dwProcessID/*your process id*/ )

                {

                    // here h is the handle to the window

                    return h;

                }

            }

            h = GetNextWindow( h , GW_HWNDNEXT);

        }

        return NULL;

    }

    用计算器测试有时成功有时失败。现在正在研究最初的方法

    HWND hWnd = ::FindWindowW(NULL,_T("计算器"));

    ::ShowWindow(hWnd, SW_MINIMIZE);

    第一次最小化启动计算器,第二次正常启动,第三次正常启动,第二次的最小化……以此类推,第n此正常启动,同时最小化第n-1次的。MSDN最::FindWindow()的解释是Retrieves a handle to the top-level window whose class name and window name match the specified strings.难道第二次以后启动的不是在最顶层吗?

    2011年7月3日 2:02
  • HWND hWnd = ::FindWindowW(NULL,_T("无标题 - 记事本"));

    ::ShowWindow(hWnd, SW_MINIMIZE);

    只所以不成功是因为程序还没有完全启动成功,先休眠一段时间就可以成功了,如下

    Sleep(nSleepTimeSpan);

    HWND hWnd = ::FindWindowW(NULL,_T("无标题 - 记事本"));

    ::ShowWindow(hWnd, SW_MINIMIZE);

    问题暂时解决了,正在研究用CreateProcess()得到的PROCESS_INFORMATION完全控制启动的进程。

    • 已标记为答案 飞羽 2011年7月3日 5:58
    2011年7月3日 5:57