안녕하세요..
실행중인 Process의 ProcessID로 그 Process의 윈도우 핸들을
구할 수 있나요?
여기 있는 팁들을 보고 프로그램을 만들고 있는데,
실행 중인 프로세스를 찾아서 실행/종료 시키는 프로그램입니다..
근데 같은 프로그램이 두개 이상 실행될 수 있어서
그 프로그램의 캡션을 얻어서 두 프로그램을 구분해서 종료시키려 하거든요..
예를 들면, mytest.exe란 프로그램이 두개이상 실행될때,
캡션이 각각 mytest1, mytest2.... 이런식으로 실행된다고 생각하시면 됩니다..
좋은 답변 부탁드립니다..
> 안녕하세요..
>
> 실행중인 Process의 ProcessID로 그 Process의 윈도우 핸들을
> 구할 수 있나요?
> 여기 있는 팁들을 보고 프로그램을 만들고 있는데,
> 실행 중인 프로세스를 찾아서 실행/종료 시키는 프로그램입니다..
> 근데 같은 프로그램이 두개 이상 실행될 수 있어서
> 그 프로그램의 캡션을 얻어서 두 프로그램을 구분해서 종료시키려 하거든요..
> 예를 들면, mytest.exe란 프로그램이 두개이상 실행될때,
> 캡션이 각각 mytest1, mytest2.... 이런식으로 실행된다고 생각하시면 됩니다..
> 좋은 답변 부탁드립니다..
안녕하세요 김영대입니다
저도 비슷한 경험이 있어서 몇자 적어봅니다
thread ID 를 가지고 EnumThreadWindows() 함수를 사용하면 원도우 핸들을
구할 수 있고 반대로 원도우 핸들을 가지고 GetWindowThreadProcessID() 함수를
사용하면 프로세스와 쓰레도 ID 를 구할 수 있습니다
근데 Proess ID 를 가지고 window handle 을 구하는게 쉽지가 않고
또 Process 를 TerminateProcess() 로 강제로 종료하면 그 프로그램이 사용했던
resource 가 제대로 반납이 안되는 문제가 있으므로 해당 원도우에 WM_CLOSE
메시지를 보내어 resource 를 반납할 기회를 주어야 좋을듯 합니다
아래는 현재 실행중인 응용 프로그램들의 원도우 핸들을 구해서 처리하는
예제입니다
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
B_Search: TButton;
B_Maximize: TButton;
B_minimize: TButton;
B_kill: TButton;
procedure B_SearchClick(Sender: TObject);
procedure B_MaximizeClick(Sender: TObject);
procedure B_minimizeClick(Sender: TObject);
procedure B_killClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure GetAllWindowsProc(WinHandle: HWND; Slist: TStrings);
var
P: array[0..256] of Char; {title bar를 저장 할 buffer}
begin
P[0] := #0;
GetWindowText(WinHandle, P, 255); {window's title bar를 알아낸다}
if (P[0] <> #0) then
(*
if IsWindowVisible(WinHandle) and {invisible한 window는 제외}
((GetWindowLong(WinHandle, GWL_EXSTYLE) and WS_EX_TOOLWINDOW) = 0) then
*)
if IsWindowVisible(WinHandle) then {invisible한 window는 제외}
Slist.AddObject(P, TObject(WinHandle)); {window의 handle 저장}
end;
procedure GetAllWindows(Slist: TStrings);
var
WinHandle: HWND;
Begin
WinHandle := FindWindow(nil, nil);
GetAllWindowsProc(WinHandle, Slist);
while (WinHandle <> 0) do {Top level의 window부터 순차적으로 handle을 구한다}
begin
WinHandle := GetWindow(WinHandle, GW_HWNDNEXT);
GetAllWindowsProc(WinHandle, Slist);
end;
end;
procedure TForm1.B_SearchClick(Sender: TObject);
begin
ListBox1.Items.Clear;
GetAllWindows(ListBox1.Items);
end;
procedure TForm1.B_MaximizeClick(Sender: TObject);
begin
if ListBox1.ItemIndex < 0 then
System.Exit;
{선택한 window를 maximize}
ShowWindow(HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]), SW_MAXIMIZE);
end;
procedure TForm1.B_minimizeClick(Sender: TObject);
begin
if ListBox1.ItemIndex < 0 then
System.Exit;
{선택한 window를 minimize}
ShowWindow(HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]), SW_MINIMIZE);
end;
procedure TForm1.B_killClick(Sender: TObject);
begin
if ListBox1.ItemIndex < 0 then
System.Exit;
{선택한 window를 close 시킨다}
PostMessage(HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]), WM_CLOSE, 0, 0);
end;
end.