[ 新規に投稿する ]

hm.NETを使って、WPF-UIを持つdllを呼び出したい。No.08670
kuke さん 18/04/17 16:50 [ コメントを投稿する ]
  hm.NETを使って、WPF-UIを持つdllを呼び出したい。

hm.NETを使って、WPF-UIを持つdllを呼び出したいと考えています。

そこで、Visual Studio 2017 communityを使って、「WPFユーザーコントロールライブラリ」プロジェクト・テンプレートを使ってC#のdllの作成をしようとしました。

秀丸エディタのマクロから呼び出すメソッド「StartWPF()」から、C# WPFのInitializeComponent()を呼び出す方法がわからずに困っています。

解決方法を教えていただけないでしょうか?

***********************
行った手順

Visual Studio 2017 communityを使って、「WPFユーザーコントロールライブラリ」プロジェクト・テンプレートを使ってソリューションを新規作成しました。

参照に、「hm.NET.dll」を追加し、

UserContral.xamlを以下のように記述しました。

<UserControl x:Class="TextInsert.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008
             xmlns:local="clr-namespace:TextInsert"
             mc:Ignorable="d" 
             d:DesignHeight="150" d:DesignWidth="200">
    
    <Grid>
        <Button Name="btn0" HorizontalAlignment="Center" VerticalAlignment="Center" 
        Width="100" Height="50" Click="btn0_Click">
            押してね。
        </Button>
    </Grid>
    
</UserControl>

続いて、UserContral.xaml.csを記述したところで、秀丸エディタのマクロから呼び出すメソッドから、InitializeComponent()を実行する方法がわからないことに気が付きました。

using Hidemaru;
using System;
using System.Windows;
using System.Windows.Controls;

namespace TextInsert
{
    /// <summary>
    /// UserControl1.xaml の相互作用ロジック
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }


        private void btn0_Click(object sender, RoutedEventArgs e)
        {
            // カーソル位置にテキストを挿入
            Hm.Edit.LineText = "テスト&#9836;";
        }

        public static IntPtr OnDeathMethod()
        {
            // 秀丸エディタが終了するさい呼び出されるメソッド
            Application.Current.Shutdown();

            return (IntPtr)1;
        }

        public static IntPtr StartWPF()
        {
            // 秀丸エディタマクロから呼び出すメソッド
   // ********************
            // どうやって、InitializeComponent()を実行すればよいのかわからない。
   // ********************

            return (IntPtr)1;
        }

    }
}

秀丸エディタで作成したdllを呼び出すマクロ

#HMNET = loaddll( hidemarudir + @"\hm.NET.dll" );
 
#r = dllfuncw( #HMNET, "SetDetachMethod", currentmacrodirectory + @"\TextInsert.dll", "TextInsert.UserControl1", "OnDeathMethod" );
#r = dllfuncw( #HMNET, "CallMethod", currentmacrodirectory + @"\TextInsert.dll", "TextInsert.UserControl1", "StartWPF" );
[ ]
RE:08670 hm.NETを使って、WPF-UIを持つdllを呼び出したい。No.08671
vscode-life さん 18/04/17 18:14 [ コメントを投稿する ]
  アセンブリの性質上、exeでもdllでも、
publicであれば、APIがほとんど透過に扱えますので、

WPFを普通にVisual Studioで作成したとして、(下記例ではWpfApp2)

MyEntiryのようなものを付け加えれば、
取り扱いやすいと思います。

(MainWindow 自体に入れてしまってもかまいませんが、
APIインターフェイスの層として分けておいたほうが良いと思います。
※ partialで分けるでも良いとおもいます)


//------------------ MainWindow.xaml.cs の編集の例

namespace WpfApp2
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }


    public class MyEntry
    {
        public static System.Windows.Window form;

        public static IntPtr CreateForm()
        {
            if (form == null || form.Visibility == Visibility.Hidden)
            {
                form = new MainWindow();
            }

            form.Show();
            return (IntPtr)1;
        }

        public static IntPtr OnDetathMethod()
        {
            if (form != null)
            {
                form.Close();
                form = null;
            }

            return (IntPtr)1;
        }
    }
}

//------------------ testtest.mac (呼び出しマクロ)

