启动程序并使用现有程序Delphi 2010进行停靠
发布时间:2020-12-15 09:06:06 所属栏目:大数据 来源:网络整理
导读:在Delphi 2010中是否有办法使用 ShellExecute启动应用程序然后将该应用程序停靠在另一个应用程序中? 即用Delphi编写的程序A包含1个表单.当显示表单时,用C#编写的程序B启动并将客户端停靠到程序A的表单中? 保罗 解决方法 是的,你可以这样做.您需要在另一个
在Delphi 2010中是否有办法使用
ShellExecute启动应用程序然后将该应用程序停靠在另一个应用程序中?
即用Delphi编写的程序A包含1个表单.当显示表单时,用C#编写的程序B启动并将客户端停靠到程序A的表单中? 保罗 解决方法
是的,你可以这样做.您需要在另一个进程中获取主窗体的窗口句柄(调用
EnumWindows ).然后调用
SetParent 使该窗口成为窗口的子窗口.
您可能希望修改窗口样式,位置等.在尝试在新进程中查找窗口句柄之前,还要调用 你现在拥有的是一个非常奇怪的野兽.在一个容器内,您有两个进程.每个进程都有自己的UI线程.您可以一次显示两个模态对话框并与之交互.你可以拥有的乐趣真是无止境! 编辑 只是为了一点乐趣,我开始编写一个简单的Delphi应用程序来完成这项工作.它相当脆弱,似乎只适用于非常基本的应用程序.我想你可能会花很长时间努力使这项工作做得很好,但结果仍然不尽如人意.如果我是你,我会寻找其他解决方案,特别是当你拥有这个C#应用程序的源代码时.当然,您可以将其功能公开为ActiveX? 无论如何,为了您的娱乐,我提供以下非常不完美的代码: program AppHost; uses Windows,Messages,SysUtils,Forms,Controls,ComCtrls; {$R *.res} procedure ResizePage(Page: TTabSheet); var hwnd: Windows.HWND; Rect: TRect; begin hwnd := Page.Tag; Rect := Page.ClientRect; MoveWindow(hwnd,Rect.Left,Rect.Top,Rect.Right-Rect.Left,Rect.Bottom-Rect.Top,True); end; type PEnumData = ^TEnumData; TEnumData = record ProcessID: DWORD; hwnd: HWND; end; function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall; var ProcessId: DWORD; EnumData: PEnumData; begin EnumData := PEnumData(lParam); GetWindowThreadProcessId(hwnd,ProcessId); if EnumData.ProcessID=ProcessID then begin EnumData.hwnd := hwnd; Result := False; exit; end; Result := True; end; procedure Absorb(PageControl: TPageControl; const App: string; StartupInfo: TStartupInfo); var Page: TTabSheet; ProcessInformation: TProcessInformation; EnumData: TEnumData; begin Page := TTabSheet.Create(PageControl); Page.PageControl := PageControl; Page.Caption := ChangeFileExt(ExtractFileName(App),''); CreateProcess(PChar(App),nil,False,StartupInfo,ProcessInformation); WaitForInputIdle(ProcessInformation.hProcess,INFINITE); EnumData.ProcessID := ProcessInformation.dwProcessId; EnumData.hwnd := 0; EnumWindows(@EnumWindowsProc,LPARAM(@EnumData)); Page.Tag := Integer(EnumData.hwnd); SetParent(HWND(Page.Tag),Page.Handle); ResizePage(Page); end; type TEventProvider = class private FForm: TForm; FPageControl: TPageControl; procedure FormResize(Sender: TObject); public constructor Create(Form: TForm; PageControl: TPageControl); end; { TEventProvider } constructor TEventProvider.Create(Form: TForm; PageControl: TPageControl); begin inherited Create; FForm := Form; FPageControl := PageControl; FForm.OnResize := FormResize; end; procedure TEventProvider.FormResize(Sender: TObject); var i: Integer; begin for i := 0 to FPageControl.PageCount-1 do begin ResizePage(FPageControl.Pages[i]); end; end; procedure Main(Form: TForm); var StartupInfo: TStartupInfo; PageControl: TPageControl; begin Form.ClientHeight := 600; Form.ClientWidth := 800; Form.Caption := 'All your processes are belong to us'; PageControl := TPageControl.Create(Form); PageControl.Parent := Form; PageControl.Align := alClient; StartupInfo.cb := SizeOf(StartupInfo); GetStartupInfo(StartupInfo); Absorb(PageControl,'C:WindowsNotepad.exe',StartupInfo); Absorb(PageControl,'C:Program FilesCommandLinedepends.exe',StartupInfo); TEventProvider.Create(Form,PageControl); end; var Form: TForm; begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm,Form); Main(Form); Application.Run; Form.Free; end. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |