?
Solved

ShellExecuteEx

Posted on 2002-05-20
7
Medium Priority
?
321 Views
Last Modified: 2010-04-04
hi Experts,

I start a windows application (let's say notepad) using ShellExecuteEx.

From here, I get hProcess.

Now, having that much, how can I make a call activate the application and bring it to front?

graga
0
Comment
Question by:graga
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 9

Accepted Solution

by:
ginsonic earned 150 total points
ID: 7023334
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7023363
The problem is: How do you know which main window belongs to the given hProcess? That's almost impossible to know, since for enumerating windows and that stuff you need the process *ID*, not the handle. And there is no documented way to get the process ID from the handle.

So you should forget about ShellExecuteEx and instead use CreateProcess. This way you get the process ID and can then call EnumWindows or EnumThreadWindows to find out the main window of the process. If you want to start a document rather than an executable, use FindExecutable prior to calling CreateProcess.

Regards, Madshi.
0
 
LVL 2

Expert Comment

by:Tasomia
ID: 7023396
Hi,

Try this:

function WinExecAndWait32(FileName: string; Visibility: Integer): Integer;
var
  zAppName: array[0..512] of Char;
  zCurDir: array[0..255] of Char;
  WorkDir: string;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  r: DWORD;
begin
  StrPCopy(zAppName, FileName);
  GetDir(0, WorkDir);
  StrPCopy(zCurDir, WorkDir);
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb          := SizeOf(StartupInfo);
  StartupInfo.dwFlags     := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  if not CreateProcess(nil,
    zAppName, // pointer to command line string
    nil, // pointer to process security attributes
    nil, // pointer to thread security attributes
    False, // handle inheritance flag
    CREATE_NEW_CONSOLE or // creation flags
    NORMAL_PRIORITY_CLASS,
    nil, //pointer to new environment block
    nil, // pointer to current directory name
    StartupInfo, // pointer to STARTUPINFO
    ProcessInfo) // pointer to PROCESS_INF
    then Result := -1
  else
  begin
    r := WaitForInputIdle(ProcessInfo.hProcess, 1000);
    while r <> 0 do
    begin
      if r = $FFFFFFFF then RaiseLastWin32Error;
      r := WaitForInputIdle(ProcessInfo.hProcess, 1000);
      Sleep(50);
    end;
    Result := ProcessInfo.dwThreadId;
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end;
end; { WinExecAndWait32 }

function EnumProc(aWnd: HWND; var wnd: HWND): BOOL; stdcall;
begin
  Result := True;
  if (GetWindowLong(aWnd, GWL_HWNDPARENT) = 0) and
    (IsWindowVisible(aWnd) or IsIconic(aWnd)) then
  begin
    Result := False;
    wnd := aWnd;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  threadID: DWORD;
  wnd: HWND;
  buf: array [0..255] of char;
begin
  threadID := WinExecAndWait32('notepad.exe', SW_SHOWNORMAL);
  if threadID = -1 then
  begin
    ShowMessage('Error....');
    Exit;
  end;
  Sleep(100);
  wnd := 0;
  EnumThreadWindows(threadID, @EnumProc, Integer(@wnd));
  memo1.Clear;
  memo1.Lines.Add(Format('Found window, handle: %d', [wnd]));
  GetClassname(wnd, buf, SizeOf(buf));
  memo1.Lines.Add(Format('Classname is %s', [buf]));
  SendMessage(wnd, WM_GETTEXT, SizeOf(buf), Integer(@buf));
  memo1.Lines.Add(Format('Caption is %s', [buf]));
end;
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Expert Comment

by:hashirviqas
ID: 7025769
It is really quite simple.

Try this

uses ShellApi;
...
ShellExecute(Handle, 'open',
  'c:\Windows\notepad.exe', nil, nil, SW_SHOWNORMAL);


If you wanted to open a file with notepad, then use this instead;

ShellExecute(Handle,'open',
  'c:\windows\notepad.exe','c:\mytext.txt',
  nil, SW_SHOWNORMAL);

As a matter of fact you can open up a site with the default web browser too

ShellExecute(Handle, 'open',
  'http://www.dawn.com',nil,nil, SW_SHOWNORMAL);


or how about if you want to send an email message with default mail client on your win 32 box;

var em_subject, em_body, em_mail : string;
begin
 em_subject := 'This is my subject line';
 em_body := 'my Message body text goes here';

 em_mail := 'mailto:me@me.com?subject=' +
   em_subject + '&body=' + em_body ;

 ShellExecute(Handle,'open',
   PChar(em_mail), nil, nil, SW_SHOWNORMAL);
end;

Let me know if you have other questions... Hope these examples help



0
 

Author Comment

by:graga
ID: 7025790
Hi Experts,

I'm just going now through your suggestions. I'll explain the scenario further:

I have a small menu system that can execute a number of different programs, both DOS and Windows.

When I select a program from the menu, this program is started.

When I select a program that has already been started, I want to find the program and bring it to front, rather than starting a new instance of the program.

To maintain a list of programs I have started, I keep a list of process ID's in a simple TList holding:

ProcessList: TList;

PProcess: ^AProcess
AProcess = record
           MenuOption: string;
           ProcessID: DWORD
           end;

Now, when a menu item is selected, I loop through my ProcessList looking for MenuOption selected.
When it is not there, I start the program.
If found, I check if the process is still running.
If running, I want to bring it to front, otherwise I remove entry from list, start the process and add the process to the list again.

So, my question summarises what I want to do:
- Start application
- Get some information from started application that I can use to activate it
- Activate application using the above information.

I hope this clarifies the problem.

I will raise points for working example.

graga
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9006100
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from ginsonic

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9010326
Thankyou for your response

Paul (pnh73)
EE Cleanup Volunteer
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses
Course of the Month8 days, 12 hours left to enroll

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question