免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Delphi實(shí)現(xiàn)窗體內(nèi)嵌其他應(yīng)用程序窗體

[代碼]Delphi實(shí)現(xiàn)窗體內(nèi)嵌其他應(yīng)用程序窗體

實(shí)現(xiàn)原理是啟動一個(gè)應(yīng)用程序,通過ProcessID得到窗體句柄,然后對其設(shè)定父窗體句柄為本程序某控件句柄(本例是窗體內(nèi)一個(gè)Panel的句柄),這樣就達(dá)成了內(nèi)嵌的效果。

本文實(shí)現(xiàn)的是內(nèi)嵌一個(gè)記事本程序,如下圖:

在實(shí)現(xiàn)細(xì)節(jié)上需要注意幾點(diǎn)

  1. 為了美化程序的嵌入效果,需要隱藏其標(biāo)題欄
  2. 在外部窗體大小變化時(shí),需要內(nèi)嵌的窗體也隨之變化大小
  3. 外部程序退出時(shí),內(nèi)嵌的程序也要退出

下面是例子程序。新建窗體,上面放置一個(gè)Panel控件,名為pnlApp,然后按下面代碼編寫:

unit frmTestEmbedApp;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;
 
type
 
  TForm1 = class(TForm)
    pnlApp: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormResize(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  hWin: HWND = 0;
 
implementation
 
{$R *.dfm}
 
type
  // 存儲窗體信息
  PProcessWindow = ^TProcessWindow;
  TProcessWindow = record
    ProcessID: Cardinal;
    FoundWindow: hWnd;
  end;
 
// 窗體枚舉函數(shù)
 
function EnumWindowsProc(Wnd: HWND; ProcWndInfo: PProcessWindow): BOOL; stdcall;
var
  WndProcessID: Cardinal;
begin
  GetWindowThreadProcessId(Wnd, @WndProcessID);
  if WndProcessID = ProcWndInfo^.ProcessID then begin
    ProcWndInfo^.FoundWindow := Wnd;
    Result := False;                                    // 已找到,故停止 EnumWindows
  end
  else
    Result := True;                                     // 繼續(xù)查找
end;
 
// 由 ProcessID 查找窗體 Handle
 
function GetProcessWindow(ProcessID: Cardinal): HWND;
var
  ProcWndInfo: TProcessWindow;
begin
  ProcWndInfo.ProcessID := ProcessID;
  ProcWndInfo.FoundWindow := 0;
  EnumWindows(@EnumWindowsProc, Integer(@ProcWndInfo)); // 查找窗體
  Result := ProcWndInfo.FoundWindow;
end;
 
// 在 Panel 上內(nèi)嵌運(yùn)行程序
 
function RunAppInPanel(const AppFileName: string; ParentHandle: HWND; var WinHandle: HWND): Boolean;
var
  si: STARTUPINFO;
  pi: TProcessInformation;
begin
  Result := False;
 
  // 啟動進(jìn)程
  FillChar(si, SizeOf(si), 0);
  si.cb := SizeOf(si);
  si.wShowWindow := SW_SHOW;
  if not CreateProcess(nil, PChar(AppFileName), nil, nil, true,
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, si, pi) then Exit;
 
  // 等待進(jìn)程啟動
  WaitForInputIdle(pi.hProcess, 10000);
 
  // 取得進(jìn)程的 Handle
  WinHandle := GetProcessWindow(pi.dwProcessID);
  if WinHandle > 0 then begin
    // 設(shè)定父窗體
    Windows.SetParent(WinHandle, ParentHandle);
 
    // 設(shè)定窗體位置
    SetWindowPos(WinHandle, 0, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOZORDER);
 
    // 去掉標(biāo)題欄
    SetWindowLong(WinHandle, GWL_STYLE, GetWindowLong(WinHandle, GWL_STYLE)
      and (not WS_CAPTION) and (not WS_BORDER) and (not WS_THICKFRAME));
 
    Result := True;
  end;
 
  // 釋放 Handle
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // 退出時(shí)向內(nèi)嵌程序發(fā)關(guān)閉消息
  if hWin > 0 then PostMessage(hWin, WM_CLOSE, 0, 0);
end;
 
procedure TForm1.FormCreate(Sender: TObject);
const
  App = 'C:\Windows\Notepad.exe';
begin
  pnlApp.Align := alClient;
 
  // 啟動內(nèi)嵌程序
  if not RunAppInPanel(App, pnlApp.Handle, hWin) then ShowMessage('App not found');
end;
 
procedure TForm1.FormResize(Sender: TObject);
begin
  // 保持內(nèi)嵌程序充滿 pnlApp
  if hWin <> 0 then MoveWindow(hWin, 0, 0, pnlApp.ClientWidth, pnlApp.ClientHeight, True);
end;
 
end.

這種方式也存在幾個(gè)問題:

問題1:如果程序有Splash窗體先顯示,則實(shí)際窗體無法內(nèi)嵌,因?yàn)閮H將Splash窗體的父窗體設(shè)定為本程序的控件句柄,后續(xù)窗體無法設(shè)定。

解決方法:可以通過輪詢方式查詢后續(xù)窗體,并設(shè)定其父窗體為本程序的控件句柄。

問題2:點(diǎn)擊內(nèi)嵌程序的窗體,則本程序的標(biāo)題欄失去焦點(diǎn)

解決方法:不詳。

問題3:點(diǎn)擊內(nèi)嵌程序的窗體,按下ALT+F4,則內(nèi)嵌程序退出,僅留下本程序

解決方法:可以通過Hook方式攔截ALT+F4。

愛生活,愛拉風(fēng)
分類: Delphi

博主后一篇:[筆記]如何屏蔽視頻網(wǎng)站的片頭廣告——優(yōu)酷
posted @ 2011-07-21 23:48 ET民工[源自火星] 閱讀(1169) 評論(12) 編輯 收藏
#1樓 2011-08-15 13:39 vcc  

請教 ET民工
我若改執(zhí)行其他exe
1.
'C:\Windows\system32\mspaint.exe';
'C:\Windows\system32\calc.exe';
加sleep(500) 還可以include 進(jìn)來

但'C:\Program Files\Internet Explorer\iexplore.exe';
就有點(diǎn)難

2.我另外自己寫的exe 被include後,在下面的windows的工作列,會像一般exe一樣有ICON 出現(xiàn),這能將他 隱藏嗎?像記事本就不會出現(xiàn)
#2樓[樓主] 2011-08-15 16:06 ET民工[源自火星]  
@vcc
1.
'C:\Windows\system32\mspaint.exe';
'C:\Windows\system32\calc.exe';
加sleep(500) 還可以include 進(jìn)來

但'C:\Program Files\Internet Explorer\iexplore.exe';
就有點(diǎn)難

不建議嵌入IE,建議使用WebBrowser控件

2.我另外自己寫的exe 被include後,在下面的windows的工作列,會像一般exe一樣有ICON 出現(xiàn),這能將他 隱藏嗎?像記事本就不會出現(xiàn)

可以參考這篇文章,不過我沒有測試,僅供參考吧:
利用ITaskbarList接口隱藏任務(wù)欄圖標(biāo)
http://blog.csdn.net/3150379/article/details/3169335

#3樓 2011-08-15 17:15 vcc  
感謝指導(dǎo)
2個(gè)方法都未能成功

利用ITaskbarList接口隱藏任務(wù)欄圖標(biāo) 只能隱藏 主程序application.handle


而是要內(nèi)嵌delphi 寫的exe,,
不要讓內(nèi)嵌的exe ICON 出現(xiàn)在下方任務(wù)檔
(利用ITaskbarList接口隱藏任務(wù)欄圖標(biāo))
未能成功

#6樓[樓主] 2011-08-17 11:45 ET民工[源自火星] 
@vcc
如果內(nèi)嵌的程序是你自己寫的,可以將其主窗體直接當(dāng)作外殼程序的子窗體,這樣就沒問題了。我的一個(gè)程序就這么做的,運(yùn)行良好。
或者將內(nèi)嵌的程序修改為運(yùn)行時(shí)不顯示在任務(wù)欄按鈕里,這樣可以達(dá)到目的,當(dāng)然,前提是你可以修改內(nèi)嵌程序的代碼。

#7樓 2011-08-17 12:20 vcc  
1.內(nèi)嵌的程序是自己寫的,但是我要他成為單一exe,而不要為MDI 子視窗方式,,我要用外殼程序 一次遙控多個(gè)同樣的exe,
exe可以同時(shí)同步運(yùn)行,,
MDI子視窗無法實(shí)現(xiàn)同時(shí)同步運(yùn)行

2.最好是 A.像記事本一樣 ,一般exe 內(nèi)嵌後,不顯示在任務(wù)欄按鈕里
(包括任何delphi exe[我內(nèi)嵌他人寫的delphi TILED.exe 也一樣會顯示,所以我懷疑delphi exe 比較特殊])

B.要如何 內(nèi)嵌的程序修改為運(yùn)行時(shí)不顯示在任務(wù)欄按鈕里

#8樓[樓主] 2011-08-17 12:32 ET民工[源自火星]  

我的做法不是使用MDI(MDI已經(jīng)過時(shí)了),如下:
1、外殼程序只做外殼的界面,但是里面有個(gè)PageControl控件,每一頁是一個(gè)子窗體的容器。
2、初始化外殼程序時(shí),讀取配置文件,初始化每個(gè)子窗體程序
3、外殼程序可以通過Notify模式和子窗體交互,說白了就是雙向廣播
4、子窗體因?yàn)槭荈orm級的被調(diào)用,所以和主窗體是完整的一個(gè)程序,不存在多余進(jìn)程

以上的基礎(chǔ)是,外殼和子窗體都是Delphi程序,都是源碼級別
#9樓 2011-08-17 13:13 vcc 
外殼將多個(gè)子窗體定義為窗體數(shù)組。
同時(shí)控制,可以通過遍歷數(shù)組每一項(xiàng)來發(fā)送指令和獲取回復(fù)。
外殼程序 用PageControl 將子視窗 分頁管理?
外殼程序 若是sendmessage 給所有子視窗(子視窗內(nèi)的程序是獨(dú)立執(zhí)行緒嗎?)
我的子程式是控制USB,,我利用外殼程序 同時(shí) 同步控制多個(gè)子程序(多個(gè)USB)

我試過MDI 將控制USB作成子Form,,但發(fā)現(xiàn) 只能有單一子視窗運(yùn)作,,
所以往Thread 跟 外殼程序 2方面找資料,,
未嘗試 Thread我的[控制USB](擔(dān)心debug...)
剛好找到了 樓主這篇,,用了幾天 大致都能得到我的預(yù)期需求
現(xiàn)在就是 任務(wù)欄按鈕 會顯示出來 處理不來,,



本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Delphi:實(shí)現(xiàn)無邊界窗體的移動
Delphi融合DLL中的窗體
第一章 Delphi快速入門(一)
Delphi制作DLL
如何在自己的系統(tǒng)中打開并關(guān)閉外部程序
DELPHI的美化插件VCLskin5.6
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服