none
生成一个wpf的.exe文件,打开这个.exe文件将窗口句柄嵌入另一个window窗体上的控件里 RRS feed

  • 问题

  • 生成一个wpf的.exe文件,打开这个.exe文件将窗口句柄嵌入另一个window窗体上的Border里

    以下是获得.exe 窗口句柄的代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Runtime.InteropServices;
    using System.Windows.Interop;
    using System.Windows.Controls;
    using System.Threading;

    namespace WpfApplication1
    {
        public class EmbeddedApp : HwndHost
        {
            [DllImport( "user32.dll" )]
            private static extern int SetParent( IntPtr hWndChild , IntPtr hWndParent );
            [DllImport( "user32.dll" , SetLastError=true , CharSet=CharSet.Auto )]
            private static extern uint SetWindowLong( IntPtr hwnd , int nIndex , uint newLong );
            [DllImport( "user32.dll" , SetLastError=true , CharSet=CharSet.Auto )]
            private static extern uint GetWindowLong( IntPtr hwnd , int nIndex );

            [DllImport( "user32.dll" )]
            private static extern int EnumWindows( CallBackPtr callPtr , ref WindowInfo WndInfoRef );
            [DllImport( "User32.dll" )]
            static extern int GetWindowText( IntPtr handle , StringBuilder text , int MaxLen );
            [DllImport( "user32.dll" )]
            public static extern int GetWindowRect( IntPtr hwnd , ref RECT rc );
            [DllImport( "user32.dll" )]
            public static extern bool MoveWindow( IntPtr hWnd , int X , int Y , int nWidth , int nHeight , bool bRepaint ); 

            [DllImport("user32.dll", EntryPoint = "FindWindowEx",
                CharSet = CharSet.Auto)]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpazWindow);

            [DllImport( "user32.dll" )]
            public static extern bool SetWindowPos(
            IntPtr hWnd ,             // handle to window
            IntPtr hWndInsertAfter ,  // placement-order handle 安置顺序处理
            int X ,                 // horizontal position
            int Y ,                 // vertical position
            int cx ,                // width
            int cy ,                // height
            uint uFlags            // window-positioning options
            );

            [DllImport( "user32.dll" )]
            public static extern IntPtr FindWindow(
            string lpClassName ,  // class name
            string lpWindowName  // window name
            );

            [DllImport( "user32.dll" )]
            public static extern long SetWindowPosition(
            long Left ,
            long Top ,
            long Width ,
            long Height
            );

            internal const int
                GWL_WNDPROC = ( -4 ) ,
                GWL_HINSTANCE = ( -6 ) ,
                GWL_HWNDPARENT = ( -8 ) ,
                GWL_STYLE = ( -16 ) ,
                GWL_EXSTYLE = ( -20 ) ,
                GWL_USERDATA = ( -21 ) ,
                GWL_ID = ( -12 );
            internal const uint
                  WS_CHILD = 0x40000000 ,
                  WS_VISIBLE = 0x10000000 ,
                  LBS_NOTIFY = 0x00000001 ,
                  HOST_ID = 0x00000002 ,
                  LISTBOX_ID = 0x00000001 ,
                  WS_VSCROLL = 0x00200000 ,
                  WS_BORDER = 0x00800000 ,
                  WS_POPUP = 0x80000000;
            internal IntPtr
                BOTTOM = (IntPtr)1,
                Top = (IntPtr)0;
            private const int HWND_TOP = 0x0;
            private const int WM_COMMAND = 0x0112;
            private const int WM_QT_PAINT = 0xC2DC;
            private const int WM_PAINT = 0x000F;
            private const int WM_SIZE = 0x0005;
            private const int SWP_FRAMECHANGED = 0x0020;
            private Border WndHoster;
            private double screenW , screenH;
            private System.Diagnostics.Process appProc;
            private uint oldStyle;
            public IntPtr hwndHost;
            private String appPath;
            public EmbeddedApp( Border b , double sW , double sH , String p , String f )
            {
                WndHoster = b;
                screenH = sH;
                screenW = sW;
                appPath = p;
                WinInfo = new WindowInfo( );
                WinInfo.winTitle = f;
            }
            protected override HandleRef BuildWindowCore( HandleRef hwndParent )
            {
                appProc = new System.Diagnostics.Process( );
                appProc.StartInfo.FileName = appPath;
                appProc.Start( );

                Thread.Sleep( 1000 );

                hwndHost = FindWindow( null , "MainWindow1" );
                //hwndHost = appProc.MainWindowHandle;

                // 嵌入在HwnHost中的窗口必须要 设置为WS_CHILD风格   
                oldStyle = GetWindowLong( hwndHost , GWL_STYLE );
                uint newStyle = oldStyle;

                newStyle |= WS_CHILD;
                newStyle &= ~WS_POPUP;

                SetWindowLong( hwndHost , GWL_STYLE , oldStyle | newStyle );
               
                //将netterm的父窗口设置为HwndHost
                SetParent( hwndHost , hwndParent.Handle );
                GetWindowRect( hwndHost , ref ( WinInfo.r ) );
                SetWindowPos( hwndHost , BOTTOM , 0 , 0 , 200 , 200 , 0x0040 );

                return new HandleRef( this , hwndHost );

            }

            protected override void DestroyWindowCore( System.Runtime.InteropServices.HandleRef hwnd )
            {
                SetWindowLong( hwndHost , GWL_STYLE , oldStyle );
                SetParent( hwndHost , (IntPtr)0 );
            }

            [StructLayout( LayoutKind.Sequential )]
            public struct RECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;
            }
            [StructLayout( LayoutKind.Sequential )]
            public struct WindowInfo
            {
                public String winTitle;
                public RECT r;
                public IntPtr hwnd;
            }
            public delegate bool CallBackPtr( IntPtr hwnd , ref WindowInfo WndInfoRef );
            private static CallBackPtr callBackPtr;
            public WindowInfo WinInfo;
            public static bool CallBackProc( IntPtr hwnd , ref WindowInfo WndInfoRef )
            {
                StringBuilder str = new StringBuilder( 512 );
                GetWindowText( hwnd , str , str.Capacity );
                if ( str.ToString( ).IndexOf( WndInfoRef.winTitle , 0 ) >= 0 )
                {
                    WndInfoRef.hwnd = hwnd;
                    GetWindowRect( hwnd , ref ( WndInfoRef.r ) );
                }

                return true;
            }
            public IntPtr FindTheWindow( )
            {
                callBackPtr = new CallBackPtr( CallBackProc );
                EnumWindows( callBackPtr , ref WinInfo );
                return WinInfo.hwnd;

            }
            public void RePosWindow( Border b , double screenW , double screenH )
            {
                double width = WinInfo.r.right - WinInfo.r.left;
                double height = WinInfo.r.bottom - WinInfo.r.top;
                double left , right , top , bottom;
                if ( screenW < width )
                {
                     left = 0;
                     right = 100;
                }
                else
                {
                     left = ( screenW - width ) / 2;
                     right = ( screenW - width ) / 2;
                }
                if ( screenH < height )
                {
                     top = 0;
                     bottom = 100;
                }
                else
                {
                     top = ( screenH - height ) / 2;
                     bottom = ( screenH - height ) / 2;
                }
                //double width = 300;
                //double height = 300;
                //double left = 50;
                //double right = 50;
                //double top = 50;
                //double bottom = 50;

                b.Margin = new Thickness( left , top , right , bottom );
            }

        }
    }

     

    在Button_Click中调用上面的类

    private void button1_Click( object sender , RoutedEventArgs e )
    {

                String path;
                path = Environment.CurrentDirectory + @"\12\12";
                ea = new EmbeddedApp( WndHost , 100 , 100 , path , "" );

                WndHost.Child = ea; //WndHost是Border容器

    }

    上面代码可以实现将.exe 文件嵌入Border,但是嵌入后.exe窗口定义不了宽和高,

    SetParent( hwndHost , hwndParent.Handle );//hwndHost  .exe 窗口句柄, hwndParent.Handle父类的窗口句柄

    这句以后,hwndHost失去控制,宽和高变成最大化,只能控制hwndParent.Handle的宽和高,所以显示出来的是hwndParent.Handle截取了hwndHost的一部分。

    怎样才能让hwndHost的大小和hwndParent.Handle同步呢??
     

    2010年7月29日 1:59

全部回复

  • 额......................

    这么难么??

    我又想了一个办法,在wpf中放入winform的Panel控件~~

    System.Windows.Forms.Panel panel = new System.Windows.Forms.Panel();

    WindowsFormsHost panelHost = new WindowsFormsHost( );
    //Grid.SetRow( panelHost , 1 );

    SetParent( hwndHost, panel.Handle );

    // Remove border and whatnot
    // SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE);

    // Move the window to overlay it on this window
    MoveWindow( appWin , 100 , 100 , 300 , 300 , true );

    panelHost.Child = panel;
    this.WndHost.Child = panelHost;

    但是最终WndHost控件,却不显示图像,加断电跟踪了一下,Panel的句柄获取到了,panelHost.Chile不为空,WndHost.Chile也不为空,但是控件里就是不显示图像..............

    问题解决中..................还请大家多多帮忙~~~~~

    2010年8月2日 2:14