見出し画像

[C#] アプリのパーツを作っておく

最近モチベーションが上がらなくて、プログラムも3Dプリンターも何もしてません。特に体調が悪い訳でなく、本業の方がなんか調子よくてストレスなくて何かやってやろう!って気が起きないだけです。まぁ幸せな感じなんですね。土日が普通に休日になっても何も予定も入れないでただぼーっとしてます。

まぁそれでも何かしようと今回C#のアプリを作るときに毎回やってることを簡単にまとめておこうと作った物です。githubにアップしてあります。


bry.exe 特に意味もないアプリ

C#のパーツを作るためのアプリなので特に意味の無いものですが、一応Javascriptのコードを解釈してその結果を表示する物です。Node.js使えればいらない物です。まぁサンプルなので。

あと、C#と言っても最新の.NET8ではなく.net framework4.8にしてます。
今後のことを考えると.NET8の方がいいのですが、しばらく使って見て、うん何かいろいろトラブルあったり、単純にVSが重いとかで作るのにストレスたまりまくるので.net frameworkで作ってます。同じ理由でWPFじゃなくて古のWinFormsです。

一応インストラーを用意していますが、gtthubでcloneして見るのを想定してます。

[AEdit.cs] Avalon テキストエディタコントロールのWinForm用ラッパー 

ちょっとしたテキスト編集させる為のコントロールにTextBoxがありますが、お世辞に余りいい感じじゃない。昔は使いやすい奴あったのですが、今はほとんどWPF用しかないです。

AvalonEditが今一番使いやすいのですがWPF用なので、ElementHostコントロールでラップして使えるようにした物です。
毎回作ってたので今回まとめました。(AEdit.cs)

AvalonEditはNugetでインストールできます。

特に使い方はググれば分かりますが、ハイライトの設定がWPFだと簡単ですがWinFormだとやっかいです。

Assembly thisAssembly = Assembly.GetExecutingAssembly();
using (Stream resourceStream = thisAssembly.GetManifestResourceStream("bry.JavaScript-Mode.xshd"))
{
	var reader = new System.Xml.XmlTextReader(resourceStream);
	var definition = HighlightingLoader.Load(reader, HighlightingManager.Instance);

	m_editor.SyntaxHighlighting = definition;
}

埋め込みリソースとして定義ファイルをプロジェクトに登録しておいて上記のコードでSyntaxHighlightingプロパティに設定してあげないといけません。これ前の記事のSVGアイコンと同じ手法ですね。
ここではClearScript用にJavaScript-Mode.xshdを適用させてます。
その他の物はここにあります。
入力補完の機能もあるので実装しようと思いましたが、かなり面倒だったのでここまでにしてあります。

[Script.cs] ClearScriptでJavascriptの処理を簡単に

ClesrScriptは入力時に簡単な四則計算させたい時に重宝します。
使うだけなら、V8エンジンクラスを作ってExecuteするだけです。C#にもRoslynというC#言語のスクリプト有りますが、速度が今一で単純な用途にはこれ一択です。これもNuGetでインストールできます。
インストール時には”Microsoft.ClearScript.V8.Native.win-x64"と"Microsoft.ClearScript.V8.Native.win-x86"も一緒にインストールしていきましょう。
https://var.blog.jp/archives/81655681.html
このページ読んでもらえればもう使えます(下のコードはここからの引用です。)

using System;
using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

namespace cs
{
	class Program
	{
		static void Main(string[] args)
		{
			using(var engine = new V8ScriptEngine()){
				var result = engine.Evaluate(@"
					1 + 2
				");
				System.Console.WriteLine(result);
			}
		}
	}
}

上記のコードだとコンソール出力してますが、アプリに使うのに不便だったので、Script.csではTextBoxコントロールに出力する汎用関数を実装しています。

[ScriptUsage(ScriptAccess.None)]
public void Init()
{
	if (engine != null) engine.Dispose();
	engine = new V8ScriptEngine();
	//engine.AddHostObject("dotnet", new HostTypeCollection("mscorlib", "System.Core"));
	engine.AddHostObject("App", HostItemFlags.GlobalMembers, this);
}
// ****
[ScriptUsage(ScriptAccess.None)]
public void ExecuteCode(string s)
{
	if (engine == null) Init();
	try
	{
		engine.Execute(s);
	}
	catch (Exception e) when (e is IScriptEngineException ex)
	{
	
		writeln(ex.ErrorDetails);
	}
}

InitメソッドのV8ScriptEngineの初期化、ExecuteCodeメソッドでコードの実行を行っています。
実行毎に初期化しないのは、グローバルな変数とかを残しておくためわざとです。
AddHostObjectで自分自身のクラスの実態をスクリプトエンジンに登録しています。このクラスに以下のように関数を定義しておけばスクリプトコードの中でグローバルな関数として使えます。以下の例はm_outputBoxというTextBoxコントロールに文字列を表示させる物です。objectToString関数は、objectをいい感じに文字列に変えてくれるC#の関数になります。

public void write(object s)
{
	if (m_outputBox != null)
	{
		m_outputBox.AppendText(objectToString(s));
	}
}

AddHostObjectは指定した名前空間に割り当てる物ですが、HostItemFlags.GlobalMembersを指定することでrootに割り当てられます。

この関数はスクリプトで使われたくないメソッドは[ScriptUsage(ScriptAccess.None)]を指定して除外させてます。
あと、コード実行時のエラーは例外処理で分岐した後、スクリプト独自の例外だけを読み込んで表示させてます。

スクリプトに解放している関数は、以下の物があります。命名規則はJavascript準拠です。

  • write(string)
    文字出力

  • writeln(string) 
    改行付き文字出力

  • cls()
    文字をすべて消去

  • toHex(value,byteLength,endianness)
    数値を16進文字列に int32
    byteLength 数値のバイト数  1/2/3/4
    endianness バイトオーダーの切り替えBoolean

  • alert(object)
    alertダイアログに表示

[PrefFile] JSONを使った簡単な設定ファイルクラス

System.Text.Jsonを使った簡単な環境設定ファイルを扱うクラスです。
もともと前から作っててバージョン違いがいっぱい出来てしまったのでここでまとめてます。
使い方はなるべく簡単になるように以下の通り

PrefFile pf = new PrefFile(this); // thisはForm
pf.SetValue("Code", editorForm.editor.Text);
pf.SetValue("FontFamily", editorForm.Font.Name);
pf.SetValue("FontSize", (double)editorForm.Font.Size);
pf.StoreForm(); //Formの位置サイズの保存
pf.Save(); //保存
//*********
pf.Load(); // 読み込み
pf.RestoreForm(); //Formの位置サイズの読み込み

bool ok = false;
object v;
v = pf.GetValueString("Code", out ok);
if (ok) { editorForm.editor.Text = (string)v; }

string nf = pf.GetValueString("FontFamily", out ok);
if (ok == false)
{
	nf = this.Font.Name;
}
double sf = pf.GetValueDouble("FontSize", out ok);
if (ok == false)
{
	sf = 12;
}

インストラー

インストラーのサンプルも入れています。
これはもう簡単なのでググってね。setup用のプロジェクトのテンプレートが標準であるのでそれを使うだけです。標準ではなく「拡張機能の管理」から
DLとインストールが必要でした(忘れてた)
拡張機能の管理から、[Microsoft Visual Studio Installer Projects 2022]を選んでインストールします。

DockPanelSuite

ドッキングパネルを実装する奴です。これも使い方は簡単です。
.NET8にはまだ対応していないので未だに.net framework使ってる理由でもあります。
NuGetでインストール出来ます。
使い方はググればいっぱいサンプル出てきます。ただ、最近のバージョンでは、dockPanel.Themeを設定しておかないと実行時エラーになるので、テーマはNuGetで別にインストールしておかないといけない(DockPanelSuite.ThemeVS2015

	dockPanel1.Theme = new WeifenLuo.WinFormsUI.Docking.VS2015DarkTheme();

久しぶりに使ったらエラーでビルド出来なくて一瞬はまりました。

最後に

最近休日は何もしないでぼーっとしてるので、これはいけないと急遽でっち上げた記事です。
NF_Pluginも途中だし。
最近仕事で悩みがないのでその反動かな?仕事でストレスあるとその解消でいろいろ作るので、いいって事なんでしょうか?
まぁいいか(^_^)/


この記事が気に入ったらサポートをしてみませんか?