トップ 最新の日記 ユーザー登録 ログイン ヘルプ

AzukiPochette@EA Club

2008-05-25

コードスニペットのVB.NET版をこっそり開発中です。

まずは VB.NETのコードを..。(これに2時間かかりました...慣れてないって大変ですね。)

Imports System

Public Class CodeSnippet

    Public Function EA_Connect(ByVal repository As EA.Repository) As String
    End Function 'EA_Connect

    Public Sub EA_Disconnect()
        ' code 

        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub 'EA_Disconnect

    Public Sub EA_FileClose(ByVal repository As EA.Repository)
    End Sub 'EA_FileClose

    Public Sub EA_FileOpen(ByVal repository As EA.Repository)
    End Sub 'EA_FileOpen

    Public Function EA_GetMenuItems(ByVal repository As EA.Repository, ByVal menuLocation As String, ByVal menuName As String) As Object
    End Function 'EA_GetMenuItems

    Public Sub EA_GetMenuState(ByVal repository As EA.Repository, ByVal menuLocation As String, ByVal menuName As String, ByVal itemName As String, ByRef isEnabled As Boolean, ByRef isChecked As Boolean)
    End Sub 'EA_GetMenuState

    Public Sub EA_MenuClick(ByVal repository As EA.Repository, ByVal menuLocation As String, ByVal menuName As String, ByVal itemName As String)
    End Sub 'EA_MenuClick

    Public Sub EA_OnContextItemChanged(ByVal repository As EA.Repository, ByVal guid As String, ByVal ot As EA.ObjectType)
    End Sub 'EA_OnContextItemChanged

    Public Function EA_OnContextItemDoubleClicked(ByVal repository As EA.Repository, ByVal guid As String, ByVal ot As EA.ObjectType) As Boolean
    End Function 'EA_OnContextItemDoubleClicked

    Public Sub EA_OnDeleteTechnology(ByVal repository As EA.Repository, ByVal info As EA.EventProperties)
    End Sub 'EA_OnDeleteTechnology

    Public Sub EA_OnImportTechnology(ByVal repository As EA.Repository, ByVal info As EA.EventProperties)
    End Sub 'EA_OnImportTechnology

    Public Sub EA_OnNotifyContextItemModified(ByVal repository As EA.Repository, ByVal repository As String, ByVal ot As EA.ObjectType)
    End Sub 'EA_OnNotifyContextItemModified

    Public Sub EA_OnOutputItemClicked(ByVal repository As EA.Repository, ByVal tabName As String, ByVal lineText As String, ByVal id As Integer)
    End Sub 'EA_OnOutputItemClicked

    Public Sub EA_OnOutputItemDoubleClicked(ByVal repository As EA.Repository, ByVal tabName As String, ByVal lineText As String, ByVal id As Integer)
    End Sub 'EA_OnOutputItemDoubleClicked

    Public Function EA_OnPostNewAttribute(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPostNewAttribute

    Public Function EA_OnPostNewConnector(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPostNewConnector

    Public Function EA_OnPostNewElement(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPostNewElement

    Public Function EA_OnPostNewMethod(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPostNewMethod

    Public Function EA_OnPostNewPackage(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPostNewPackage

    Public Function EA_OnPreDeleteConnector(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreDeleteConnector

    Public Function EA_OnPreDeleteDiagram(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreDeleteDiagram

    Public Function EA_OnPreDeleteElement(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreDeleteElement

    Public Function EA_OnPreDeletePackage(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreDeletePackage

    Public Function EA_OnPreDeleteTechnology(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreDeleteTechnology

    Public Function EA_OnPreNewAttribute(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreNewAttribute

    Public Function EA_OnPreNewConnector(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreNewConnector

    Public Function EA_OnPreNewElement(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreNewElement

    Public Function EA_OnPreNewMethod(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreNewMethod

    Public Function EA_OnPreNewPackage(ByVal repository As EA.Repository, ByVal info As EA.EventProperties) As Boolean
    End Function 'EA_OnPreNewPackage

    Public Sub EA_ShowHelp(ByVal repository As EA.Repository, ByVal menuLocation As String, ByVal menuName As String, ByVal itemName As String)
    End Sub 'EA_ShowHelp

End Class 'CodeSnippet 

2007-01-16

続「アドインメニューをデザイナで作る」

以前、私のブログで紹介したFormデザイナを利用したメニュー作成ですが、

その後、拡張してメニュー関連の下記の処理をすべてデザイナ側で行えるように拡張しました。

  • EA_GetMenuItems
  • EA_GetMenuState
  • EA_MenuClick

これにより、メニューの構造だけでなく、メニューの有効・無効、チェック状態を簡単に行うことができます。

また、複雑になりがちだった EA_MenuClick 関数も各メニュー要素の Click イベントを利用することができます。

Click イベントは、メニュー項目をダブルクリックすることで自動的生成できます)

下記に、変換クラスソースコードと使用例を示しますので、ご利用頂ければと思います。


# この機能は、別途作成している「アドインテンプレート」にも追加する予定です。


MenuStripToEAAddInMenu.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Reflection;

namespace AzukiPochette.EnterpriseArchitect.AddIn
{
    /// <summary>
    /// MenuStrip から Enterprise Architect アドインのメニューへの変換を提供します。
    /// </summary>
    class MenuStripToEAAddInMenu
    {
        #region 子クラス

        /// <summary>
        /// EnterpriseArchitect 向けメニューの情報を提供します。
        /// </summary>
        class EA_MenuItemInfo
        {
            #region フィールド

            /// <summary>
            /// メニュー項目名です。
            /// </summary>
            public readonly string Name;

            /// <summary>
            /// ToolStripItem のインスタンスです。
            /// </summary>
            public readonly ToolStripItem Item;

            #endregion

            #region 構築

            /// <summary>
            /// ToolStripItemInfo を構築します。
            /// </summary>
            /// <param name="name">メニュー項目名</param>
            /// <param name="item">インスタンス</param>
            public EA_MenuItemInfo(string name, ToolStripItem item)
            {
                Name = name;
                Item = item;
            }

            /// <summary>
            /// ToolStripItemInfo を構築します。
            /// </summary>
            /// <param name="item">構築対象の ToolStripMenuItem 。</param>
            public EA_MenuItemInfo(ToolStripMenuItem item)
            {
                Item = item;
                Name = (item.DropDownItems.Count >= 1) ? item.Text.Insert(0, "-") : item.Text;
            }

            #endregion
        }

        #endregion

        #region フィールド
        
        Dictionary<string, List<EA_MenuItemInfo>> _ToolStripMenuTable = new Dictionary<string, List<EA_MenuItemInfo>>();

        #endregion

        #region 構築

        /// <summary>
        /// MenuStripToEAAddInMenu のインスタンスを構築します。
        /// </summary>
        /// <param name="menuStrip">MenuStrip クラスのインスタンス</param>
        public MenuStripToEAAddInMenu(MenuStrip menuStrip)
        {
            if (menuStrip.Items.Count != 1) throw new ArgumentException("ルートレベルには 1 つのメニュー項目のみが可能です。");

            ToolStripMenuItem menuItem = menuStrip.Items[0] as ToolStripMenuItem;
            if (menuItem == null) throw new ArgumentException("ルートレベルに ToolStripMenuItem が必要です。");

            List<EA_MenuItemInfo> rootList = new List<EA_MenuItemInfo>();
            rootList.Add(new EA_MenuItemInfo(menuItem));
            this._ToolStripMenuTable.Add("", rootList);

            this.AddMenuItemsToToolStripMenuTable(menuItem);
        }

        #endregion

        #region メソッド

        /// <summary>
        /// 管理テーブルに対してメニューを再帰的に追加します。
        /// </summary>
        /// <param name="menuTable">管理テーブル</param>
        /// <param name="toolStripMenuItem">追加する toolStripMenuItem</param>
        private void AddMenuItemsToToolStripMenuTable(ToolStripMenuItem toolStripMenuItem)
        {
            List<EA_MenuItemInfo> menuList = new List<EA_MenuItemInfo>();

            ToolStripItemCollection items = toolStripMenuItem.DropDownItems;
            foreach (ToolStripItem item in items)
            {
                // ToolStripItem が ToolStripMenuItem であるかを検証
                ToolStripMenuItem menuItem = item as ToolStripMenuItem;
                if (menuItem == null)
                {
                    // セパレータの場合は"-"として追加
                    ToolStripSeparator separator = item as ToolStripSeparator;
                    if (separator == null) throw new ArgumentException("変換できない ToolStripItem が含まれています。");

                    menuList.Add(new EA_MenuItemInfo("-", separator));
                    continue;
                }

                if (menuItem.DropDownItems.Count >= 1) this.AddMenuItemsToToolStripMenuTable(menuItem);

                menuList.Add(new EA_MenuItemInfo(menuItem));
            }
            
            if (this._ToolStripMenuTable.ContainsKey(toolStripMenuItem.Text)) throw new ArgumentException("分岐に使用されるメニュー名に重複があります。");
            
            this._ToolStripMenuTable.Add(toolStripMenuItem.Text.Insert(0,"-"), menuList);
        }

        /// <summary>
        /// リストから対象の ToolStripItem を取得します。
        /// </summary>
        /// <param name="items">検索対象のリスト</param>
        /// <param name="name">メニュー項目名</param>
        /// <returns>一致した場合は対象の ToolStripItem のインスタンス。それ以外は null を返します。</returns>
        private ToolStripItem GetToolStripItem(List<EA_MenuItemInfo>items, string name)
        {
            foreach (EA_MenuItemInfo item in items)
            {
                if (item.Name == name) return item.Item;
            }

            return null;
        }

        /// <summary>
        /// メニュー項目の名前を取得します。
        /// </summary>
        /// <param name="menuName">親メニューの項目名です。/param>
        /// <returns>メニュー項目名の配列</returns>
        public string[] EA_GetMenuItems(string menuName)
        {
            List<EA_MenuItemInfo> items = this._ToolStripMenuTable[menuName];
            if (items == null) return null;

            List<string> menuNames = new List<string>();
            foreach (EA_MenuItemInfo item in items)
            {
                menuNames.Add(item.Name);
            }

            return menuNames.ToArray();
        }

        /// <summary>
        /// メニュー項目の選択可能の有無を指定します。
        /// </summary>
        /// <param name="menuName">親メニューの項目名です。</param>
        /// <param name="itemName">実際に選択されたメニュー項目名です。</param>
        /// <param name="isEnabled">メニュー項目を有効にする場合は true 。それ以外は false を返します。</param>
        /// <param name="isChecked">メニュー項目をチェックする場合は true 。それ以外は false を返します。</param>
        public void EA_GetMenuState(string menuName, string itemName, ref bool isEnabled, ref bool isChecked)
        {
            List<EA_MenuItemInfo> menuList = this._ToolStripMenuTable[menuName];
            if (menuList == null) return;

            ToolStripMenuItem menuItem = this.GetToolStripItem(menuList, itemName) as ToolStripMenuItem;
            if (menuItem == null) return;

            isEnabled = menuItem.Enabled;
            isChecked = menuItem.Checked;
        }

        public void EA_MenuClick(string menuName, string itemName)
        {
            List<EA_MenuItemInfo> menuList = this._ToolStripMenuTable[menuName];
            if (menuList == null) return;

            ToolStripItem menuItem = this.GetToolStripItem(menuList, itemName) as ToolStripItem;
            if (menuItem == null) return;

            menuItem.PerformClick();
        }

        #endregion
    }
}

使用例

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using AzukiPochette.EnterpriseArchitect.AddIn;
using EA;

namespace YourCompanyName.EnterpriseArchitect
{
    public class MenuSample
    {
        MenuStripToEAAddInMenu _EA_MenuItem = null;

        public MenuSample()
        {
            UserControl1 control = new UserControl1();
            this._EA_MenuItem = new MenuStripToEAAddInMenu(control.MenuStrip);
        }

        public object EA_GetMenuItems(EA.Repository repository, string menuLocation, string menuName)
        {
            return this._EA_MenuItem.EA_GetMenuItems(menuName);
        }

        public void EA_GetMenuState(EA.Repository repository, string menuLocation, string menuName, string itemName, ref bool isEnabled, ref bool isChecked)
        {
            this._EA_MenuItem.EA_GetMenuState(menuName, itemName, ref isEnabled, ref isChecked);
        }

        public void EA_MenuClick(EA.Repository repository, string menuLocation, string menuName, string itemName)
        {
            this._EA_MenuItem.EA_MenuClick(menuName, itemName);
        }
    }
}

2007-01-10

スクリプト仕事を3倍早くする

スクリプト開発のススメ

API 自体はヘルプにある通り、 ActiveX COM を利用出来る言語であれば使用できます。

通常、Windowsの場合は WSH と呼ばれるスクリプトホストインストールされており、これを使用する事で便利なスクリプトが作成できます。

つまり、特別な環境は必要なく、メモ帳プログラムを作成できるのです。

具体的な作成方法は本エントリでは取り上げませんが、私の愛読しているWSH書籍を紹介しますので、参考にしてください。

WSHクイックリファレンス 第2版

WSHクイックリファレンス 第2版

開発言語デフォルトJScript(JavaScript), VBScript(VisualBasic)がありますが、他にも Active Perl等のアプリケーションインストールすることで様々なスクリプト言語で開発することが出来ます。

スクリプトの応用範囲

例えば、作成した要素の一覧が欲しいような場合、アドインを作成するのは「やや大げさ」な感じがしませんか。

スクリプトであれば、作成や配布も容易で、アンインストールを考える必要も有りません。

また、「作成中の要素数」で進捗状況を自動的に調べたい、というような場合は Windowsタスク機能と連携することで、自動化することが出来るでしょう。

作成者は喜ばないかもしれませんが(笑)ルール違反の作成者にメールで報告するような自動ツールの作成も可能です。

サンプル

これからスクリプトを作成される方への参考として、ヘルプのサンプルコードリポジトリを開く」と「プロジェクトファイル内を探索する」をスクリプトで書いてみました。

これを下記のように実行すると、プロジェクトツリーがテキストファイルで取得出来ます。(サンプルコードdump.js で C:\ に保存した場合)

C:\> dump.js >> result.txt 

サンプルコードは以下の通りです。

function DumpModel()
{
    for (var i = 0; i < repository.Models.Count; i++)
    {
        DumpPackage('', repository.Models.GetAt(i));
    }
}

function DumpPackage(indent, objPackage)
{
    WScript.Echo(indent + objPackage.Name);
    DumpElements(indent + '    ', objPackage);
    
    for (var i = 0; i < objPackage.Packages.Count; i++)
    {
        DumpPackage(indent + '    ', objPackage.Packages.GetAt(i));
    }
}

function DumpElements(indent, objPackage)
{
    for (var i = 0; i < objPackage.Elements.Count; i++)
    {
        WScript.Echo(indent + '::' + objPackage.Elements.GetAt(i).Name);
    }
}


// リポジトリオブジェクトの新規作成
var repository = WScript.CreateObject('EA.Repository');

// 対象となる EAP ファイルを開く
repository.OpenFile('C:\\SMOD\.EAP');

// モデルの列挙
DumpModel();

// リポジトリオブジェクトを閉じる
repository.Exit();

2007-01-07

Vista でアドインを開発するポイント

Vista開発時に発生する問題

Vista では Program Files へのコピー(移動)及びアセンブリの登録(RegAsm)の実行に管理者権限が必要です。

対策

バッチファイルを作成した場合はショートカットを作成し、下記の手順で管理者権限で実行するように設定すると便利です。

  1. ショートカットプロパティを開きます
  2. ショートカット」タブを開き、「詳細設定」ボタン押します
  3. 「管理者として実行」にチェックし保存します。