接着上一章内容,这一章我们主要实现C#调用dll内的算法。
同样的,我们按照之前几章编写好的动态效果应用程序进行修改。因为我们需要实现加减乘除运算,使用我们在之前的应用程序添加额外的控件:
AXML代码实现添加额外控件:
1 <Grid Background="Black"> 2 <Grid.RowDefinitions> 3 <RowDefinition Height="30"/> 4 <RowDefinition Height="30"/> 5 <RowDefinition Height="30"/> 6 <RowDefinition Height="30"/> 7 <RowDefinition Height="60"/> 8 </Grid.RowDefinitions> 9 <Grid.ColumnDefinitions> 10 <ColumnDefinition/> 11 <ColumnDefinition/> 12 </Grid.ColumnDefinitions> 13 14 <Label Grid.Row="0" Grid.Column="0" FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Right">Entry your First Data:</Label> 15 <TextBox Grid.Row="0" Grid.Column="1" Name="m_edit1" Margin="0,5,10,5" Background="BurlyWood" Text="0" TextAlignment="Right"/> 16 17 <Label Grid.Row="1" Grid.Column="0" FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Right">Entry your Second Data:</Label> 18 <TextBox Grid.Row="1" Grid.Column="1" Name="m_edit2" Margin="0,5,10,5" Background="BurlyWood" Text="0" TextAlignment="Right"/> 19 20 <Label Grid.Row="2" Grid.Column="0" FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Right">Your Result:</Label> 21 <TextBox Grid.Row="2" Grid.Column="1" Name="m_edit3" Margin="0,5,10,5" Background="BurlyWood" IsReadOnly="True" TextAlignment="Right"/> 22 23 <Label Grid.Row="3" Grid.Column="0" FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Right">Method Entry: +, -, *, /</Label> 24 <TextBox Grid.Row="3" Grid.Column="1" Name="m_edit4" Margin="0,5,10,5" Background="BurlyWood" Text="+" TextAlignment="Center" /> 25 26 <Button Grid.Row="4" Grid.Column="0" Name="submit" Click="Click_submiit" Width="Auto" HorizontalAlignment="Center" >Get Result</Button> 27 <Button Grid.Row="4" Grid.Column="1" Name="Clear" Click="Click_clean" Width="Auto" HorizontalAlignment="Center">Reset Deft</Button> 28 </Grid>
接着,我们开始运算编程:
- 在cs文件中添加命名空间 using System.Runtime.InteropServices; 这个服务主要是提供了相应的类或者方法来支持托管/非托管模块间的互相调用。
- DllImportAttribute 该类提供了对非托管动态链接库进行引用的方法,并告诉编译器该程序的静态入口点是非托管的动态连接库,它的静态属性提供了对非托管动态链接库进行调用所必需的信息,作为最基本的要求,该类应该定义提供调用的非托管动态链接库的名称。 [DllImport(@"F:MiloLu2015vsC#cppDllDebugcppDll.dll", EntryPoint = "Calculation", CallingConvention = CallingConvention.Cdecl)] 参数1代表我们dll动态库文件的存放位置,当然如果将dll复制到项目下indebug下就直接更改为 [DllImport("cppDll.dll", EntryPoint = "Calculation", CallingConvention = CallingConvention.Cdecl)] 即可。
- 定义静态外部dll接口函数作为我们的入口函数: public static extern double calculation(double a, double b, char c); 这里与我们C++调用dll接口函数定义是一样,名称可以更改,但参数数目必须与dll定义的一样多。否则我们调用 的过程中可能会导致程序出错。
- 下面我们实现按键点击事件:
- 复位按键事件:
private void Click_clean(object sender, RoutedEventArgs e) { m_edit1.Text = m_edit2.Text = m_edit3.Text = "0"; m_edit4.Text = "+"; }
- 运算按键事件:
private void Click_submiit(object sender, RoutedEventArgs e) { try { double a = Convert.ToDouble(m_edit1.Text); double b = Convert.ToDouble(m_edit2.Text); char c = Convert.ToChar(m_edit4.Text); double result = calculation(a, b, c); m_edit3.Text = result.ToString(); } catch(Exception ex) { MessageBox.Show(ex.Message); } }
注意这里我们运用了 system.convert 类,将编辑框内容强制进行转换,这可能会导致异常风险,例如当编辑框1输入的是非数字字符,那么转换就会失败,导致程序崩溃。为了避免这种情况的发生,我们加入异常处理 try.... catch.... 在异常情况下打印异常信息。
- 复位按键事件:
完整代码:
AXML:
1 <Window x:Class="WpfControls.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="300" Width="525" > 5 <Window.Resources> 6 <!--define glass gradient stop resource--> 7 <GradientStopCollection x:Key="myGradientStopResource"> 8 <GradientStop Color="WhiteSmoke" Offset="0.2"/> 9 <GradientStop Color="Transparent" Offset="0.4"/> 10 <GradientStop Color="WhiteSmoke" Offset="0.5"/> 11 <GradientStop Color="Transparent" Offset=" 0.75"/> 12 <GradientStop Color="WhiteSmoke" Offset="0.9"/> 13 <GradientStop Color="Transparent" Offset=" 1.0"/> 14 </GradientStopCollection> 15 16 <!--define gradient brush resource--> 17 <LinearGradientBrush x:Key="myGlassBrushResource" StartPoint="0,0" EndPoint=" 1,1" Opacity="0.75" 18 GradientStops="{StaticResource myGradientStopResource }"/> 19 20 <!--background brush resource--> 21 <LinearGradientBrush x:Key="grayBlueGradientBrush" StartPoint=" 0,0" EndPoint="1,1"> 22 <GradientStop Color="Gray" Offset="0"/> 23 <GradientStop Color="Cyan" Offset="0.5"/> 24 <GradientStop Color="Gold" Offset="1.0"/> 25 </LinearGradientBrush> 26 27 <!--define button options--> 28 <Style TargetType="Button"> 29 <!--define button background--> 30 <Setter Property="Background" Value="{StaticResource grayBlueGradientBrush}"/> 31 <!--define button template--> 32 <Setter Property="Template"> 33 <Setter.Value> 34 <!--target type is button--> 35 <ControlTemplate TargetType="{x:Type Button}"> 36 <Grid Margin="-26,0,-56,2"> 37 <!--outline rectangle--> 38 <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" 39 VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" 40 RadiusX="20" RadiusY="20" StrokeThickness="10" Fill="Transparent"/> 41 <!--inner rectangle--> 42 <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" 43 VerticalAlignment="Stretch" Stroke="Transparent" 44 RadiusX="20" RadiusY="20" StrokeThickness="10" Fill="{TemplateBinding Background}"/> 45 <!--glass rectangle--> 46 <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" 47 VerticalAlignment="Stretch" StrokeThickness="2" 48 RadiusX="10" RadiusY="10" Opacity="0" 49 Fill="{StaticResource myGlassBrushResource}" 50 RenderTransformOrigin="0.5,0.5" Margin="0"> 51 <!--rectangle stroke--> 52 <Rectangle.Stroke> 53 <LinearGradientBrush StartPoint=" 0.5,0" EndPoint="0.5,1"> 54 <LinearGradientBrush.GradientStops> 55 <GradientStop Color="LightBlue" Offset="0.0"/> 56 <GradientStop Color="Gray" Offset="1.0"/> 57 </LinearGradientBrush.GradientStops> 58 </LinearGradientBrush> 59 </Rectangle.Stroke> 60 <!--glass rectangle render transform--> 61 <Rectangle.RenderTransform> 62 <TransformGroup> 63 <!--To stretch or contact horizontally or vertially--> 64 <ScaleTransform/> 65 <!--rotate transform by angles--> 66 <RotateTransform/> 67 </TransformGroup> 68 </Rectangle.RenderTransform> 69 </Rectangle> 70 <!--dock panel--> 71 <DockPanel Name="myContentPresenterDockPanel"> 72 <ContentPresenter x:Name="myContentPresent" Margin="20" 73 Content="{TemplateBinding Content}" TextBlock.Foreground="Black"/> 74 </DockPanel> 75 </Grid> 76 <!--control template--> 77 <ControlTemplate.Triggers> 78 <!--mouse over trigger--> 79 <Trigger Property="IsMouseOver" Value="True"> 80 <!--rectangle stroke--> 81 <Setter Property="Rectangle.Stroke" TargetName="outerRectangle" 82 Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 83 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> 84 </Trigger> 85 <!--Mouse focused trigger--> 86 <Trigger Property="IsFocused" Value="True"> 87 <Setter Property="Rectangle.Stroke" TargetName="innerRectangle" 88 Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 89 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> 90 </Trigger> 91 <!--Event trigger mouse enter--> 92 <EventTrigger RoutedEvent="Mouse.MouseEnter"> 93 <!--actions--> 94 <EventTrigger.Actions> 95 <!--begin story board--> 96 <BeginStoryboard Name="mouseEnterBeginStoryboard"> 97 <Storyboard> 98 <!--animation--> 99 <DoubleAnimation Storyboard.TargetName="glassCube" 100 Storyboard.TargetProperty= 101 "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" 102 By="-0.1" Duration="0:0:0.5" /> 103 <DoubleAnimation Storyboard.TargetName="glassCube" 104 Storyboard.TargetProperty= 105 "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" 106 By="-0.1" Duration="0:0:0.5" /> 107 </Storyboard> 108 </BeginStoryboard> 109 </EventTrigger.Actions> 110 </EventTrigger> 111 <!--event trigger mouse leave--> 112 <EventTrigger RoutedEvent="Mouse.MouseLeave"> 113 <EventTrigger.Actions> 114 <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard"/> 115 </EventTrigger.Actions> 116 </EventTrigger> 117 <!--event trigger button click--> 118 <EventTrigger RoutedEvent="Button.Click"> 119 <EventTrigger.Actions> 120 <BeginStoryboard> 121 <Storyboard> 122 <DoubleAnimation Storyboard.TargetName="glassCube" 123 Storyboard.TargetProperty= 124 "(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)" 125 By="360" Duration="0:0:0.5"/> 126 </Storyboard> 127 </BeginStoryboard> 128 </EventTrigger.Actions> 129 </EventTrigger> 130 </ControlTemplate.Triggers> 131 </ControlTemplate> 132 </Setter.Value> 133 </Setter> 134 </Style> 135 136 </Window.Resources> 137 <Grid Background="Black"> 138 <Grid.RowDefinitions> 139 <RowDefinition Height="30"/> 140 <RowDefinition Height="30"/> 141 <RowDefinition Height="30"/> 142 <RowDefinition Height="30"/> 143 <RowDefinition Height="60"/> 144 </Grid.RowDefinitions> 145 <Grid.ColumnDefinitions> 146 <ColumnDefinition/> 147 <ColumnDefinition/> 148 </Grid.ColumnDefinitions> 149 150 <Label Grid.Row="0" Grid.Column="0" FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Right">Entry your First Data:</Label> 151 <TextBox Grid.Row="0" Grid.Column="1" Name="m_edit1" Margin="0,5,10,5" Background="BurlyWood" Text="0" TextAlignment="Right"/> 152 153 <Label Grid.Row="1" Grid.Column="0" FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Right">Entry your Second Data:</Label> 154 <TextBox Grid.Row="1" Grid.Column="1" Name="m_edit2" Margin="0,5,10,5" Background="BurlyWood" Text="0" TextAlignment="Right"/> 155 156 <Label Grid.Row="2" Grid.Column="0" FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Right">Your Result:</Label> 157 <TextBox Grid.Row="2" Grid.Column="1" Name="m_edit3" Margin="0,5,10,5" Background="BurlyWood" IsReadOnly="True" TextAlignment="Right"/> 158 159 <Label Grid.Row="3" Grid.Column="0" FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Right">Method Entry: +, -, *, /</Label> 160 <TextBox Grid.Row="3" Grid.Column="1" Name="m_edit4" Margin="0,5,10,5" Background="BurlyWood" Text="+" TextAlignment="Center" /> 161 162 <Button Grid.Row="4" Grid.Column="0" Name="submit" Click="Click_submiit" Width="Auto" HorizontalAlignment="Center" >Get Result</Button> 163 <Button Grid.Row="4" Grid.Column="1" Name="Clear" Click="Click_clean" Width="Auto" HorizontalAlignment="Center">Reset Deft</Button> 164 </Grid> 165 </Window>
cs完整代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 using System.Runtime.InteropServices; 16 17 namespace WpfControls 18 { 19 /// <summary> 20 /// Interaction logic for MainWindow.xaml 21 /// </summary> 22 public partial class MainWindow : Window 23 { 24 [DllImport(@"F:MiloLu2015vsC#cppDllDebugcppDll.dll", EntryPoint = "Calculation", CallingConvention = CallingConvention.Cdecl)] 25 public static extern double calculation(double a, double b, char c); 26 public MainWindow() 27 { 28 InitializeComponent(); 29 } 30 31 private void Click_submiit(object sender, RoutedEventArgs e) 32 { 33 try 34 { 35 double a = Convert.ToDouble(m_edit1.Text); 36 double b = Convert.ToDouble(m_edit2.Text); 37 char c = Convert.ToChar(m_edit4.Text); 38 double result = calculation(a, b, c); 39 m_edit3.Text = result.ToString(); 40 } 41 catch(Exception ex) 42 { 43 MessageBox.Show(ex.Message); 44 } 45 } 46 47 private void Click_clean(object sender, RoutedEventArgs e) 48 { 49 m_edit1.Text = m_edit2.Text = m_edit3.Text = "0"; 50 m_edit4.Text = "+"; 51 } 52 } 53 }
编译运行:
输入对应的运算符,就可以实现我们的对应的加减乘除运算。整体看起,既有动态效果,又有运算.....至此,对应动态库的运用我们有了初步的了解。
End.
谢谢.