启动程序并使用现有程序Delphi 2010进行停靠

启动程序并使用现有程序Delphi 2010进行停靠,第1张

概述在Delphi 2010中是否有办法使用 ShellExecute启动应用程序然后将该应用程序停靠在另一个应用程序中? 即用Delphi编写的程序A包含1个表单.当显示表单时,用C#编写的程序B启动并将客户端停靠到程序A的表单中? 保罗 是的,你可以这样做.您需要在另一个进程中获取主窗体的窗口句柄(调用 EnumWindows).然后调用 SetParent使该窗口成为窗口的子窗口. 您可能希望修 在Delphi 2010中是否有办法使用 ShellExecute启动应用程序然后将该应用程序停靠在另一个应用程序中?

即用Delphi编写的程序A包含1个表单.当显示表单时,用C#编写的程序B启动并将客户端停靠到程序A的表单中?

保罗

解决方法 是的,你可以这样做.您需要在另一个进程中获取主窗体的窗口句柄(调用 EnumWindows).然后调用 SetParent使该窗口成为窗口的子窗口.

您可能希望修改窗口样式,位置等.在尝试在新进程中查找窗口句柄之前,还要调用WaitForInputIdle.您必须为新流程提供入门机会.

你现在拥有的是一个非常奇怪的野兽.在一个容器内,您有两个进程.每个进程都有自己的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:\windows\Notepad.exe',StartupInfo);  Absorb(PageControl,'C:\Program files\Commandline\depends.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.
总结

以上是内存溢出为你收集整理的启动程序并使用现有程序Delphi 2010进行停靠全部内容,希望文章能够帮你解决启动程序并使用现有程序Delphi 2010进行停靠所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1216252.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存