2011-03-01 48 views
5

我已經能夠成功地包裝我的非託管Borland C++ dll,並從C#.NET 4.0應用程序啓動它的表單。是否有可能將DLL中的表單直接嵌入到.NET應用程序中?如何將非託管C++表單嵌入到.NET應用程序中?

爲了說明問題,原始表單已被用作Borland C++項目中的嵌入式控件。它基本上看起來像一個自定義控件,坐在應用程序中的一個面板上。

當我說'嵌入'的時候,我的意思是把你的按鈕,面板等放到表單上,放到表單中。我不打算做一個孩子的形式。

如果這是不可能的,那麼或許一個更好的問題是如何將一個unmanged自定義控件嵌入到.Net應用程序中?

+1

您的意思是嵌入爲顯示爲子窗口,還是嵌入到.NET項目中的代碼中? – 2011-03-01 16:52:39

回答

4

是的,你只需要使用user32.dll中的一些低級別的win32函數:SetParent,GetWindowLog,SetWindowLong,MoveWindow。您可以創建一個空的.NET容器控件,將本機窗口的父級設置爲.NET控件,然後(可選)修改窗口樣式(即刪除本機窗口的邊框),並注意將其與.NET控件。請注意,在受管級別,.NET控件將不知道它有任何子級。

在.NET控件這樣做

public void AddNativeChildWindow(IntPtr hWndChild){ 

     //adjust window style of child in case it is a top-level window 
     int iStyle = GetWindowLong(hWndChild, GWL_STYLE); 
     iStyle = iStyle & (int)(~(WS_OVERLAPPEDWINDOW | WS_POPUP)); 
     iStyle = iStyle | WS_CHILD; 
     SetWindowLong(hWndChild, GWL_STYLE, iStyle); 


     //let the .NET control be the parent of the native window 
     SetParent((IntPtr)hWndChild, this.Handle); 
     this._childHandle=hWndChild; 

     // just for fun, send an appropriate message to the .NET control 
     SendMessage(this.Handle, WM_PARENTNOTIFY, (IntPtr)1, (IntPtr)hWndChild); 

} 

然後覆蓋.NET控件的WndProc中,使其適當調整原生形式 - 例如,以填補客戶區。

protected override unsafe void WndProc(ref Message m) 
    { 

     switch (m.Msg) 
     { 
      case WM_PARENTNOTIFY: 
        //... maybe change the border styles , etc 
        break; 
       case WM_SIZE: 
       iWid =(int)((int)m.LParam & 0xFFFF); 
       iHei= (int) (m.LParam) >> 16; 
       if (_childHandle != (IntPtr)0) 
       { 

        MoveWindow(_childHandle, 0, 0, iWid, iHei, true); 

       } 
       break; 

     } 

} 
+0

這確實使本機形式成爲.NET應用程序的子形式之一,但並沒有真正解決在.NET應用程序中「嵌入」窗口的問題。我們似乎完全不同的解釋這個問題。 – 2011-03-01 16:53:34

+0

這個問題毫無疑問含糊不清。 – 2011-03-01 16:56:05

+0

我試圖澄清更多的問題。基本上,我正在尋找的是一種將窗體放置在.NET窗體中的方式,就像您在窗體上放置按鈕和標籤一樣。我想將它嵌入到表單控件中,而不僅僅是一個子窗口。 – Everett 2011-03-01 17:17:32

1

注意我寫了這個響應假設OP想字面上包含嵌入在.NET應用程序形式本機DLL,不只是修改其中它的顯示方式。

總之,沒有。您需要將C++ DLL與您的發行版一起打包,並按照您現在所做的相同方式導入/包裝其功能。

我似乎回想起我的Delphi(它使用與Borland C++相同的編譯器後端),表單設計器生成C++代碼,該代碼爲窗體中的每個資源創建winproc/message循環等與Win32 API。

由於所有這些代碼都是非託管的,因此無法編譯爲託管程序集。你可以將它移植到託管的C++中,但是這會消耗C++中的大部分好處,而且你會遇到一個蹩腳的異常模型和C++的所有其他精彩部分。在那種情況下,你可能會更好用C#重寫它。

但是,由於這是軟件,幾乎所有的東西都是可能的,所以這是一個非常糟糕的解決方案:將DLL作爲二進制資源嵌入到.NET應用程序中,並在運行時將其內容拉入二進制流,它到磁盤然後加載它(我不知道是否有辦法從內存中執行非託管DLL,除了通過將其放在RAM磁盤上進行作弊)。

這隻能讓你隱藏DLL的能力,但我真的看不到這一點。

編輯 您的意思是嵌入爲顯示爲子窗口,還是嵌入到.NET項目中的代碼中?

相關問題