This is my discussion in a forum. I think these situations will often encounter during the practical program design process, so I wrote these discussion information:
Author: e Meng Yuan
?
How can I run an external EXE and return it? WINEXEC returns a Handleshellexecute, shellexecuteEx, is not createProcess, how can I return to the same handle or the same handle returned to getWindow?
RE:
You can use the findwindow () function, it can solve this problem, it has two parameters: lpClassName: The class name of the program; LPWindowname: The title of the program form.
E.g:
Procedure TForm1.Button1Click (Sender: Tobject); BeginsHellexecute (Handle, 'Open', 'NIL, SW_SHOWNORMAL);
Procedure TForm1.Button2Click (Sender: Tobject); VAREXEHANDLE: THANDLE; begin // Get handle ExeHandle: = FINDWINDOW ('NOTEPAD', NIL); // '); // Return Handle // Close Program IF EXEHANDE <> 0 ThensendMessage (ExeHandle, WM_Close, 0, 0.0) elseApplication.MessageBox ('did not open "Notepad" program!', 'prompt', MB_ICONITIONMATION MB_OK);
The FindWindow () method is not what I want, because the lpwindowname here is uncertain, there is no way to find accurately. I hope to get its handle in the implementation of this external program. For example, if there is any way, get it has Application Handle and MainForm Handle through Process Handle.
RE:
You can find it through the LPClassName: The class name of the program is accurately found.
ExeHandle: = FindWindow ('NOTEPAD', NIL); // Returns Handle
Function Executefile (const filename, params, defaultdir: string;
Showcmd: integer: thandle;
VAR
ZFileName, Zparams, ZDIR: Array [0..79] of char;
Begin
Result: = shellexecute (Application.mainform.handle, NIL,
Strpcopy (ZFileName, FileName), Strpcopy (Zparams, Params),
Strpcopy (zdir, defaultdir), showcmd;
END;
Procedure TForm1.Button3Click (Sender: TOBJECT); VARHWD: THANDE; Begin
HWD: = executefile ('Notepad.exe', '', '', sw_shownormal); if hwd <> 0 Then ShowMessage ('Haha ~~' # 13 'I get to Handle, YES >>>' INTOSTR (HWD));
END;
?
Thank you for your enthusiasm, but Shellexecute is not Handle to get the true handle. You can try it. The easiest way is to send a WM_QUIT message to you get it, see if it will be closed. Such as : SendMessage (Ahandle, Wm_quit, 0, 0);
RE:
I have read a lot of Delphi's information, as if only the FindWindow () function is achievable, as far as there is other way, I don't know much!
final result:
I have been satisfied from the Daxion Forum, and share it with you: (Daxion Forum: http://www.delphibbs.com/)
TYPEPENUMINFO = ^ TenumInfo; TenumInfo = RecordProcessID: DWORD; HWND: THANDLE;
function EnumWindowsProc (Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall; varPID: DWORD; beginGetWindowThreadProcessID (Wnd, @PID); Result: = (PID <> EI.ProcessID) or (not IsWindowVisible (WND)) or ( NOT ISWINDOWENABLED (WND));
IF NOT RESULT THEN EI.HWND: = WND;
Function FindMainWindow (PID: DWORD): DWORD; VAREI: TenumInfo; Beginei.ProcessId: = PID; Ei.hWnd: = 0; EnumWindows (@EnumWindowsProc, Integer); result: = ei.hwnd;
Procedure TForm1.Button1Click (Sender: TOBJECT); VARSI: TSTARTUPINFO; PI: TPROCESSINFOPINFO; PI: TPROCESSINFORMATION; H: THANDLE; S: String; BeginzeromeMory; ZeromeMory (@PI, SIZEOF (PI)); Si. CB: = SizeOf (Si); if CreateProcess (NIL, 'Calc.exe', NIL, NIL, FALSE, 0, NIL, NIL, SI, PI) THENBEGIN / / Note! WaitforInputIdle (Pi.hProcess, Infinite);
H: = FindmainWindow; IF H> 0 Thenbeginsetlength (s, 255); getWindowText (h, pchar (s), 255); setlength (s, strlen (pchar (s)); showMessage (s) ;
CloseHandle (Pi.hprocess); CloseHandle (PI.hthread); end; end; end.