WPF内嵌exe问题

疯狂的大菠萝 2012-12-14 06:15:03
先上代码


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;


[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(2000);
hwndHost = FindWindow(null, "Island Demo");
//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);
}

上面是EmbeddedApp.cs内容

下面是窗体.cs代码。
string formName;
String path;

formName = "Island Demo";
path = Environment.CurrentDirectory + "\\" + "3D Demo\\app.exe";

EmbeddedApp ea = new EmbeddedApp(WndHost, this.Width, this.Height, path, formName);
WndHost.Child = ea;
可以运行出


但是鼠标和键盘全部失效。根本操作不了这个窗体。
谁有好办法吗?
http://www.itpub.net/forum.php?mod=viewthread&tid=980820
这个人说有办法。可是他的说【Win32Native .cs是我们写的一个对Win32API的调用声明,都是简单的PInvoke声明,由于尺寸比较大这里就不贴出来了,大家可以查MSDN自己来声明。】
...全文
383 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
A971319231 2014-12-11
  • 打赏
  • 举报
回复
引用 4 楼 gngnxx 的回复:
你好我会报错误:寄宿的 HWND 必须是指定父级的子窗口。
我的也会报这个错误,请问你解决了没
gngnxx 2014-07-10
  • 打赏
  • 举报
回复
你好我会报错误:寄宿的 HWND 必须是指定父级的子窗口。
Y伯爵7 2013-06-13
  • 打赏
  • 举报
回复
private void Button_Click(object sender, RoutedEventArgs e) { String path; // path = Environment.CurrentDirectory + @"\ui.exe"; var ea = new EmbeddedApp(WndHost, 100, 100, path, ""); WndHost.Child = ea; //WndHost是Border容器 }
Y伯爵7 2013-06-13
  • 打赏
  • 举报
回复
<Grid> <Button VerticalAlignment="Top" HorizontalAlignment="Left" Width="35" Height="35" Click="Button_Click">测试</Button> <Border x:Name="WndHost" Margin="35" BorderBrush="Black" BorderThickness="1"> <!--<WindowsFormsHost Height="100" Name="windowsFormsHost1" Width="200" />--> </Border> </Grid>
Y伯爵7 2013-06-13
  • 打赏
  • 举报
回复
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; using System.Diagnostics; 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 ); [DllImport("user32.dll")] private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); //[DllImport("user32.dll", SetLastError = true)] //private static extern int GetWindowLong(IntPtr hWnd, int nIndex); 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, WS_CAPTION = 0x00C00000; 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, "MainWindow"); ////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); ProcessStartInfo psi = new ProcessStartInfo("test.exe"); psi.WindowStyle = ProcessWindowStyle.Minimized; var _process = Process.Start(psi); _process.WaitForInputIdle(); // The main window handle may be unavailable for a while, just wait for it while (_process.MainWindowHandle == IntPtr.Zero) { Thread.Yield(); } IntPtr notepadHandle = _process.MainWindowHandle; uint style = GetWindowLong(notepadHandle, GWL_STYLE); //style = style & ~((int)WS_CAPTION) & ~((int)WS_THICKFRAME); // Removes Caption bar and the sizing border style = style & ~((uint)WS_CAPTION); style |= ((int)WS_CHILD); // Must be a child window to be hosted SetWindowLong(notepadHandle, GWL_STYLE, style); SetParent(notepadHandle, hwndParent.Handle); this.InvalidateVisual(); HandleRef hwnd = new HandleRef(this, notepadHandle); return hwnd; } 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); } } }
在Windows系统中,notepad.exe(记事本)是一个“经典的”、“简洁的”文本编辑器。这个软件,没有华丽的外观,也没有繁杂的功能,仅仅是一个文本编辑小软件。虽然经过Windows系统数十年的变换,但它却保持着永恒姿态,数十年来几乎不曾改变过。曾经,VS中的经典DEMO中,就有它的身影,一个新建的项目,就藏有一个新建的“记事本”。然而,在WPF的项目中,“记事本”却消失的无影无踪,也许是很容易实现,也许是为了革新,而不愿再传承“经典”。确实,使用WPF技术再次让“记事本”复活,确实也是一件非常容易的事情。但是,如果,使用WPF技术,再搭配当下非常流行的MVVM模式呢?复活“记事本”的难度却陡然上升至很多WPF程序员为之默默叹气。而,MVVM模式是掌握WPF的最顶级技术,MVVM模式拥有的无尽的优势,让WPF相对于过往的编程模式来说,是一种革命性的创新,从而也成为大中型WPF项目中必须的模式。但,学习难度。。。。。。在这个《WPF记事本开发详解》的课程中,赵老师带领你在WPF中,从零开始一步步构建MVVM模式,直到让你亲自以WPF+MVVM的方式,让这个经典的“记事本”软件从你的手中“复活”。在课程中,赵老师会详细讲解WPF和MVVM中的各种技巧,让你从此爱上WPF+MVVM编程。

8,737

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