winexec (...)와 같은 사용자 지정 함수를 만드는 데 사용합니다. 실행 된 응용 프로그램 핸들을 다시 실행하는 Hwnd입니다.winexec 또는 shellexecute에서 실행되는 핸들을 얻는 방법은 무엇입니까?
필자는 findwindow()를 사용했지만 윈도우 캡션을 변경하면 문제가 발생했습니다.
winexec (...)와 같은 사용자 지정 함수를 만드는 데 사용합니다. 실행 된 응용 프로그램 핸들을 다시 실행하는 Hwnd입니다.winexec 또는 shellexecute에서 실행되는 핸들을 얻는 방법은 무엇입니까?
필자는 findwindow()를 사용했지만 윈도우 캡션을 변경하면 문제가 발생했습니다.
어떤 프로그램이 하나 개의 창을 가지고 있다는 보장이 없기 때문에 응용 프로그램의 "는"창 핸들을 얻을 수있는 일반적인 방법은 없습니다 핸들. 프로그램에는 많은 최상위 핸들 (즉, Microsoft Word, 각 문서 당 하나)이 있거나 윈도우가 전혀 없을 수도 있습니다. 창 핸들을 정말로 필요로하는지 질문 할 수 있습니다. 특정 창 핸들을 필요로하지 않으려 고 시도하고있는 모든 작업을 더 나은 방법으로 수행 할 수 있습니다.
WinExec
(약 15 년간 사용되지 않으므로 더 이상 사용하지 않는 것이 좋습니다.) ShellExecute
실제로 시작하는 프로그램에 대한 정보는 절대 반환되지 않습니다. (ShellExecute
은 DDE를 사용하여 이미 실행중인 응용 프로그램 인스턴스에 명령을 보낼 수 있습니다.) 응용 프로그램을 시작하면 프로그램이 더 이상 실행되기 전에 실행을 마칠 수 있습니다.
대신 CreateProcess
또는 ShellExecuteEx
을 사용할 수 있습니다. 프로그램을 시작하면 시작한 프로그램을 나타내는 프로세스 핸들을 제공합니다. 이를 사용하여 창 목록과 같은 프로그램에 대한 추가 정보를 얻을 수 있습니다. 귀찮게하지 마십시오 FindWindow
; 캡션 및 윈도우 클래스가 고유하다고 보장 할 수는 없습니다. 프로그램은 많은 다른 창에 대해 동일한 클래스 이름을 사용할 수 있으며 프로그램의 여러 인스턴스는 실제로 원하는 것을 선택하기 위해 동일한 클래스 이름을 사용합니다.
EnumWindows
은 후보 창 핸들 목록을 가져 오는 데 사용할 수있는 함수입니다. 함수 포인터를주고, 데스크톱의 각 최상위 창마다 해당 함수를 한 번 호출합니다. 관심있는 프로세스와 결과 목록을 반환하는 방법을 알려주는 방법이 필요합니다.
type
PWindowSearch = ^TWindowSearch;
TWindowSearch = record
TargetProcessID: DWord;
ResultList: TWndList;
end;
TWndList
내가 HWnd
값의 목록을 유지하기 위해 만들어 유형은 다음과 같습니다 매개 변수가 더 많은 정보를 보유하는 구조에 대한 포인터해야 할 것이다 있도록 기능은, 하나 개의 매개 변수를 받아들입니다. Delphi 2009 이상을 사용하는 경우 TList<HWnd>
을 사용할 수 있습니다. 이전 버전에서는 TList
자손 또는 선택한 항목을 사용할 수있었습니다.
CreateProcess
TProcessInformation
기록의 dwProcessID
구성원에 새 프로세스 ID를 알려줍니다. ShellExecuteEx
은 프로세스 핸들 만 반환하므로 GetProcessID
을 사용하십시오.
function GetWindowListByProcessID(pid: DWord): TWndList;
var
SearchRec: TWindowSearch;
begin
Result := TWndList.Create;
try
SearchRec.TargetProcessID := pid;
SearchRec.ResultList := Result;
Win32Check(EnumWindows(SelectWindowByProcessID, LParam(@SearchRec)));
except
Result.Free;
raise;
end;
end;
당신은이 같은 콜백 함수를 구현하는 것입니다 :
function SelectWindowByProcessID(Wnd: HWnd; Param: LParam): Bool; stdcall;
당신은이 같은 핸들의 목록을 얻으려면 EnumWindows
를 사용할 수 있습니다 창 - 열거 기능이 서명과 일치하는 콜백 함수를 필요로
function SelectWindowByProcessID(Wnd: HWnd; Param: LParam): Bool; stdcall;
var
SearchRec: PWindowSearch;
WindowPid: DWord;
begin
SearchRec := PWindowSearch(Param);
Assert(Assigned(SearchRec));
GetWindowThreadProcessID(Wnd, WindowPid);
if WindowPid = SearchRec.TargetProcessID then
SearchRec.ResultList.Add(Wnd);
Result := True;
end;
일단 목록이 있으면 실제로 어떤 것이 있는지 확인하기 위해 창의 다른 속성을 검사 할 수 있습니다. 창 제목이나 클래스 이름 또는 해당 창 중 하나 인 다른 컨트롤에 의해 결정할 수 있습니다.
프로세스 핸들 사용을 마쳤 으면 OS가 프로세스의 부기 정보를 정리할 수 있도록 CloseHandle
으로 전화하십시오.
EnumWindows라는 함수가 있습니다. 나는 그것이 당신에게 유용하다고 생각합니다.
확인 자세한 정보는 다음 링크
이 페이지의 예제 6을 (http://delphidabbler.com/tips/134) 사용해 보시고 조금 수정하십시오. 그게 내가 한 짓이야. 당신이 확인 어디에 분할하려는 당신이 당신의 결과를 검토 어디에 당신은 내가 당신의 일부가 절전()에서 던지는이에 증오 메일을 삭제합니다 실현
var
//...
runNext : Boolean;
//...
begin
{ startup code from other sample here }
// but instead of if
runNext := ShellExecuteEx(@SEInfo);
{ some more code here }
// need delay before running next process
// run loop until window with Handle is closed
if runNext then
with SEInfo do
repeat
GetExitCodeProcess(SEInfo.hProcess, ExitCode);
Sleep(20);
Application.ProcessMessages;
CheckSynchronize();
until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
{ next process code here }
end;
그런 짓을하지만 할 수있는 경우
보트로드를 처리하고 기다릴 때까지 실행을 마칠 때까지 창을 잠그지 마십시오.
SetWindowText()를 사용 했습니까? 커스텀 함수에서? SetWindowText(); 자막을 원하는대로 다시 바꿀 것입니다. 사용자 정의 함수를 공유하면 을 (를) 도울 수 있고 내 영어가 유감 스럽습니다. –
어떤 창을 처리합니까? 메인 윈도우? 응용 프로그램 핸들? 시작하는 앱에 따라 특정 핸들은 절대로 존재하지 않으며 잠시 후에 만 존재한다는 점에 유의하십시오. –
@Omair, 그가 원하는대로 캡션을 다시 설정하려면 SetWindowText를 호출 할 수 있다면 그는 이미 윈도우 핸들을 가졌다는 것을 의미합니다. 그는 창 핸들을 찾고 있기 때문에 아직 가지고 있지 않으므로 SetWindowText를 호출 할 수 없다고 확신 할 수 있습니다. 게다가 다른 프로그램의 창 캡션을 변경하는 것은 좋지 않습니다. –