內嵌第三方EXE程式視窗

2021-07-04 11:08:02 字數 2695 閱讀 8116

近日,在做乙個將乙個第三方應用視窗嵌入自己的程式視窗內部的功能,經過幾次摸索,終於能比較好的嵌入進去了,為方便敘述,以下稱需要被嵌入應用視窗為目標視窗,承載嵌入應用視窗的為宿主視窗,目標視窗為任意第三方應用,宿主視窗為自己開發。

將目標視窗完美嵌入,關鍵在於將目標視窗做為宿主視窗的子視窗,這樣作業系統就會幫我們完成移動,繪製等操作,為目標視窗設定父視窗,也很簡單,呼叫乙個api即可:

hwnd setparent(      

hwnd hwndchild,

hwnd hwndnewparent

);

第乙個引數是子視窗的控制代碼,也即目標視窗的控制代碼,第二個視窗為我們想設定的目標視窗的父視窗,即宿主視窗,由於宿主視窗的程式為自己開發,要拿到這個控制代碼就很簡單,關鍵在於如何找到目標視窗的控制代碼。

找到目標視窗的控制代碼,也有乙個api:

hwnd findwindow(      

lpctstr lpclassname,

lpctstr lpwindowname

);

第乙個引數為視窗的類名,建立視窗之前,首先需要使用registerclass向系統註冊乙個視窗類wndclass,這個結構體中有個lpszclassname欄位,就代表這個視窗類的名稱。第二個引數為目標視窗的標題。具體這兩個值多少,可以使用vs自帶的spy++工具,檢視下目標視窗,就能獲得。

下面分步驟,結合**,詳細展示下整體流程。

這個可以通過響應wm_ctlcolor訊息,並返回乙個透明畫刷完成,**很簡單如下:

hbrush cdlgmainintelligent::onctlcolor(cdc* pdc, cwnd* pwnd, uint nctlcolor)

這裡又分為兩種情景,一種是第三方應用尚未啟動,需要我們自己去啟動,並等待其啟動完成後,查詢其視窗控制代碼,另一種情形是第三方應用已啟動,這樣可以直接去查詢視窗控制代碼。如何區分這兩種情形,很簡單,先去查詢下視窗,如果能找到就證明已啟動,否則就去啟動下。

啟動應用程序可以使用createprocess,這裡有個問題,如何判斷這個程序已經啟動好了呢?可以使用

dword winapi waitforinputidle(

__in handle hprocess,

__in dword dwmilliseconds

);

不過這個僅僅是判斷程序啟動好,有可能主視窗還沒建立完成,也有可能第三方程式崩了,壓根拿不到。試過幾種方法,都不太理想,我採用了最簡單有效的方法,就是迴圈探測等待,並設定超時時間,具體看**,我封裝了乙個函式,可以拿到第三方程序的控制代碼及主視窗控制代碼。

hwnd getivawindowandprocess(handle& hprocess)

closehandle(pi.hthread);

waitforinputidle(pi.hprocess,infinite);

hprocess = pi.hprocess;

while((hwnd = ::findwindow("***xclient3",null)) == null && nnumberdely > 0)

}else

return hwnd;

}

通過以上函式,就能拿到控制代碼了。接下來就可以設定其父視窗了。

前面說過,將第三方視窗設定為子視窗,移動繪製這些我們不用管了,系統會幫忙完成,不過wm_size是需要我們處理的,有了視窗控制代碼,這個也變得很簡單。只要在onsize裡面呼叫movewindow即可

void cdlgmainintelligent::onsize(uint ntype, int cx, int cy)

if(!iswindow(getsafehwnd()))

if(!m_bisinit)

crect rect;

getclientrect(&rect);

if(m_hivawnd != null && !m_bisattached)

if(m_hivawnd)

}

好的體驗就是,目標視窗完全做為宿主視窗的一部分,同生共死,因此當宿主視窗銷毀的時候,目標視窗也要一併銷毀。這個也很簡單,只要在宿主視窗的onclose中做處理即可。

void cdlgmainintelligent::onclose()

if(m_hivaprocess != null)

cdetachdlg::onclose();

}

經過這樣處理,基本能完美嵌入第三方應用的主視窗了。

另外還有一些細節上的體驗,一般第三方應用視窗,也是有自己的最大最小化按鈕的,需要把這個遮蔽掉,否則看起來不美觀。我使用的方法是,向第三方應用注入乙個dll,在該dll中建立乙個小視窗,把應用視窗的右上角遮擋住。這樣介面看起來就非常統一和協調了。

注入dll的**就是windows核心程式設計上的,沒什麼好說的,如下:

bool cdlgmainintelligent::injecthookdll(handle hprocess)

pcwstr pszlibfile = l"msghookdll.dll";

if(hprocess != null)

return false;

}

C 內嵌第三方EXE程式視窗

近日,在做乙個將乙個第三方應用視窗嵌入自己的程式視窗內部的功能,經過幾次摸索,終於能比較好的嵌入進去了,為方便敘述,以下稱需要被嵌入應用視窗為目標視窗,承載嵌入應用視窗的為宿主視窗,目標視窗為任意第三方應用,宿主視窗為自己開發。將目標視窗完美嵌入,關鍵在於將目標視窗做為宿主視窗的子視窗,這樣作業系統...

WPF應用程式嵌入第三方exe

思路是,第一步 在自己的應用程式中準備顯示第三方控制項的容器,border,grid什麼的都可以,下面是觸發 private void button click object sender,routedeventargs e 第二步 編寫啟動第三方exe的類,主要是獲取第三方窗體的控制代碼,這裡需要...

第三方登入

我的應用就可以通過token第三方應用獲取一些基本資訊了,我的應用在獲取到這些基本資訊之後,就可以在我的應用中建立乙個賬號了。下次使用地方登入獲取到的這些使用者資訊,就可以直接用來登入我的應用了。為什麼先返回code呢?這個返回的code只能夠使用一次。這個code是從qq的伺服器返回給 時,我們時...