We help IT Professionals succeed at work.

Handle

trunin
trunin asked
on
Hi,
I want to get handle of the application. I know only application name(qqq.exe). I cannot use FindWindow, because i don't know application class name. Can I found class name or handle?
Comment
Watch Question

Commented:
You can find application handle with Caption on the main form, no need for class name, example:

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  i: Integer;
begin
  i:= FindWindow(nil, 'Experts-Exchange Notifier');
  SendMessage(i, Wm_Close, 0, 0);
end;

This will close the application that has 'Experts-Exchange NOtifier' in main form caption

Motaz
Mohammed NasmanSoftware Developer
CERTIFIED EXPERT

Commented:
Hello

  use CreateProccess to run a program, and you can get the handle for the process using ProcInfo.hProcess, then u can close the applicaion u started without needing to know the class name
//===
var
  Form1: TForm1;
  ProcInfo : TProcessInformation;
implementation

{$R *.DFM}


procedure TForm1.Button1Click(Sender: TObject);
var
  SUInfo : TStartupInfo;
begin
  if ProcInfo.hProcess <> 0 then
    Exit;

  FillChar(SUInfo   , SizeOf(SUInfo)   , #0);
  FillChar(ProcInfo , SizeOf(ProcInfo) , #0);

  SUInfo.cb          := SizeOf(SUInfo);
  SUInfo.dwFlags     := STARTF_USESHOWWINDOW;
  SUInfo.wShowWindow := SW_SHOW;
  if not CreateProcess(nil,
                       pChar('c:\windows\'+
                             'notepad.exe'),
                       nil,
                       nil,
                       FALSE,
                       CREATE_NEW_CONSOLE or
                       NORMAL_PRIORITY_CLASS,
                       nil,
                       pChar(ExtractFilePath('c:\windows\'+
                                             'notepad.exe')),
                       SUInfo,
                       ProcInfo) then
    ShowMessage('CreateProcess FAILED!!!');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  tmpCard : Cardinal;
begin
  if GetExitCodeProcess(ProcInfo.hProcess,tmpCard) then
  begin
    if TerminateProcess(ProcInfo.hProcess,tmpCard) then
      FillChar(ProcInfo, SizeOf(ProcInfo),#0);
  end;
end;

Commented:
Hi,

here is a simple sample. I think, it's help. I don't sure it (GetModuleFileNameEx) works on Win95/98.

uses PsApi;  // !!

function EnumWindowsProc(Wnd : HWnd; Form : TForm1) : Bool;
          Export; StdCall;
var
  Buffer : Array[0..200] of char;
  A : array[0..MAX_PATH] of Char;
  ClassName  : Array[0..255] of Char;
  aInstance : integer;
  ThreadId : integer;
  ProcessId : integer;
  aProcess : integer;
begin
  Result := True;
  if GetWindow(Wnd, GW_CHILD) <= 0 then Exit;
  GetWindowText(Wnd, Buffer,100);
  if StrPas(Buffer) = '' then Exit;
  aInstance := GetWindowLong(Wnd, GWL_HINSTANCE);
  ThreadId := GetWindowThreadProcessId(Wnd, @ProcessId);
  aProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
  GetModuleFileNameEx(aProcess, aInstance, @A[0], MAX_PATH);
  GetClassName(Wnd, ClassName, SizeOf(ClassName))
  if AnsiUpperCase(ExtractFilePath(StrPas(A))) = 'ANYTHING.EXE' then
    begin
      Form.QryHandle := aInstance;
      Form1.qryClassName := StrPas(ClassName);
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form1.QryHandle := 0;
  Form1.qryClassName := '';
  EnumWindows(@EnumWindowsProc,LongInt(Self));
end;
firstly .. what do you really need ?
a handle of a running application or a handle to it's main window ?
for application handle use mnasman's code
to find an apps main window use motaz' way

please make questions more understandable and add a lil' info on what you're trying to do ...
then we can help you with it or even find a better way to do it

Author

Commented:
to Motaz. Caption of the application is allways different, but I try to see all windows, because 3 last letters of the caption is allways same.

to mnasman. The apllication can be also started before I start my program.

to kunetz. I try your code later and then answer how it was.

Commented:
HI, trunin,
Could you exactly tell what do you know of the application
you want a Handle of.
And for what purpose: to terminate or what?
Sincerely,
Nestorua.

Author

Commented:
Hi all.
I already did it. There is source code.

procedure KillAllABCs;
var
  test, test1 : THandle;
  capt: array[0..255] of char;
  temp: string;
  i, no_prgs : integer;
  prgs : array of THandle;
begin
  no_prgs := 0;
  test := GetWindow(GetDeskTopWindow, GW_CHILD);
  while (test <> 0) do
  begin
    test1 := GetNextWindow(test, GW_HWNDNEXT);
    GetWindowText(test1, @capt, 255);
    temp := capt;
    if Copy(temp, Length(temp) - 2, 3) = 'ABC' then
    begin
      Inc(no_prgs);
      SetLength(prgs, no_prgs);
      prgs[no_prgs - 1] := test1;
    end;
    test := test1;
  end;

  for i := 0 to no_prgs - 1 do
  begin
    PostMessage(prgs[i], WM_Close, 0, 0);
    Sleep(200);
    PostMessage(prgs[i], WM_Close, 0, 0);
  end;
end;