If you leave your web address and email address in your software, you will definitely hope that people will start the browser or email software. This is actually how to start external software, very simple, isn't it? However, if I ask you, how to start the external program and wait for it to end, can you tell me?
In fact, this is a topic of "ancient" and is discussed in the Win95 era. However, since there are so many people don't know, I feel still necessary to discuss it.
First, why start the external program
Perhaps you want your program to complete all features. However, no matter from material or human, you should develop habits of resource sharing. Better considerations are to make full use of existing procedures, and let your program focus on a certain aspect. For example, the browser is responsible for opening the web, letting people browse, when you encounter the downloaded task, you can give more professional download software to do. You may also leave your homepage and email address in your program, you want someone to start browsers and emails separately when they click them. In some cases, after you need an external program to process, you will perform the next step, and you will encounter the problem that starts the external program and waits it.
Second, prepare knowledge
Start external programs We can use functions Winexec, Shellexecute, and ShellexecuteEx. I recommend you to use the function shellexecute because it is flexible and simple. Take a look at the example below, the usage is clear:
*: Start a program
Shellexecute (Handle, 'Open', PCHAR ('c: /test/app.exe'),
NIL, NIL, SW_SHOW;
* Start a notepad (because the notepad is under the system path, so you don't have to write a complete path name):
Shellexecute (Handle, 'Open', Pchar ('Notepad'),
NIL, NIL, SW_SHOW;
* Start the notepad and load a plain text file:
Shellexecute (Handle, 'Open', Pchar ('Notepad'),
Pchar ('c: /te/readme.txt', nil, sw_show);
* Use Notepad to open a plain text file (please determine the * .txt file is associated with Notepad):
Shellexecute (Handle, 'Open', Pchar ('C: /Test/Readme.txt'),
NIL, NIL, SW_SHOW;
* Open URL using the default browser:
Shellexecute (Handle, 'Open', Pchar ('http://www.festra.com/'),
NIL, NIL, SW_SHOW;
* Print a file:
Shellexecute (Handle, 'Print', Pchar ('c: /test/readme.txt'),
NIL, NIL, SW_SHOW;
* Open a folder with Windows Explorer:
Shellexecute (Handle, 'Explore', Pchar ('C: / Windows)',
NIL, NIL, SW_SHOW;
* Run a DOS command and return immediately:
Shellexecute (Handle, 'Open', Pchar ('Command.com'),
PCHAR ('/ c copy file1.txt file2.txt'), nil, sw_show;
* Run a DOS command and keep the DOS window to open ("Stay in dos"): Shellexecute (Handle, 'Open', PCHAR ('Command.com'),
PCHAR ('/ K DIR'), NIL, SW_SHOW;
It's not difficult to start an external program? However, how do we know if it is running? How do our programs waiting to end?
Third, start the external program and wait for the function it end
We can view processes (programs) over process handle (program) end. In order to get a process handle, two Win32 API functions can be used: ShellexecuteEx or createProces. The simplest way to solve this problem is to launch an external program using ShellexecuteEx and use WaitForsingleObject to manage the process handle of this external program. We can define a function like this:
......
{EXECAPPWAIT: Function: Run external programs and wait for it to end. .
Run external program appname, parameter params;
Returns: If an external program error returns FASLE
}
Function Execappwait (Appname, Params: String): boolean
......
Function Execappwait (Appname, Params: String): boolean
VAR
// structure containing and receiving info about coplication to start
ShellexInfo: TshellexecuteInfo;
Begin
Fillchar (Shellexinfo, Sizeof (ShellexInfo), 0);
With shellexinfo do begin
CBSIZE: = Sizeof (ShellexInfo);
Fmask: = see_mask_nocloseprocess;
WND: = Application.handle;
LPFILE: = PCHAR (AppName);
LPParameters: = pchar (params);
NSHOW: = sw_shownormal;
END;
Result: = shellexecuteEx (@SHELLEXINFO);
IF results
While WaitforsingleObject (ShellexInfo.hprocess, 100) = Wait_Timeout Do
Begin
Application.ProcessMESSAGES;
IF Application.Terminated Then Break;
END;
END;
......
Not difficult to understand?
Create a Unit Execwait to enter the above code.
Four, example
Established FORM as shown, the source program is as follows:
UNIT Demounit;
Interface
Uses
Windows, Messages, Sysutils, Classes, Graphics, Controls,
Forms, Dialogs, Stdctrls, Shellapi;
Type
TFORM1 = Class (TFORM)
EDIT1: TEDIT;
EDIT2: TEDIT;
Label1: TLABEL;
Label2: TLABEL;
BTNEXEC: TBUTTON
Checkboxwait: tcheckbox;
Label3: TLABEL;
Label4: TLABEL;
EDIT3: TEDIT;
EDIT4: TEDIT;
Label5: TLABEL;
Procedure Btnexecclick (Sender: TOBJECT);
Private
{Private Declarations}
public
{Public declarations}
END;
VAR
FORM1: TFORM1;
IMPLEMENTATION
Uses
EXECWAIT;
{$ R * .dfm}
Procedure TFORM1.BTNEXECCLICK (Sender: TOBJECT);
VAR
Success: boolean;
Thandi;
Begin
{Minimize window, reminded changes}
Application.minimize;
Success: = false;
Try
If checkboxwait.checked kil
Success: = execappwait (edit1.text, edit2.text)
Else Begin
InstanceId: = shellexecute (Handle, 'Open', PCHAR (Edit1.Text),
Pchar (edit2.text), NIL, SW_SHOW;
Success: = instanceID> = 32; // less than 32 can be wrong
END;
Finally
// Don't forget the window of restoring our programs!
Application.Restore;
IF not success
ShowMessage ('Application 1 Failed:' Edit1.Text ' Edit2.Text);
END;
Try
If checkboxwait.checked kil
Success: = execappwait (edit3.text, edit4.text)
Else Begin
InstanceId: = shellexecute (Handle, 'Open', PCHAR (Edit3.Text),
Pchar (edit4.text), NIL, SW_SHOW;
Success: = instanceID> = 32; // less than 32 can be wrong
END;
Finally
// Restore our program's window
Application.Restore;
IF not success
ShowMessage ('Application 2 Failed:' Edit3.Text '' Edit4.Text);
END;
END;
End.
OK, no problem? You try it, apply it to your program. #