#HMNET = loaddll( hidemarudir + @"\hm.NET.dll" );
 
#r = dllfuncw( #HMNET, "SetDetachMethod", currentmacrodirectory + @"\WpfApp2.exe", "WpfApp2.MyEntry", "OnDetathMethod" );
#r = dllfuncw( #HMNET, "CallMethod", currentmacrodirectory + @"\WpfApp2.exe", "WpfApp2.MyEntry", "CreateForm" );

[ ]
RE:08671 hm.NETを使って、WPF-UIを持つdllを呼び出したい。No.08672
vscode-life さん 18/04/17 18:18 [ コメントを投稿する ]
  WPF系ライブラリを利用して、ごりごりイチから記述するという手もあります。

(参照として、「PretentationCore, PresentationFramework, System.Windows, WindowsBase」の4つが必要です。




using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace HmWPFTest
{
    public class HmWPFTestClass : System.Windows.Window
    {
        public HmWPFTestClass()
        {
            SetForm();
            SetButton();
        }

        Canvas c;
        void SetForm()
        {
            this.Title = "秀丸マクロ hmPyによるWPFに組み込むWPF";
            this.FontSize = 22;
            this.Width = 1000;
            this.Height = 500;
            c = new Canvas();
            this.Content = c;
        }

        Button btn;
        void SetButton()
        {
            var ef = new System.Windows.Media.Effects.DropShadowEffect
            {
                BlurRadius = 5,
                ShadowDepth = 1
            };

            btn = new Button()
            {
                Content = "秀丸",
                Padding = new System.Windows.Thickness(2),
                Effect = ef,
                Foreground = Brushes.White,
                Background = Brushes.Black
            };

            btn.Click += Btn_Click;
            c.Children.Add(btn);
            Canvas.SetLeft(btn, 30);
            Canvas.SetTop(btn, 100);
        }

        private void Btn_Click(object sender, RoutedEventArgs e)
        {
            // 未実装なので例外処理が走る
            throw new NotImplementedException();
        }
    }

    public class MyEntry
    {
        public static System.Windows.Window form;

        public static IntPtr CreateForm()
        {
            if (form == null || form.Visibility == Visibility.Hidden)
            {
                form = new HmWPFTestClass();
            }

            form.Show();
            return (IntPtr)1;
        }

        public static IntPtr OnDetathMethod()
        {
            if (form != null)
            {
                form.Close();
                form = null;
            }

            return (IntPtr)1;
        }

    }
}


//-------------------------- callmytest.mac --------------------

#HMNET = loaddll( hidemarudir + @"\hm.NET.dll" );
 
#r = dllfuncw( #HMNET, "SetDetachMethod", currentmacrodirectory + @"\HmWPFTest.dll", "HmWPFTest.MyEntry", "OnDetathMethod" );
#r = dllfuncw( #HMNET, "CallMethod", currentmacrodirectory + @"\HmWPFTest.dll", "HmWPFTest.MyEntry", "CreateForm" );


[ ]
RE:08672 hm.NETを使って、WPF-UIを持つdllを呼び出したい。No.08673
vscode-life さん 18/04/17 18:39 [ コメントを投稿する ]
  WPFだと、一度閉じてしまったインスタンスをそのままShow()すると
エラーが出てしまうようなので、CreateForm(...) のところは、


        public static IntPtr CreateForm()
        {
            if (form != null) {
                form.Close();
                form = null;
            }
            form = new HmWPFTestClass();
            form.Show();
            return (IntPtr)1;
        }


みたいな感じにする必要がありそうです。
(あるいはWPF側で閉じる処理をした時に本当にウィンドウを閉じてしまうのではなくHiddenするだけにするとか)
[ ]
RE:08673 hm.NETを使って、WPF-UIを持つdllを呼び出したい。No.08674
kuke さん 18/04/17 21:08 [ コメントを投稿する ]
  vscode-life さん

ありがとうございました。おかげさまで、wpfウィンドウを秀丸マクロから表示することができました。また、秀丸エディタを閉じると、wpfウィンドウが閉じることも確認できました。

dllではなく、exeでも問題なくhm.netから、呼び出すことができました。これで、hm.netを使って、いろいろ楽しめそうです。
[ ]

[ 新規に投稿する ]