delphi – 如何从我的GUI应用程序启动控制台窗口的处理?
在我的GUI应用程序中,我运行控制台应用程序,需要其窗口的处理.我尝试使用Enum Windows(),看下面的代码,但它不起作用.在列表中没有我的控制台应用程序
1 type 2 TEnumWindowsData = record 3 ProcessId: Cardinal; 4 WinHandle: THandle; 5 List: TStrings; // For test only 6 end; 7 PEnumWindowsData = ^TEnumWindowsData; 8 9 function FindWindow(hWnd: THandle; lParam: LPARAM): BOOL; stdcall; 10 var 11 ParamData: TEnumWindowsData; 12 ProcessId: Cardinal; 13 WinTitle: array[0..200] of Char; // For test only 14 begin 15 ParamData := PEnumWindowsData(lParam)^; 16 GetWindowThreadProcessId(hWnd,ProcessId); 17 if ProcessId <> ParamData.ProcessId then 18 Result := True 19 else begin 20 ParamData.WinHandle := hWnd; 21 Result := False; 22 end; 23 // For test only 24 GetWindowText(hWnd,WinTitle,Length(WinTitle) - 1); 25 ParamData.List.Add(IntToStr(ProcessId) + ' ' + IntToStr(hWnd) + ' ' + WinTitle); 26 end; 27 28 procedure TForm1.Button1Click(Sender: TObject); 29 30 function RunApp(const AProgram: string): Cardinal; 31 var 32 StartupInfo: TStartupInfo; 33 ProcessInformation: TProcessInformation; 34 begin 35 Result := 0; 36 ... 37 if CreateProcess(nil,PChar(AProgram),nil,False,NORMAL_PRIORITY_CLASS,StartupInfo,ProcessInformation) 38 then 39 Result := ProcessInformation.dwProcessId; 40 ... 41 end; 42 43 var 44 ParamData: TEnumWindowsData; 45 begin 46 ParamData.ProcessId := RunApp('cmd.exe /C D:\TMP\TEST.exe'); 47 ParamData.WinHandle := 0; 48 ParamData.List := Memo1.Lines; 49 EnumWindows(@FindWindow,THandle(@ParamData)); 50 51 FWindowHandle := ParamData.WinHandle; 52 end;
解决方法
以下代码只是创建进程(控制台应用程序),将您的进程通过
AttachConsole功能附加到新创建的控制台,并从该连接的控制台使用 GetConsoleWindow功能使用窗口句柄.
以下代码最大的缺点是CreateProcess函数在此时立即返回,当控制台尚未完全初始化时,当您尝试立即附加控制台后,您将失败.不幸的是,没有WaitForInputIdle功能for console applications,所以作为一种可能的解决办法,我会选择尝试在一些有限的循环计数中附加控制台,一旦成功,获取句柄并分离控制台.
在代码中可能如下所示. RunApp函数应该返回控制台窗口的句柄(假设您只能运行控制台应用程序),并且应该等待大约. 1秒钟的控制台应用程序你开始可以附加.您可以通过更改尝试变量的初始值和/或更改睡眠间隔来修改此值.
1 function GetConsoleWindow: HWND; stdcall; 2 external kernel32 name 'GetConsoleWindow'; 3 function AttachConsole(dwProcessId: DWORD): BOOL; stdcall; 4 external kernel32 name 'AttachConsole'; 5 6 function RunApp(const ACmdLine: string): HWND; 7 var 8 CmdLine: string; 9 Attempt: Integer; 10 StartupInfo: TStartupInfo; 11 ProcessInfo: TProcessInformation; 12 begin 13 Result := 0; 14 FillChar(StartupInfo,SizeOf(TStartupInfo),0); 15 FillChar(ProcessInfo,SizeOf(TProcessInformation),0); 16 StartupInfo.cb := SizeOf(TStartupInfo); 17 StartupInfo.dwFlags := STARTF_USESHOWWINDOW; 18 StartupInfo.wShowWindow := SW_SHOWNORMAL; 19 CmdLine := ACmdLine; 20 UniqueString(CmdLine); 21 if CreateProcess(nil,PChar(CmdLine),CREATE_NEW_CONSOLE,ProcessInfo) then 22 begin 23 Attempt := 100; 24 while (Attempt > 0) do 25 begin 26 if AttachConsole(ProcessInfo.dwProcessId) then 27 begin 28 Result := GetConsoleWindow; 29 FreeConsole; 30 Break; 31 end; 32 Sleep(10); 33 Dec(Attempt); 34 end; 35 CloseHandle(ProcessInfo.hThread); 36 CloseHandle(ProcessInfo.hProcess); 37 end; 38 end;
那么你可以以这种方式更改您的lauched应用程序的控制台窗口的标题:
1 procedure TForm1.Button1Click(Sender: TObject); 2 var 3 S: string; 4 ConsoleHandle: HWND; 5 begin 6 ConsoleHandle := RunApp('cmd.exe'); 7 if ConsoleHandle <> 0 then 8 begin 9 S := 'Hello! I''m your console,how can I serve ?'; 10 SendTextMessage(ConsoleHandle,WM_SETTEXT,S); 11 end; 12 end;
总结
以上是编程之家为你收集整理的delphi – 如何从我的GUI应用程序启动控制台窗口的处理?全部内容,希望文章能够帮你解决delphi – 如何从我的GUI应用程序启动控制台窗口的处理?所遇到的程序开发问题。
如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

浙公网安备 33010602011771号