Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Triggering an .exe file from a TreeView. 1

Status
Not open for further replies.

delphiman

Programmer
Dec 13, 2001
422
ZA
Can anyone pleasehelp with the code needed in a TreeView whereby
a click on a branch will trigger an .exe file?
 
use:

WinExec('c:\myFile\myprogram.exe',sw_show);

Regards S. van Els
SAvanEls@cq-link.sr
 
Thanks!
I used the code you suggested in the UponDoubleClick of the TreeView window - and it works. But I need to trigger a different .exe for eachBranch of the TreeView. Depending upon which Branch I click on. How can I acheive that?
 
I have done something similar where I needed to show an Autocad dwf file in an active X control.
I created a List of Records and used the treeview.Item.AddObject to attach the record to a node. One of the fields in the record is the file name, so that can be passed to WinExec. S. van Els
SAvanEls@cq-link.sr
 
I've used approaches similar to svanels, creating a custom record type to maintain the name displayed in the tree view, as well as the path to the the target file.

I would caution, though, to use createProcess or shellExecute instead of winExec. WinExec was the windows 3.x way of doing things and has been replaced by createProcess. Microsoft has said that WinExec will go away at some point and this could impact the long term maintenance of your application.

CreateProcess lets you create an application that more fully supports Windows NT, 2000 and so on. For example, you can specify the security attributes and so on.

CreateProcess, though, can be a bit confusing. There's an interesting discussion can be found at and there are other tidbits located in common places on the 'Net.

ShellExecute is documented in the Win32 SDK help file and may be a more appropriate approach, especially if you're considering porting your application to Kylix at some point.

Hope this helps...

-- Lance
 
Thanks for the hint Footpad, can you elaborate a little more the CreateProcess mechanism, it is indeed confusing.

To DelphiMan, your question put me to work, I needed to implement a similar thing, but I was just to lazy to look it up. My construction ended this way:


procedure TMainFrm.PIDs1Click(Sender: TObject);
var
PIDView : string;
pFile : pchar;
begin
PIDVIEW := ExtractFilePath('MainProgram.Exe') + 'pidview.exe';
if not (Fileexists(PIDVIEW)) then
ShowMessage('PidView not Found')
else
begin
pFile := StrNew(PChar(PIDVIEW));
ShellExecute(0,nil,pFile,'',nil,sw_shownormal);
StrDispose(pFile);
end;
end;

Don't forget to include the ShellAPi unit

Regards S. van Els
SAvanEls@cq-link.sr
 
svanels,

Sure, though that URL I referred to contains some useful info, too. You should also take time to pore through the documentation in the Win32 SDK Help file provided with Delphi. There are some important caveats discussed there, such as what's needed under NT, etc.

Here's a wrapper function I used to launch .EXE's using createProcess. Note that it's based on Pat Richey's variant, though I think I tweaked things a bit for the project I was working on.

Code:
function execWait( strFile, strPath, strOpts : String ) : Boolean;
{ ---------------------------------------------------------------
  Executes an external program and waits for it to exit.  The
  parameters are:

  -- strFile: The name of the program to execute
  -- strPath: The directory to use.
  -- strOpts: Any command line options needed.

  The return value indicates whether or not the application executed and
  completed sucessfully (TRUE) or not (FALSE).  If an error occurs, it's
  displayed here.

  Please note that this implementation is based on Pat Richey's
  WinExecAndWait32, as posted to several newsgroups over the past
  couple of years; for more info, search groups.google.com
  --------------------------------------------------------------- }
var
  si : tStartupInfo;         { Startup info for spawned process }
  pi : tProcessInformation;  { Process handle for spawned process }
  dwRetval : dWORD;          { Return value from createProcess }
begin

  { Initialize the startup info record }
  fillChar( si, sizeOf( si ), #0 );
  with si do
  begin
     cb := Sizeof( StartupInfo );
     dwFlags := STARTF_USESHOWWINDOW;
     wShowWindow := sw_ShowNormal;
  end; { with }

  { try to launch the application }
  if not createProcess( nil, pchar( strPath + strFile + ' ' + strOpts ), nil,
                        nil, FALSE, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                        nil, pchar( strPath ), si, pi ) then
     begin
        dwRetval := getLastError;  { save system error info }

        { display interpreted error }
        msgError( 'Can''t Run Program',
                  'Reason: ' + sysErrorMessage( dwRetval ) + #10#10 +
                  'File: "' + strFile + '"' + #10 +
                  'Path: "' + strPath + '"' + #10 +
                  'Opts: "' + strOpts + '"' );
        result := FALSE;  { trigger offer to cancel remaining items }
     end
  else
     begin
        repeat
           application.processMessages;  { wait }
        until ( WaitforSingleObject( pi.hProcess, 500 ) <> WAIT_TIMEOUT );
        GetExitCodeProcess( pi.hProcess, dwRetval ); { saved for future use }
        CloseHandle( pi.hProcess );  { clean up }
        CloseHandle( pi.hThread );
        result := TRUE;
     end;

The idea, here, is to launch some target application and wait for it to finish executing. Note that the parameters are validated before the function gets called, so there's little error checking on those.

I used this as a starting place for installing multiple software products from a CD with minimal user input. In creating that, I found I needed some variations depending on the installation file. For example, Installshield projects need to be started with the -SMS switch for this to work.

This seems to work decently on NT, though YMMV.

I should also mention that the reference to MsgError() in the above refers to a wrapper function I use for various incarnations of the MessageBox() API function. Details on that wrapper can be found at though the article itself is designed to illustrate the overload and parameter default features added to Delphi 4.0.

Hope this helps...

-- Lance
 
Many thanks Footpad, the phrase Executes an external program and waits for it to exit. cleared it for me. S. van Els
SAvanEls@cq-link.sr
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top