2011-11-25 2 views
1

응용 프로그램을 숨기려고하면 실행 중이지만 응용 프로그램 양식은 ​​계속 표시됩니다.델파이 : shellexecute 및 sw_hide

ShellExecute(Handle, nil, 'app.exe', nil, nil, SW_HIDE); 

델파이에서 숨겨진 응용 프로그램을 실행하는 방법은 무엇입니까?

+2

ShellExecute의 SW_HIDE는 전원이 거의 없습니다. 이것은 단지 제안 일뿐 요구는 아닙니다. 숨김 여부는 응용 프로그램에 따라 다릅니다. @ Pateman의 솔루션과 같은 것이 프로세스의 핸들을 얻은 후 숨기고 시작하면 더 확실하게 작동합니다. – hatchet

답변

6

새로 출시 된 응용 프로그램의 프로세스 ID를 반환하고이를 사용하여 창 핸들을 가져올 수 있으므로 CreateProcess을 대신 사용하는 것이 좋습니다. 여기 제가 사용하고있는 함수가 있습니다. 아마도 불필요한 조각을 빼앗아 필요에 맞출 수 있을까요?

{$HINTS OFF} 
{ .: ExecNewProcess :. } 
function ExecNewProcess(const ProgramName: String; 
    const StartHidden, WaitForInput: Boolean; out WndInfo: TWndInfo): Boolean; 
var 
    StartInfo: TStartupInfo; 
    ProcInfo: TProcessInformation; 
    R: TRect; 
    SL: TStringList; 

    {$REGION 'EnumProcess'} 
    function EnumProcess(hHwnd: HWND; lParam: Integer): Boolean; stdcall; 
    var 
    WndInfo: PWndInfo; 
    pid: DWORD; 
    begin 
    Result := True; 

    WndInfo := PWndInfo(lParam); 
    if (WndInfo = nil) or (hHwnd = 0) then 
     exit; 

    GetWindowThreadProcessId(hHwnd, pid); 
    if (pid = WndInfo.PID) then 
    begin 
     if (WndInfo.WndHandle = 0) and (IsWindowVisible(hHwnd)) then 
     WndInfo.WndHandle := hHwnd; 
     //Result := False; 
    end; 
    end; 
    {$ENDREGION} 

begin 
    Result := False; 

    ZeroMemory(@StartInfo, SizeOf(TStartupInfo)); 
    ZeroMemory(@ProcInfo, SizeOf(TProcessInformation)); 

    StartInfo.cb := SizeOf(TStartupInfo); 
    StartInfo.dwFlags := STARTF_USESTDHANDLES; 
    if StartHidden then 
    begin 
    StartInfo.dwFlags := STARTF_USESHOWWINDOW or StartInfo.dwFlags; 
    StartInfo.wShowWindow := SW_SHOWMINNOACTIVE; 
    end; 

    Result := CreateProcess(PChar(ProgramName), nil, nil, nil, False, 0, nil, 
    nil, StartInfo, ProcInfo); 
    try 
    if Result then 
    begin 
     WndInfo.WndHandle := 0; 
     WndInfo.PID := ProcInfo.dwProcessId; 

     if WaitForInput then 
     WaitForInputIdle(ProcInfo.hProcess, INFINITE); 

     EnumWindows(@EnumProcess, Integer(@WndInfo)); 
     if (WndInfo.WndHandle <> 0) then 
     begin 
     if (StartHidden) then 
      ShowWindow(WndInfo.WndHandle, SW_HIDE); 
     Windows.GetWindowRect(WndInfo.WndHandle, R); 

     WndInfo.Width := R.Right - R.Left; 
     WndInfo.Height := R.Bottom - R.Top; 
     end; 
    end; 
    finally 
    CloseHandle(ProcInfo.hProcess); 
    CloseHandle(ProcInfo.hThread); 
    end; 
end; 
{$HINTS ON} 
+0

[DCC 오류] Unit1.pas (28) : E2003 선언되지 않은 식별자 : 'TWndInfo' – dedoki

+0

나중에 사용할 수 있도록 일부 정보를 반환하기 위해 사용중인 레코드입니다. 당신은 정말로 그것을 필요로하지 않습니다. 기본적으로 내가 게시 한 스 니펫에서 필수 부분을 제거하십시오. – Pateman

2

여기

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx

는 SW_HIDE를 처리하는 방법을 결정하는 응용 프로그램에 달려 읽을 수있다. 따라서 응용 프로그램은 메시지를 가져 와서 내가 볼 수있는 한 숨어 야합니다.

+0

** ** 일부 경우 ** 다른 응용 프로그램에서 허용하는 경우 새 프로세스의 프로세스 ID를 사용하고 Windows에이를 숨길 수 있습니다 (위의 Pateman 게시). 하지만 대상 응용 프로그램이 원본이 아니며 대상 응용 프로그램이 강제로 자기를 표시하는 것을 원한다면 다른 응용 프로그램에서 숨길 수 없습니다. 그러나 창을 띄운 직후와 같이 창을 숨기도록 지시 할 수 있습니다. –