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のInitiali
zeComponent()を呼び出す方法がわからずに困っています。

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

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

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-compatibilit
y/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 + @"\TextIns
ert.dll", "TextInsert.UserControl1", "OnDeathMethod" );
#r = dllfuncw( #HMNET, "CallMethod", currentmacrodirectory + @"\TextInsert.d
ll", "TextInsert.UserControl1", "StartWPF" );

[ ]
RE:08670 hm.NETを使って、WPF-UIを持つdlNo.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を持つdlNo.08672
vscode-life さん 18/04/17 18:18
 
WPF系ライブラリを利用して、ごりごりイチから記述するという手もあります。

(参照として、「PretentationCore, PresentationFramework, System.Windows, Wind
owsBase」の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 + @"\HmWPFTe
st.dll", "HmWPFTest.MyEntry", "OnDetathMethod" );
#r = dllfuncw( #HMNET, "CallMethod", currentmacrodirectory + @"\HmWPFTest.dl
l", "HmWPFTest.MyEntry", "CreateForm" );



[ ]
RE:08672 hm.NETを使って、WPF-UIを持つdlNo.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を持つdlNo.08674
kuke さん 18/04/17 21:08
 
vscode-life さん

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

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

[ ]