Created
October 5, 2014 16:45
-
-
Save stinos/fdd62bcdb4cb3ea10476 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Window x:Class="WpfApplication1.MainWindow" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
Title="MainWindow" Height="350" Width="460"> | |
<StackPanel Orientation="Horizontal"> | |
<StackPanel Orientation="Vertical" Width="160"> | |
<Button x:Name="StartButton" Content="Start Python"/> | |
<TextBlock x:Name="Status"/> | |
</StackPanel> | |
<ContentControl Grid.Column="1" x:Name="PythonWinHost" Width="300"/> | |
</StackPanel> | |
</Window> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.Runtime.InteropServices; | |
using System.Threading; | |
using System.Windows; | |
using System.Windows.Interop; | |
using System.Windows.Threading; | |
using IronPython.Hosting; | |
namespace WpfApplication1 | |
{ | |
public static class User32 | |
{ | |
public const int WS_CHILD = 0x40000000; | |
public const int WS_CAPTION = 0x00C00000; | |
public const int WS_THICKFRAME = 0x00040000; | |
public const int GWL_STYLE = -16; | |
[DllImport( "user32.dll" )] | |
public static extern int GetWindowLong( IntPtr hWnd, int nIndex ); | |
[DllImport( "user32.dll" )] | |
public static extern int SetWindowLong( IntPtr hWnd, int nIndex, int dwNewLong ); | |
[DllImport( "user32" )] | |
public static extern IntPtr SetParent( IntPtr hWnd, IntPtr hWndParent ); | |
} | |
public class WpfHwndEmbedHost : HwndHost | |
{ | |
private readonly IntPtr childWin; | |
public WpfHwndEmbedHost( IntPtr childWin ) | |
{ | |
this.childWin = childWin; | |
} | |
protected override HandleRef BuildWindowCore( HandleRef hwndParent ) | |
{ | |
int style = User32.GetWindowLong( childWin, User32.GWL_STYLE ); | |
style = style & ~User32.WS_CAPTION & ~User32.WS_THICKFRAME; | |
style |= User32.WS_CHILD; | |
User32.SetWindowLong( childWin, User32.GWL_STYLE, style ); | |
User32.SetParent( childWin, hwndParent.Handle ); | |
this.InvalidateVisual(); | |
return new HandleRef( this, childWin ); | |
} | |
protected override void DestroyWindowCore( HandleRef hwnd ) | |
{ | |
} | |
} | |
public partial class MainWindow : Window | |
{ | |
private const bool hostedWin = true; | |
private readonly Dispatcher mainDispatcher; | |
private Dispatcher pyDispatcher; | |
private Thread procThread; | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
DataContext = this; | |
mainDispatcher = Application.Current.Dispatcher; | |
Status.Text = "Ready"; | |
StartButton.Click += ( sender, args ) => StartPythonThread(); | |
} | |
private void StartPythonThread() | |
{ | |
var thr = new Thread( PythonThread ) { IsBackground = true, Name = "Python" }; | |
thr.SetApartmentState( ApartmentState.STA ); | |
thr.Start(); | |
} | |
private Window CreateWindow() | |
{ | |
var win = new Window(); | |
win.Show(); | |
if( hostedWin ) | |
{ | |
var hostedWinHandle = new WindowInteropHelper( win ).Handle; | |
mainDispatcher.Invoke( () => { PythonWinHost.Content = new WpfHwndEmbedHost( hostedWinHandle ); } ); | |
} | |
return win; | |
} | |
private void StartProcessThread() | |
{ | |
procThread = new Thread( ProcessThread ) { Name = "Process" }; | |
procThread.Start(); | |
} | |
private bool ProcessRunning() | |
{ | |
return procThread != null && procThread.IsAlive; | |
} | |
private void ProcessThread() | |
{ | |
mainDispatcher.Invoke( () => { Status.Text = "Process start"; } ); | |
Thread.Sleep( 5000 ); | |
mainDispatcher.Invoke( () => { Status.Text = "Process done"; } ); | |
} | |
private void PythonThread() | |
{ | |
pyDispatcher = Dispatcher.CurrentDispatcher; | |
Debug.Assert( !ReferenceEquals( pyDispatcher, Application.Current.Dispatcher ) ); | |
SynchronizationContext.SetSynchronizationContext( new DispatcherSynchronizationContext( pyDispatcher ) ); | |
var py = Python.CreateEngine(); | |
var scope = py.CreateScope(); | |
( (dynamic) scope ).createWindow = new Func<Window>( CreateWindow ); | |
( (dynamic) scope ).startProcess = new Action( StartProcessThread ); | |
( (dynamic) scope ).processRunning = new Func<bool>( ProcessRunning ); | |
( (dynamic) scope ).runDispatcher = new Action( Dispatcher.Run ); | |
py.Execute( script, scope ); | |
} | |
private const string script = | |
@" | |
import time | |
import clr | |
clr.AddReference( 'PresentationFramework' ) | |
clr.AddReference( 'PresentationCore' ) | |
from System.Windows.Controls import Button | |
def RunIt( s, e ): | |
startProcess() | |
time.sleep( 1.5 ) #make sure proc thread started... | |
while processRunning(): | |
time.sleep( 0.5 ) | |
b = Button() | |
b.Content = 'Start Process' | |
b.Click += RunIt | |
win = createWindow() | |
win.Content = b | |
runDispatcher() | |
"; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | |
<PropertyGroup> | |
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |
<ProjectGuid>{F3304AF0-F1E8-45EB-A6E0-C480D2909B30}</ProjectGuid> | |
<OutputType>WinExe</OutputType> | |
<AppDesignerFolder>Properties</AppDesignerFolder> | |
<RootNamespace>WpfApplication1</RootNamespace> | |
<AssemblyName>WpfApplication1</AssemblyName> | |
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> | |
<FileAlignment>512</FileAlignment> | |
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |
<WarningLevel>4</WarningLevel> | |
</PropertyGroup> | |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |
<PlatformTarget>AnyCPU</PlatformTarget> | |
<DebugSymbols>true</DebugSymbols> | |
<DebugType>full</DebugType> | |
<Optimize>false</Optimize> | |
<OutputPath>bin\Debug\</OutputPath> | |
<DefineConstants>DEBUG;TRACE</DefineConstants> | |
<ErrorReport>prompt</ErrorReport> | |
<WarningLevel>4</WarningLevel> | |
</PropertyGroup> | |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |
<PlatformTarget>AnyCPU</PlatformTarget> | |
<DebugType>pdbonly</DebugType> | |
<Optimize>true</Optimize> | |
<OutputPath>bin\Release\</OutputPath> | |
<DefineConstants>TRACE</DefineConstants> | |
<ErrorReport>prompt</ErrorReport> | |
<WarningLevel>4</WarningLevel> | |
</PropertyGroup> | |
<ItemGroup> | |
<Reference Include="IronPython, Version=2.7.0.40, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL"> | |
<SpecificVersion>False</SpecificVersion> | |
<HintPath>packages\IronPython.2.7.4\lib\Net45\IronPython.dll</HintPath> | |
</Reference> | |
<Reference Include="IronPython.Modules, Version=2.7.0.40, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL"> | |
<SpecificVersion>False</SpecificVersion> | |
<HintPath>packages\IronPython.2.7.4\lib\Net45\IronPython.Modules.dll</HintPath> | |
</Reference> | |
<Reference Include="IronPython.SQLite"> | |
<HintPath>packages\IronPython.2.7.4\lib\Net45\IronPython.SQLite.dll</HintPath> | |
</Reference> | |
<Reference Include="IronPython.Wpf"> | |
<HintPath>packages\IronPython.2.7.4\lib\Net45\IronPython.Wpf.dll</HintPath> | |
</Reference> | |
<Reference Include="Microsoft.Dynamic, Version=1.1.0.20, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL"> | |
<SpecificVersion>False</SpecificVersion> | |
<HintPath>packages\IronPython.2.7.4\lib\Net45\Microsoft.Dynamic.dll</HintPath> | |
</Reference> | |
<Reference Include="Microsoft.Scripting, Version=1.1.0.20, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL"> | |
<SpecificVersion>False</SpecificVersion> | |
<HintPath>packages\IronPython.2.7.4\lib\Net45\Microsoft.Scripting.dll</HintPath> | |
</Reference> | |
<Reference Include="Microsoft.Scripting.AspNet"> | |
<HintPath>packages\IronPython.2.7.4\lib\Net45\Microsoft.Scripting.AspNet.dll</HintPath> | |
</Reference> | |
<Reference Include="Microsoft.Scripting.Metadata, Version=1.1.0.20, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL"> | |
<SpecificVersion>False</SpecificVersion> | |
<HintPath>packages\IronPython.2.7.4\lib\Net45\Microsoft.Scripting.Metadata.dll</HintPath> | |
</Reference> | |
<Reference Include="System" /> | |
<Reference Include="System.Data" /> | |
<Reference Include="System.Xml" /> | |
<Reference Include="Microsoft.CSharp" /> | |
<Reference Include="System.Core" /> | |
<Reference Include="System.Xml.Linq" /> | |
<Reference Include="System.Data.DataSetExtensions" /> | |
<Reference Include="System.Xaml"> | |
<RequiredTargetFramework>4.0</RequiredTargetFramework> | |
</Reference> | |
<Reference Include="WindowsBase" /> | |
<Reference Include="PresentationCore" /> | |
<Reference Include="PresentationFramework" /> | |
</ItemGroup> | |
<ItemGroup> | |
<ApplicationDefinition Include="App.xaml"> | |
<Generator>MSBuild:Compile</Generator> | |
<SubType>Designer</SubType> | |
</ApplicationDefinition> | |
<Page Include="MainWindow.xaml"> | |
<Generator>MSBuild:Compile</Generator> | |
<SubType>Designer</SubType> | |
</Page> | |
<Compile Include="App.xaml.cs"> | |
<DependentUpon>App.xaml</DependentUpon> | |
<SubType>Code</SubType> | |
</Compile> | |
<Compile Include="MainWindow.xaml.cs"> | |
<DependentUpon>MainWindow.xaml</DependentUpon> | |
<SubType>Code</SubType> | |
</Compile> | |
</ItemGroup> | |
<ItemGroup> | |
<Compile Include="Properties\AssemblyInfo.cs"> | |
<SubType>Code</SubType> | |
</Compile> | |
<Compile Include="Properties\Resources.Designer.cs"> | |
<AutoGen>True</AutoGen> | |
<DesignTime>True</DesignTime> | |
<DependentUpon>Resources.resx</DependentUpon> | |
</Compile> | |
<Compile Include="Properties\Settings.Designer.cs"> | |
<AutoGen>True</AutoGen> | |
<DependentUpon>Settings.settings</DependentUpon> | |
<DesignTimeSharedInput>True</DesignTimeSharedInput> | |
</Compile> | |
<EmbeddedResource Include="Properties\Resources.resx"> | |
<Generator>ResXFileCodeGenerator</Generator> | |
<LastGenOutput>Resources.Designer.cs</LastGenOutput> | |
</EmbeddedResource> | |
<None Include="packages.config" /> | |
<None Include="Properties\Settings.settings"> | |
<Generator>SettingsSingleFileGenerator</Generator> | |
<LastGenOutput>Settings.Designer.cs</LastGenOutput> | |
</None> | |
<AppDesigner Include="Properties\" /> | |
</ItemGroup> | |
<ItemGroup> | |
<None Include="App.config" /> | |
</ItemGroup> | |
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |
Other similar extension points exist, see Microsoft.Common.targets. | |
<Target Name="BeforeBuild"> | |
</Target> | |
<Target Name="AfterBuild"> | |
</Target> | |
--> | |
</Project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment