ショートカットメニューを実装する(非MVVM)

WindowsForms でショートカットキーを実装するのは、プロパティエディタでササッと指定できましたが、WPFではそうはいきません。

ここでは MVVM を使わずに最も簡単な実装と思われる方法を紹介します。( MVVM で実施すると、かなり面倒です )

Fig. コントロールキーと組み合わせのショートカット
Fig. 複数の修飾キーと組み合わせのショートカット
Fig. ファンクションキーによるショートカット

まず MainWindow.xaml.cs に、ショートカットをつけたいメニューについて、下記の CustomCommands クラスを定義します。

	public static class CustomCommands
	{
		// ここは同じ名前にする必要がある.
		public static readonly RoutedCommand RtdCmdSave = new RoutedCommand( "RtdCmdSave", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdOpen = new RoutedCommand( "RtdCmdOpen", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdQuit = new RoutedCommand( "RtdCmdQuit", typeof( MainWindow ) );

		public static readonly RoutedCommand RtdCmdDebugExec000 = new RoutedCommand( "RtdCmdDebugExec000", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdDebugExec001 = new RoutedCommand( "RtdCmdDebugExec001", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdDebugExec002 = new RoutedCommand( "RtdCmdDebugExec002", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdDebugExec003 = new RoutedCommand( "RtdCmdDebugExec003", typeof( MainWindow ) );
	}

つぎに MainWindow.xaml に下記のようなコードを書きます。

<CommandBinding>で定義した CustomCommands クラスと関連付けます。
<KeyBinding>の Gesture プロパティにショートカットキーの組み合わせを指定します。

    <Window.CommandBindings>
        <CommandBinding Command="local:CustomCommands.RtdCmdSave" Executed="menuFileSave_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdOpen" Executed="menuFileOpen_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdQuit" Executed="menuApplicationQuit_Click" />

        <CommandBinding Command="local:CustomCommands.RtdCmdDebugExec000" Executed="menuDebugExec000_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdDebugExec001" Executed="menuDebugExec001_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdDebugExec002" Executed="menuDebugExec002_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdDebugExec003" Executed="menuDebugExec003_Click" />
    </Window.CommandBindings>
    
    <Window.InputBindings>
        <!-- ここの Gesture でショートカットキーの組み合わせを決定する -->
        <KeyBinding Command="local:CustomCommands.RtdCmdSave" Gesture="Ctrl+S" />
        <KeyBinding Command="local:CustomCommands.RtdCmdOpen" Gesture="Ctrl+O" />
        <KeyBinding Command="local:CustomCommands.RtdCmdQuit" Gesture="Ctrl+Shift+Alt+Q" />

        <!-- ここの Gesture でショートカットキーの組み合わせを決定する -->
        <KeyBinding Command="local:CustomCommands.RtdCmdDebugExec000" Gesture="F5" />
        <KeyBinding Command="local:CustomCommands.RtdCmdDebugExec001" Gesture="F6" />
        <KeyBinding Command="local:CustomCommands.RtdCmdDebugExec002" Gesture="F7" />
        <KeyBinding Command="local:CustomCommands.RtdCmdDebugExec003" Gesture="F8" />
    </Window.InputBindings>

以降に全体のコードを示しますが、3つのファイルの紹介なので、ビルドして試すのは困難だと思われます。ソースコードのアーカイブを用意しておきましたので、よろしければダウンロードしてご利用ください。

全体のコード

MainWindow.xaml.cs の冒頭にショートカットキーを効かせるために必要な CustomCommands クラスを定義しています。コンパイルが通る場所ならば、どこに置いてもかまいません。( public にしておいてください )

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace aaa
{

	// ショートカットキーを効かせるために必要なクラス.
	public static class CustomCommands
	{
		// ここは同じ名前にする必要がある.
		public static readonly RoutedCommand RtdCmdSave = new RoutedCommand( "RtdCmdSave", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdOpen = new RoutedCommand( "RtdCmdOpen", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdQuit = new RoutedCommand( "RtdCmdQuit", typeof( MainWindow ) );

		public static readonly RoutedCommand RtdCmdDebugExec000 = new RoutedCommand( "RtdCmdDebugExec000", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdDebugExec001 = new RoutedCommand( "RtdCmdDebugExec001", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdDebugExec002 = new RoutedCommand( "RtdCmdDebugExec002", typeof( MainWindow ) );
		public static readonly RoutedCommand RtdCmdDebugExec003 = new RoutedCommand( "RtdCmdDebugExec003", typeof( MainWindow ) );
	}

	public partial class MainWindow : Window
	{

		const int INI_W = 512;
		const int INI_H = 256;
		byte [] TheData;
		WriteableBitmap TheBmp;

		List <Label> StbLabels = new List<Label>(0);

		int FillType = 0;

		public MainWindow()
		{

			// デフォルトで用意されているコード.
			InitializeComponent();

			// データ領域を確保する.
			int w = INI_W;
			int h = INI_H;
			int numpix = w * h;
			TheData = new byte[ numpix ];

			// 画像データを仕込む.
			MyUtility myu = new MyUtility();
			FillType = 0;
			myu.SetDataTypeN( TheData, w, h, FillType );

			// ビットマップのDPI、とりあえず 96dpi で決め打ちした.
			const double DPI_X = 96.0;
			const double DPI_Y = 96.0;

			// byte[] データを表示するのでグレースケールな256要素のカラーパレット形式とする.
			PixelFormat pixfmt = PixelFormats.Indexed8;

			// 256要素のカラーパレット生成のために必要な256要素の色リストを作成する.
			List<Color> list_colors = new List<Color>(0);
			const int NUM_COLORS = 256;
			for ( int k = 0; k < NUM_COLORS; k++ )
			{
				const byte LEVEL_ALPHA = 0xff;
				byte level = (byte)( k );
				Color c = Color.FromArgb( LEVEL_ALPHA, level, level, level );
				list_colors.Add( c );
			}

			// 256要素の色リストからパレットを生成する.
			BitmapPalette palette = new BitmapPalette( list_colors );

			// 書き込み可能なビットマップを作成する.
			TheBmp = new WriteableBitmap( w, h, DPI_X, DPI_Y, pixfmt, palette );

			// 書き込み可能ビットマップにデータを仕込む.
			Int32Rect rct = new Int32Rect( 0, 0, w, h );
			int stride_bytes = w * sizeof( byte );
			const int OFFSET_BYTES = 0;
			TheBmp.WritePixels( rct, TheData, stride_bytes, OFFSET_BYTES );

			// 表示させるデータを内包したビットマップと表示イメージを関連付ける.
			image000.Width = w;
			image000.Height = h;
			image000.Source = TheBmp;

			// ステータスバーのラベルをリスト化する.
			StbLabels.Add( stbLabel000 );
			StbLabels.Add( stbLabel001 );
			StbLabels.Add( stbLabel002 );
			StbLabels.Add( stbLabel003 );

			// ステータスバーのラベルの再描画を要請する.
			this.InvalidateVisual();

		}

		protected override void OnRender( DrawingContext dc )
		{

			// ステータスバーのラベルに表示する文字列を指定する.
			for ( int n = 0; n < MyUtility.MAX_NUM_TYPE_OF_FILL; n++ )
			{
				StbLabels[n].Content = String.Format( "{0:d3}", n );
			}

			// ステータスバーのラベルの背景色を設定する.
			for ( int n = 0; n < MyUtility.MAX_NUM_TYPE_OF_FILL; n++ )
			{
				if ( n == FillType )
				{
					// ステータスバーのフィルタイプに該当するラベルのみ色を変更する.
					StbLabels[n].Background = Brushes.Aqua;
				}
				else
				{
					// それ以外は背景色を透明にする.
					StbLabels[n].Background = Brushes.Transparent;
				}
			}

		}

		private void menuApplicationQuit_Click( object sender, RoutedEventArgs e )
		{
			this.Close();
		}

		private void menuFileOpen_Click( object sender, RoutedEventArgs e )
		{

			Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();

			// ダイアログのタイトル.
			ofd.Title = "ふぁいるをひらく";

			// 拡張子フィルタ.
			ofd.Filter = "Bitmap|*.bmp|JPEG|*.jpeg|PNG|*.png|ALL|*.*";

			// 基数は1.
			ofd.FilterIndex = 3;

			// デフォルト表示ファイル名.
			ofd.FileName = "default_filename";

			// 戻り値は bool ではなくて bool? であることに注目.
			bool? ret = ofd.ShowDialog();
			
			// bool ではないので if ( ret ) にはできない.
			if ( ret == true )
			{
				String filepath = ofd.FileName;
				MessageBox.Show( filepath );
			}
			else
			{
				MessageBox.Show( "Canceled." );
			}

		}

		private void menuFileSave_Click( object sender, RoutedEventArgs e )
		{

			Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog();

			// ダイアログのタイトル.
			sfd.Title = "ふぁいるをほぞんする";

			// 拡張子フィルタ.
			sfd.Filter = "Bitmap|*.bmp|JPEG|*.jpeg|PNG|*.png|ALL|*.*";

			// 基数は1.
			sfd.FilterIndex = 2;

			// デフォルト表示ファイル名.
			sfd.FileName = "default_filename";

			// 戻り値は bool ではなくて bool? であることに注目.
			bool? ret = sfd.ShowDialog();
			
			// bool ではないので if ( ret ) にはできない.
			if ( ret == true )
			{
				String filepath = sfd.FileName;
				MessageBox.Show( filepath );
			}
			else
			{
				MessageBox.Show( "Canceled." );
			}

		}

		private void menuDebugExec000_Click( object sender, RoutedEventArgs e )
		{

			// タイプ0のデータを仕込む.
			MyUtility myu = new MyUtility();
			int w = TheBmp.PixelWidth;
			int h = TheBmp.PixelHeight;
			FillType = 0;
			bool bret = myu.SetDataTypeN( TheData, w, h, FillType );
			if ( !bret )
			{
				String strerr = String.Format( "Error: SetDataType{0}();", FillType );
				MessageBox.Show( strerr );
				return;
			}

			// 書き込み可能ビットマップにデータを仕込む.
			Int32Rect rct = new Int32Rect( 0, 0, w, h );
			int stride_bytes = w * sizeof( byte );
			const int OFFSET_BYTES = 0;
			TheBmp.WritePixels( rct, TheData, stride_bytes, OFFSET_BYTES );

			// ステータスバーのラベルの再描画を要請する.
			this.InvalidateVisual();

		}

		private void menuDebugExec001_Click( object sender, RoutedEventArgs e )
		{

			// タイプ1のデータを仕込む.
			MyUtility myu = new MyUtility();
			int w = TheBmp.PixelWidth;
			int h = TheBmp.PixelHeight;
			FillType = 1;
			bool bret = myu.SetDataTypeN( TheData, w, h, FillType );
			if ( !bret )
			{
				String strerr = String.Format( "Error: SetDataType{0}();", FillType );
				MessageBox.Show( strerr );
				return;
			}

			// 書き込み可能ビットマップにデータを仕込む.
			Int32Rect rct = new Int32Rect( 0, 0, w, h );
			int stride_bytes = w * sizeof( byte );
			const int OFFSET_BYTES = 0;
			TheBmp.WritePixels( rct, TheData, stride_bytes, OFFSET_BYTES );

			// ステータスバーのラベルの再描画を要請する.
			this.InvalidateVisual();

		}

		private void menuDebugExec002_Click( object sender, RoutedEventArgs e )
		{

			// タイプ2のデータを仕込む.
			MyUtility myu = new MyUtility();
			int w = TheBmp.PixelWidth;
			int h = TheBmp.PixelHeight;
			FillType = 2;
			bool bret = myu.SetDataTypeN( TheData, w, h, FillType );
			if ( !bret )
			{
				String strerr = String.Format( "Error: SetDataType{0}();", FillType );
				MessageBox.Show( strerr );
				return;
			}

			// 書き込み可能ビットマップにデータを仕込む.
			Int32Rect rct = new Int32Rect( 0, 0, w, h );
			int stride_bytes = w * sizeof( byte );
			const int OFFSET_BYTES = 0;
			TheBmp.WritePixels( rct, TheData, stride_bytes, OFFSET_BYTES );

			// ステータスバーのラベルの再描画を要請する.
			this.InvalidateVisual();

		}

		private void menuDebugExec003_Click( object sender, RoutedEventArgs e )
		{

			// タイプ3のデータを仕込む.
			MyUtility myu = new MyUtility();
			int w = TheBmp.PixelWidth;
			int h = TheBmp.PixelHeight;
			FillType = 3;
			bool bret = myu.SetDataTypeN( TheData, w, h, FillType );
			if ( !bret )
			{
				String strerr = String.Format( "Error: SetDataType{0}();", FillType );
				MessageBox.Show( strerr );
				return;
			}

			// 書き込み可能ビットマップにデータを仕込む.
			Int32Rect rct = new Int32Rect( 0, 0, w, h );
			int stride_bytes = w * sizeof( byte );
			const int OFFSET_BYTES = 0;
			TheBmp.WritePixels( rct, TheData, stride_bytes, OFFSET_BYTES );

			// ステータスバーのラベルの再描画を要請する.
			this.InvalidateVisual();

		}
	}
}

下記がウインドウの外観を決める XAML です。

<Window x:Class="aaa.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:aaa"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.CommandBindings>
        <CommandBinding Command="local:CustomCommands.RtdCmdSave" Executed="menuFileSave_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdOpen" Executed="menuFileOpen_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdQuit" Executed="menuApplicationQuit_Click" />

        <CommandBinding Command="local:CustomCommands.RtdCmdDebugExec000" Executed="menuDebugExec000_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdDebugExec001" Executed="menuDebugExec001_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdDebugExec002" Executed="menuDebugExec002_Click" />
        <CommandBinding Command="local:CustomCommands.RtdCmdDebugExec003" Executed="menuDebugExec003_Click" />
    </Window.CommandBindings>
    
    <Window.InputBindings>
        <!-- ここの Gesture でショートカットキーの組み合わせを決定する -->
        <KeyBinding Command="local:CustomCommands.RtdCmdSave" Gesture="Ctrl+S" />
        <KeyBinding Command="local:CustomCommands.RtdCmdOpen" Gesture="Ctrl+O" />
        <KeyBinding Command="local:CustomCommands.RtdCmdQuit" Gesture="Ctrl+Shift+Alt+Q" />

        <!-- ここの Gesture でショートカットキーの組み合わせを決定する -->
        <KeyBinding Command="local:CustomCommands.RtdCmdDebugExec000" Gesture="F5" />
        <KeyBinding Command="local:CustomCommands.RtdCmdDebugExec001" Gesture="F6" />
        <KeyBinding Command="local:CustomCommands.RtdCmdDebugExec002" Gesture="F7" />
        <KeyBinding Command="local:CustomCommands.RtdCmdDebugExec003" Gesture="F8" />
    </Window.InputBindings>
 
    <DockPanel>

        <Menu DockPanel.Dock="Top">

            <MenuItem x:Name="menuApplication" Header="Application">
                <!-- ここのInputGetstureText はメニューの右側に表示される文字列 -->
                <MenuItem x:Name="menuApplicationQuit" Header="Quit" Click="menuApplicationQuit_Click" InputGestureText="コントロール+シフト+オルト+Q"/>
            </MenuItem>

            <MenuItem x:Name="menuFile" Header="File">
                <!-- ここのInputGetstureText はメニューの右側に表示される文字列 -->
                <MenuItem x:Name="menuFileOpen" Header="Open" Click="menuFileOpen_Click" InputGestureText="コントロール+O"/>
                <MenuItem x:Name="menuFileSave" Header="Save" Click="menuFileSave_Click" InputGestureText="コントロール+S"/>
            </MenuItem>

            <MenuItem x:Name="menuDebug" Header="Debug">
                <!-- ここのInputGetstureText はメニューの右側に表示される文字列 -->
                <MenuItem x:Name="menuDebugExec000" Header="Exec000" Click="menuDebugExec000_Click" InputGestureText="エフ5"/>
                <MenuItem x:Name="menuDebugExec001" Header="Exec001" Click="menuDebugExec001_Click" InputGestureText="エフ6"/>
                <MenuItem x:Name="menuDebugExec002" Header="Exec002" Click="menuDebugExec002_Click" InputGestureText="エフ7"/>
                <MenuItem x:Name="menuDebugExec003" Header="Exec003" Click="menuDebugExec003_Click" InputGestureText="エフ8"/>
            </MenuItem>

        </Menu>

        <ToolBarTray DockPanel.Dock="Top">
            <ToolBar>

                <Border BorderBrush="DarkViolet" BorderThickness="1" >
                    <Button x:Name="tbnApplicationQuit" Content="Quit" Width ="48" Height="48" Click="menuApplicationQuit_Click"></Button>
                </Border>

                <Separator />

                <Button x:Name="tbnFileOpen" Content="Open" Width ="48" Height="48" Click="menuFileOpen_Click"></Button>
                <Button x:Name="tbnFileSave" Content="Save" Width ="48" Height="48" Click="menuFileSave_Click"></Button>

                <Separator />

                <Border BorderBrush="DarkViolet" BorderThickness="0.0" >
                    <Button x:Name="tbnDebugExec000" Width ="48" Height="48" Click="menuDebugExec000_Click">
                        <Button.Content>
                            <TextBlock Text="Exec000&#x0a;[F5]" TextAlignment="Center" />
                        </Button.Content>
                    </Button>
                </Border>

                <Border BorderBrush="DarkViolet" BorderThickness="0.1" >
                    <Button x:Name="tbnDebugExec001" Width ="48" Height="48" Click="menuDebugExec001_Click">
                        <Button.Content>
                            <TextBlock Text="Exec001&#x0a;[F6]" TextAlignment="Center" />
                        </Button.Content>
                    </Button>
                </Border>

                <Border BorderBrush="DarkViolet" BorderThickness="0.2" >
                    <Button x:Name="tbnDebugExec002" Width ="48" Height="48" Click="menuDebugExec002_Click">
                        <Button.Content>
                            <TextBlock Text="Exec002&#x0a;[F7]" TextAlignment="Center" />
                        </Button.Content>
                    </Button>
                </Border>

                <Border BorderBrush="DarkViolet" BorderThickness="0.4" >
                    <Button x:Name="tbnDebugExec003" Width ="48" Height="48" Click="menuDebugExec003_Click">
                        <Button.Content>
                            <TextBlock Text="Exec003&#x0a;[F8]" TextAlignment="Center" />
                        </Button.Content>
                    </Button>
                </Border>
            
            </ToolBar>
        </ToolBarTray>

        <StatusBar DockPanel.Dock="Bottom" Height="30">
            <Label x:Name="stbLabel000"/>
            <Separator/>
            <Label x:Name="stbLabel001"/>
            <Separator/>
            <Label x:Name="stbLabel002"/>
            <Separator/>
            <Label x:Name="stbLabel003"/>
        </StatusBar>

        <Border BorderBrush="DarkViolet" BorderThickness="1" >
            <ScrollViewer x:Name="scv000" Background="DarkViolet" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible">
                <Grid x:Name="grid000">
                    <Image x:Name="image000" Stretch="Uniform" />
                    <Canvas x:Name="canvas000" Background="Transparent"/>
                </Grid>
            </ScrollViewer>
        </Border>

    </DockPanel>

</Window>

下記が WriteableBitmap に仕込む byte[] 型のデータをフィルするメソッドを定義したクラスです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace aaa
{

	public class MyUtility
	{
	
		public const int MAX_NUM_TYPE_OF_FILL = 4;

		public MyUtility()
		{
		
		}

		public bool SetDataTypeN( byte [] data, int width, int height, int type_of_fill )
		{
		
			if (!(( 0 <= type_of_fill ) && ( type_of_fill < MAX_NUM_TYPE_OF_FILL )))
			{
				return false;
			}

			if ( data == null ) return false;
			if (( width <= 0 ) || ( height <= 0 )) return false;

			int w = width;
			int h = height;

			bool bret;

			if      ( type_of_fill == 0 ) { bret = set_data_type0( data, w, h ); }
			else if ( type_of_fill == 1 ) { bret = set_data_type1( data, w, h ); }
			else if ( type_of_fill == 2 ) { bret = set_data_type2( data, w, h ); }
			else if ( type_of_fill == 3 ) { bret = set_data_type3( data, w, h ); }
			else                          { return false; }

			return bret;

		}

		private bool set_data_type0( byte [] data, int width, int height )
		{

			if ( data == null ) return false;
			if ( width <= 0 || height <= 0 ) return false;

			int w = width;
			int h = height;

			for ( int j = 0; j < h; j++ )
			{
				int adrs = w * j;
				for ( int i = 0; i < w; i++ )
				{
					data[ adrs ] = (byte)( i + j );
					adrs++;
				}
			}

			return true;
		}

		private bool set_data_type1( byte [] data, int width, int height )
		{

			if ( data == null ) return false;
			if ( width <= 0 || height <= 0 ) return false;

			int w = width;
			int h = height;

			for ( int j = 0; j < h; j++ )
			{
				int adrs = w * j;
				for ( int i = 0; i < w; i++ )
				{
					double rate_x = (double)( i )/(double)( w - 1 );
					data[ adrs ] = (byte)( rate_x * 255.0 );
					adrs++;
				}
			}

			return true;
		}

		private bool set_data_type2( byte [] data, int width, int height )
		{

			if ( data == null ) return false;
			if ( width <= 0 || height <= 0 ) return false;

			int w = width;
			int h = height;

			for ( int j = 0; j < h; j++ )
			{
				double rate_y = (double)(j)/(double)( h - 1 );
				byte v = (byte)( rate_y * 255.0 );

				int adrs = w * j;
				for ( int i = 0; i < w; i++ )
				{
					data[ adrs ] = v;
					adrs++;
				}
			}

			return true;

		}

		private bool set_data_type3( byte [] data, int width, int height )
		{

			if ( data == null ) return false;
			if ( width <= 0 || height <= 0 ) return false;

			int w = width;
			int h = height;

			for ( int j = 0; j < h; j++ )
			{

				double rate_y = (double)( j )/(double)( h - 1 );
				byte v_y = (byte)( rate_y * 128.0 );

				int adrs = w * j;

				for ( int i = 0; i < w; i++ )
				{
					double rate_x = (double)( i )/(double)( w - 1 );
					byte v_x = (byte)( rate_x * 127.0 );
					data[ adrs ] = ( byte )( v_x + v_y );
					adrs++;
				}

			}

			return true;

		}
	}
}