「マクロメニュー」の版間の差分

提供:MeryWiki
ナビゲーションに移動 検索に移動
(ページを新規作成)
 
(更新 第2版)
1行目: 1行目:
標準メニューバーの「マクロ(M)」には表示されないマクロを含めて、「マクロのカスタマイズ」に登録済みのすべてのマクロをポップアップメニューで表示します。
標準メニューバーの「マクロ(M)」には表示されないマクロを含めて、「マクロのカスタマイズ」に登録済みのすべてのマクロをポップアップメニューで表示します。
<br>
<br>
* 通常では非表示扱いのマクロは、「非表示マクロ」サブメニュー内に表示します。
* 「マクロのカスタマイズ」で <q>☑ なし</q> のマクロ(ツールバーのマクロメニューで非表示扱い)は、<span style="color:#0000c0;">「非表示マクロ」サブメニュー</span>内に表示します。
* マクロ名はファイル名で表示します(各ソースコード内の #title="Hoge" を読みこみません)。
* <span style="color:#0000c0;">マクロ名は '''ファイル名''' で表示します</span>(各ソースコード内の <syntaxhighlight lang="javascript" inline>#title="Hoge"</syntaxhighlight> を読みこみません)。
: ファイル名 「1 マクロ1.js」 「2.マクロ2.js」 「3_マクロ3.js」 「4. マクロ4.js」 などの先頭の連番部分と拡張子をポップアップメニュー上に表示させないように設定できるので、通常のマクロメニューと同じような状態にできます。
: 各マクロの実体ファイルの親フォルダ名を表示できます。
* 各マクロの実体ファイルの親フォルダ名を表示できます。
: ファイル名 「1 マクロA.js」 「2. マクロB.js」 「3_マクロC.js」 「4 - マクロD.js」 などの先頭の連番部分と拡張子をポップアップメニュー上に表示させないように設定できるので、通常のマクロメニューと同じような状態にできます。
* [選択] や [これを選択] で登録したマクロがメニューに表示されない場合は、 [カスタマイズ] ダイアログを開いて <kbd>OK</kbd> ボタンで確定すると表示されるようになります。
* [選択] や [これを選択] で登録したマクロがメニューに表示されない場合は、 [カスタマイズ] ダイアログを開いて <kbd>OK</kbd> ボタンで確定すると表示されるようになります。
 
<br>
 
* 追加コマンド [このマクロを実行] は、アクティブなタブのマクロを実行するためのコマンドです。
: ※ マクロ用と判別できる拡張子で保存済みのタブでのみ使用できます。<br> 拡張子に対して正規表現 <syntaxhighlight lang="javascript" inline>/^(?:jse?|pls?|php|pys?|rbs?|vb[es])$/i</syntaxhighlight> でチェックします。
<br>
* 追加コマンド [Macros フォルダを開く] は、Mery インストールフォルダ内の "Macros" フォルダをファイラ(エクスプローラ)で開くためのコマンドです。
<br><br>
<div class="warningbox">
*「[[GetKeyState.exe(キー状態取得実行ファイル)]]」を導入すると、<kbd>Ctrl</kbd> キーを押しながらこのマクロを起動したときに、ポップアップメニュー内のマクロ名を選択(クリック/Enter)したさいの処理を変更できます。<br><b> ⇒ 選択したマクロを Mery で開く</b>(編集する)
: Mery インストールフォルダ内の '''Macros''' フォルダに実行ファイル GetKeyState.exe を配置してください <br> (または、設定項目 <syntaxhighlight lang="javascript" inline>var gksPath</syntaxhighlight> でフルパスを指定)。
: <span style="color:#c00;">※ GetKeyState.exe を導入していないばあいは、選択したマクロをそのまま実行します。</span>
: マクロの自作・編集をしない人には設定項目 <syntaxhighlight lang="javascript" inline>var gksEnable = false;</syntaxhighlight>  にすることをおすすめします(ポップアップメニューの表示が高速化するはず)。
</div>
<br><br>
== ソースコード ==
== ソースコード ==


; ダウンロード >> 「[[ファイル:マクロメニュー.zip]]」(アイコン入り)
<b> ダウンロード >> 「[[ファイル:マクロメニュー.zip]]」</b>(アイコン入り、第2版: 2020/05/02)


<source lang="javascript">
<source lang="javascript" style="height:60em; overflow:auto;" highlight="18-36,123">
#title = "マクロメニュー..."
#title = "マクロメニュー..."
#tooltip = "全マクロをポップアップメニュー表示"
#tooltip = "全マクロをポップアップメニュー表示"
#icon = "script_with_lines+.ico"
// #icon = "script_with_lines+.ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",318


/**
/**
* ---------------------------------------------------------
* マクロメニュー
* sukemaru, 2019/11/02 - 2020/05/02
* ---------------------------------------------------------
  * 非表示マクロを含めて全ての登録済みマクロをポップアップメニューで表示する。
  * 非表示マクロを含めて全ての登録済みマクロをポップアップメニューで表示する。
  *  
  *  
  * ※ マクロ名はファイル名で表示(各ソースコード内の #title を読みこまない)。
  * Ctrl キーを押しながら「マクロメニュー」マクロを起動して (要 GetKeyState.exe)
* ※ ファイル名 「1 マクロ1.js」 「2.マクロ2.js」 「3_マクロ3.js」 「4. マクロ4.js」 の
  * ポップアップメニュー内のマクロを選択したときは、ソースコードを Mery で開く。
*    先頭の連番部分と拡張子をポップアップメニュー上に表示させないようにできる。
* ※ [選択] や [これを選択] で登録したマクロがメニューに表示されない場合は、
  *   [カスタマイズ] ダイアログを開いて [ OK ] ボタンで確定すると表示されるようになる。
  */
  */


33行目: 46行目:


// ■ 各マクロの親フォルダ名を表示する
// ■ 各マクロの親フォルダ名を表示する
var showParentFolderName = false; // (true: 表示する / false: 表示しない)
var showParent = false; // (true: 表示する / false: 表示しない)


// ■ 各マクロの拡張子を表示しない(※ファイル名先頭の連番部分も表示しない)
// ■ 各マクロの拡張子を表示しない(※ファイル名先頭の連番部分も表示しない)
var trimExtension = false; // (true: 表示しない / false: 表示する)
var trimExt = false; // (true: 表示しない / false: 表示する)
 
// ■ GetKeyState.exe による機能拡張を使用する
var gksEnable = true;
 
// ■ GetKeyState.exe のフルパスを指定する場合
var gksPath = "";
  // 未指定 "" なら、Mery インストールフォルダの Macros\GetKeyState.exe
  // ※ GetKeyState.exe なしのときも "" にする
  // ※ \ 記号はふたつがさね「\\」で記述すること


// ---------- ▲ 設定項目 ▲ ---------- //
// ---------- ▲ 設定項目 ▲ ---------- //
var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
var WshShell = new ActiveXObject( "WScript.Shell" );
var meryPath = editor.FullName;
var meryDir = meryPath.replace( /[^\\]+$/, "" );
var macroDir = meryDir + "Macros\\";
var currentDir = WshShell.CurrentDirectory;
var macroPath = filePath = editor.ActiveDocument.FullName;
// GetKeyState.exe
var gks  = gksPath || macroDir + "GetKeyState.exe";
var $ctrl = ( gksEnable && Fso.FileExists( gks ) &&
            WshShell.Run( '"' + gks + '" ctrl', 0, true ) != 0 )
          ? true : false;




// ポップアップメニューを表示
// ポップアップメニューを表示
var r = MacroMenu( showParentFolderName, trimExtension ).Track( menuPosMouse );
var mm = MacroMenu( showParent, trimExt, $ctrl );
if ( r > 0 ) {
var id = mm.menu.Track( menuPosMouse );
   // マクロを実行
 
  editor.ExecuteCommandByID( r );
// 「このマクロを実行」
if ( id == 1 ) {
   WshShell.Run( '"' + meryPath + '" /mf "' + macroPath + '" "' + filePath + '"' );
}
}


// 「Macros フォルダを開く」
else if ( id == 2 ) {
  WshShell.Run( '"' + macroDir + '"' );
  Status = " " + macroDir;
}
// Ctrl キーを押しながらマクロメニューを起動したとき
else if ( $ctrl && id >= 6144 && id < 7168 ) {
  WshShell.CurrentDirectory = meryDir;
  macroPath = Fso.GetAbsolutePathName( mm.macros[id - 6144].path ); // 相対パスの解決
  WshShell.CurrentDirectory = currentDir;
  if ( Fso.FileExists( macroPath ) ) {
    // 選択したマクロの実体ファイルを Mery で開く(編集モード)
    WshShell.Run( '"' + meryPath + '" "' + macroPath + '"' );
    Status = " " + macroPath;
  }
}
// マクロまたはコマンドを実行
else if ( id > 2 ) {
  editor.ExecuteCommandByID( id );
}


function MacroMenu( showParent, trimExt ) {
/**
* 関数 MacroMenu( [ showParentFolderName: boolean [, trimExtension: boolean [, ctrl ]]] )
* 戻り値は { menu: objPopupMenu, macros: macroArray }
* ※ macroArray の各要素は { path: macroPath, visible: int } で
*    path は Mery.ini に記述されているままの相対パス
*    visible は 数値 1 または 0
*/
function MacroMenu( showParent, trimExt, $ctrl ) {
   var start = new Date();
   var start = new Date();
   var menu = CreatePopupMenu();
   var menu = CreatePopupMenu();
  var b3 = "\u2002\u2002\u2002"; // EN SPACE 「 」(U+2002)
  var d = editor.ActiveDocument;


   // Mery.ini のパス
   // Mery.ini のパスを取得
   var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
   var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
   var WshShell = new ActiveXObject( "WScript.Shell" );
   var WshShell = new ActiveXObject( "WScript.Shell" );
74行目: 143行目:
   var iniText = Adodb.ReadText( adReadAll );
   var iniText = Adodb.ReadText( adReadAll );
   Adodb.Close();
   Adodb.Close();
  // 「このマクロを実行」コマンドの準備
  var ext = d.Name.substr( d.Name.lastIndexOf( "\." ) + 1 );
  var reg2 = /^(?:jse?|pls?|php|pys?|rbs?|vb[es])$/i;
  var macroName = reg2.test( ext ) ? d.Name : "";
  var runFlag = ( macroName && d.Saved ) ? 0 : meMenuGrayed;


   // マクロのパスを抽出
   // マクロのパスを抽出
   var reg1 = /\r\n\[Macros\\Macro\d+\]\r\nFileName=[^\r\n]+\r\nVisible=\d/g;
   var reg3 = /\r\n\[Macros\\Macro\d+\]\r\nFileName=[^\r\n]+\r\nVisible=\d/g;
   var macroArray = iniText.match( reg1 ) || [];
  // \r\n [Macros\Macro##] \r\n FileName=MacroPath \r\n Visible=#
   var macroArray = iniText.match( reg3 ) || [];
   var mcCount = macroArray.length;
   var mcCount = macroArray.length;
   if ( mcCount ) {
   if ( mcCount ) {
     var invisible = false;
     var invisible = false;
     var reg2 = /\r\nFileName=([^\r\n]+)\r\n/;
     var reg4 = /\r\nFileName=([^\r\n]+)\r\n/;
     for ( var i = 0, len = mcCount; i < len; i ++ ) {
     for ( var i = 0; i < mcCount; i ++ ) {
       macroArray[i] = [ reg2.exec( macroArray[i] )[1], macroArray[i].slice( -1 ) ];
      // path: MacroPath, visible: #int ※ path は相対パスの場合がある
       if ( ! invisible && macroArray[i][1] == "0" ) { invisible = true; }
       macroArray[i] = {
        path:    reg4.exec( macroArray[i] )[1],
        visible: + macroArray[i].slice( -1 )
      };
       if ( ! invisible && macroArray[i].visible == 0 ) { invisible = true; }
     }
     }


     // マクロのファイル名一覧を列挙(非表示マクロをサブメニュー化)
     // マクロのファイル名一覧を作成 (非表示マクロをサブメニュー化)
     if ( invisible ) {
     if ( invisible ) {
       menu.AddPopup( "非表示マクロ(&J)", smMenu = CreatePopupMenu() );
       menu.AddPopup( "非表示マクロ(&H)", subMenu = CreatePopupMenu() );
       menu.Add( "-----", 0, meMenuSeparator );
       menu.Add( "-----", 0, meMenuSeparator );
     }
     }
     var reg3 = /(?:[^\\]+?\\)*?(?:([^\\]+)(?:\\))?([^\\]+)$/;
     var reg5 = /(?:[^\\]+?\\)*?(?:([^\\]+)(?:\\))?([^\\]+)$/;
     var reg4 = /([^\/]*\/ )?(?:\d+[._ ]+)?([^\/]+)(?:\.[^.]+?)$/;
     var reg6 = /([^\/]*\/ )?(?:\d+[-._ ]+)?([^\/]+)(?:\.[^.]+?)$/;
     var id,  num,  label,  j = 0,  k = 0;
     var id,  num,  label,  j = 0,  k = 0;
     var mcWidth = ( "" + mcCount ).length;
     var mcWidth = ( "" + mcCount ).length;
     for ( var i = 0; i < mcCount; i ++ ) {
     for ( var i = 0; i < mcCount; i ++ ) {
       id = i + 6144;
       // "親フォルダ名/ ファイル名"
       label = ( showParent )
       label = ( showParent )
             ? macroArray[i][0].replace( reg3, "$1/ $2" )
             ? macroArray[i].path.replace( reg5, "$1/ $2" )
             : /([^\\]+)$/.exec( macroArray[i][0] )[1];
             : /([^\\]+)$/.exec( macroArray[i].path )[1];
       if ( label.charAt( 0 ) == "/" ) { label = meryDirName + label; }
       if ( label.charAt( 0 ) == "/" ) {
      // ファイル名先頭の連番と、拡張子を削除
        label = meryDirName + "/ " + label.slice( 1 );
      if ( trimExt ) {
        label = label.replace( reg4, "$1$2" );
       }
       }
       // 可視マクロと不可視マクロの振り分け
      // 起動モードでは ファイル名先頭の連番 と 拡張子 を削除
       if ( macroArray[i][1] == "1" ) {
      // 編集モードでは拡張子を大文字に
         num = ( "  " + ( ++ j ) ).slice( - mcWidth ).replace( /\d$/, "&$&:" );
      label = ( ( trimExt && ! $ctrl ) ? label.replace( reg6, "$1$2" )
              : ( $ctrl ) ? label.replace( /[^.\\]+$/, function( tmp ) {
                                  return tmp.toUpperCase(); } )
              : label
              ).replace( /&/g, "&&" );
 
       // 可視マクロと不可視マクロの振り分け (Visible= 1 or 0)
      id = i + 6144;
       if ( macroArray[i].visible == 1 ) {
         num = ( b3 + ( ++ j ) ).slice( - mcWidth ).replace( /\d$/, "&$&:\u2002" );
         menu.Add( num + label, id );
         menu.Add( num + label, id );
       }
       }
       else {
       else {
         num = ( "  " + ( ++ k ) ).slice( - mcWidth ).replace( /\d$/, "&$&:" );
         num = ( b3 + ( ++ k ) ).slice( - mcWidth ).replace( /\d$/, "&$&:\u2002" );
         smMenu.Add( num + label, id );
         subMenu.Add( num + label, id );
       }
       }
     }
     }
     menu.Add( "-----", 0, meMenuSeparator );
     menu.Add( "-----", 0, meMenuSeparator );
     if ( invisible ) {
     if ( invisible ) {
       smMenu.Add( "-----", 0, meMenuSeparator );
       subMenu.Add( "-----", 0, meMenuSeparator );
       smMenu.Add( "キャンセル\t& ", 0 );
       subMenu.Add( "キャンセル\t& ", 0 );
    }
    if ( gksEnable ) {
      menu.Add( b3 + "▲ 選択した"
                + ( $ctrl ? "ソースコードを編集" : "マクロを実行" )
                + " ▲", 0, meMenuGrayed );
      menu.Add( "-----", 0, meMenuSeparator );
     }
     }
   }
   }
  // 標準コマンド
   menu.Add( "編集(&E)  " + ScriptName, 2173 );
   menu.Add( "編集(&E)  " + ScriptName, 2173 );
   menu.Add( "選択(&L)...", 2174 );
   menu.Add( "選択(&L)...", 2174 );
   menu.Add( "これを選択(&T)", 2175, ! document.Name *2 );
   menu.Add( "これを選択(&T)", 2175, ! d.Name *2 );
  if ( d.FullName != ScriptFullName ) {
    menu.Add( "このマクロを実行(&G)*  " + macroName, 1, runFlag );
  }
   menu.Add( "カスタマイズ(&C)...", 2176 );
   menu.Add( "カスタマイズ(&C)...", 2176 );
  menu.Add( "-----", 0, meMenuSeparator );
  menu.Add( "Macros フォルダを開く(&F)*", 2 );
   menu.Add( "-----", 0, meMenuSeparator );
   menu.Add( "-----", 0, meMenuSeparator );
   menu.Add( "キャンセル\t& ", 0 );
   menu.Add( "キャンセル\t& ", 0 );


   // ステータスを表示
   // ステータスを表示
   Status = " マクロメニュー: " + j + " 件 + " + k + " 件 [ "
   Status = " 「マクロメニュー」 "
        + "** " + ( $ctrl ? "編集" : "起動" ) + "モード **  "
        + j + " 件 + " + k + " 件  [ "
         + ( ( new Date() - start ) / 1000 ).toFixed( 3 ).replace( /\./, ". " )
         + ( ( new Date() - start ) / 1000 ).toFixed( 3 ).replace( /\./, ". " )
         + " 秒 ]";
         + " 秒 ]";
   return menu;
   return { menu: menu, macros: macroArray };
}
}
</source>
</source>

2020年5月2日 (土) 03:49時点における版

標準メニューバーの「マクロ(M)」には表示されないマクロを含めて、「マクロのカスタマイズ」に登録済みのすべてのマクロをポップアップメニューで表示します。

  • 「マクロのカスタマイズ」で ☑ なし のマクロ(ツールバーのマクロメニューで非表示扱い)は、「非表示マクロ」サブメニュー内に表示します。
  • マクロ名は ファイル名 で表示します(各ソースコード内の #title="Hoge" を読みこみません)。
各マクロの実体ファイルの親フォルダ名を表示できます。
ファイル名 「1 マクロA.js」 「2. マクロB.js」 「3_マクロC.js」 「4 - マクロD.js」 などの先頭の連番部分と拡張子をポップアップメニュー上に表示させないように設定できるので、通常のマクロメニューと同じような状態にできます。
  • [選択] や [これを選択] で登録したマクロがメニューに表示されない場合は、 [カスタマイズ] ダイアログを開いて OK ボタンで確定すると表示されるようになります。


  • 追加コマンド [このマクロを実行] は、アクティブなタブのマクロを実行するためのコマンドです。
※ マクロ用と判別できる拡張子で保存済みのタブでのみ使用できます。
拡張子に対して正規表現 /^(?:jse?|pls?|php|pys?|rbs?|vb[es])$/i でチェックします。


  • 追加コマンド [Macros フォルダを開く] は、Mery インストールフォルダ内の "Macros" フォルダをファイラ(エクスプローラ)で開くためのコマンドです。



  • GetKeyState.exe(キー状態取得実行ファイル)」を導入すると、Ctrl キーを押しながらこのマクロを起動したときに、ポップアップメニュー内のマクロ名を選択(クリック/Enter)したさいの処理を変更できます。
    ⇒ 選択したマクロを Mery で開く(編集する)
Mery インストールフォルダ内の Macros フォルダに実行ファイル GetKeyState.exe を配置してください
(または、設定項目 var gksPath でフルパスを指定)。
※ GetKeyState.exe を導入していないばあいは、選択したマクロをそのまま実行します。
マクロの自作・編集をしない人には設定項目 var gksEnable = false; にすることをおすすめします(ポップアップメニューの表示が高速化するはず)。



ソースコード

ダウンロード >> 「ファイル:マクロメニュー.zip(アイコン入り、第2版: 2020/05/02)

#title = "マクロメニュー..."
#tooltip = "全マクロをポップアップメニュー表示"
// #icon = "script_with_lines+.ico"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",318

/**
 * ---------------------------------------------------------
 * マクロメニュー
 * sukemaru, 2019/11/02 - 2020/05/02
 * ---------------------------------------------------------
 * 非表示マクロを含めて全ての登録済みマクロをポップアップメニューで表示する。
 * 
 * Ctrl キーを押しながら「マクロメニュー」マクロを起動して (要 GetKeyState.exe)
 * ポップアップメニュー内のマクロを選択したときは、ソースコードを Mery で開く。
 */

// ---------- ▼ 設定項目 ▼ ---------- //

// ■ ポップアップメニューを表示する位置
var menuPosMouse = true;	// (true: マウス位置 / false: キャレット位置)

// ■ 各マクロの親フォルダ名を表示する
var showParent = false;	// (true: 表示する / false: 表示しない)

// ■ 各マクロの拡張子を表示しない(※ファイル名先頭の連番部分も表示しない)
var trimExt = false;	// (true: 表示しない / false: 表示する)

// ■ GetKeyState.exe による機能拡張を使用する
var gksEnable = true;

// ■ GetKeyState.exe のフルパスを指定する場合
var gksPath = "";
  // 未指定 "" なら、Mery インストールフォルダの Macros\GetKeyState.exe
  // ※ GetKeyState.exe なしのときも "" にする
  // ※ \ 記号はふたつがさね「\\」で記述すること

// ---------- ▲ 設定項目 ▲ ---------- //

var Fso			 = new ActiveXObject( "Scripting.FileSystemObject" );
var WshShell	 = new ActiveXObject( "WScript.Shell" );
var meryPath	 = editor.FullName;
var meryDir		 = meryPath.replace( /[^\\]+$/, "" );
var macroDir	 = meryDir + "Macros\\";
var currentDir	 = WshShell.CurrentDirectory;
var macroPath	 = filePath = editor.ActiveDocument.FullName;

// GetKeyState.exe
var gks   = gksPath || macroDir + "GetKeyState.exe";
var $ctrl = ( gksEnable && Fso.FileExists( gks ) &&
            WshShell.Run( '"' + gks + '" ctrl', 0, true ) != 0 )
          ? true : false;


// ポップアップメニューを表示
var mm = MacroMenu( showParent, trimExt, $ctrl );
var id = mm.menu.Track( menuPosMouse );

// 「このマクロを実行」
if ( id == 1 ) {
  WshShell.Run( '"' + meryPath + '" /mf "' + macroPath + '" "' + filePath + '"' );
}

// 「Macros フォルダを開く」
else if ( id == 2 ) {
  WshShell.Run( '"' + macroDir + '"' );
  Status = " " + macroDir;
}

// Ctrl キーを押しながらマクロメニューを起動したとき
else if ( $ctrl && id >= 6144 && id < 7168 ) {
  WshShell.CurrentDirectory = meryDir;
  macroPath = Fso.GetAbsolutePathName( mm.macros[id - 6144].path ); // 相対パスの解決
  WshShell.CurrentDirectory = currentDir;
  if ( Fso.FileExists( macroPath ) ) {
    // 選択したマクロの実体ファイルを Mery で開く(編集モード)
    WshShell.Run( '"' + meryPath + '" "' + macroPath + '"' );
    Status = " " + macroPath;
  }
}

// マクロまたはコマンドを実行
else if ( id > 2 ) {
  editor.ExecuteCommandByID( id );
}

/**
 * 関数 MacroMenu( [ showParentFolderName: boolean [, trimExtension: boolean [, ctrl ]]] )
 * 戻り値は { menu: objPopupMenu, macros: macroArray }
 * ※ macroArray の各要素は { path: macroPath, visible: int } で
 *    path は Mery.ini に記述されているままの相対パス
 *    visible は 数値 1 または 0
 */
function MacroMenu( showParent, trimExt, $ctrl ) {
  var start = new Date();
  var menu = CreatePopupMenu();
  var b3 = "\u2002\u2002\u2002";	// EN SPACE 「 」(U+2002)
  var d = editor.ActiveDocument;

  // Mery.ini のパスを取得
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  var WshShell = new ActiveXObject( "WScript.Shell" );
  var meryPath = editor.FullName;
  var meryDir = Fso.GetParentFolderName( meryPath ) + "\\";
  var meryName = Fso.GetBaseName( meryPath );
  var meryDirName = Fso.GetBaseName( meryDir );
  var iniPath = meryDir + meryName + ".ini";
  if ( ! Fso.FileExists( iniPath ) ) {
    iniPath = WshShell.SpecialFolders( "APPDATA" )
            + "\\Mery\\" + meryName + ".ini";
  }

  // Mery.ini からデータを取得
  var Adodb = new ActiveXObject( "ADODB.Stream" );
  var adTypeText = 2,  adReadAll = -1;
  Adodb.Type = adTypeText,  Adodb.Charset = "UTF-8";
  Adodb.Open();
  Adodb.LoadFromFile( iniPath );
  var iniText = Adodb.ReadText( adReadAll );
  Adodb.Close();

  // 「このマクロを実行」コマンドの準備
  var ext = d.Name.substr( d.Name.lastIndexOf( "\." ) + 1 );
  var reg2 = /^(?:jse?|pls?|php|pys?|rbs?|vb[es])$/i;
  var macroName = reg2.test( ext ) ? d.Name : "";
  var runFlag = ( macroName && d.Saved ) ? 0 : meMenuGrayed;

  // マクロのパスを抽出
  var reg3 = /\r\n\[Macros\\Macro\d+\]\r\nFileName=[^\r\n]+\r\nVisible=\d/g;
  // \r\n [Macros\Macro##] \r\n FileName=MacroPath \r\n Visible=#
  var macroArray = iniText.match( reg3 ) || [];
  var mcCount = macroArray.length;
  if ( mcCount ) {
    var invisible = false;
    var reg4 = /\r\nFileName=([^\r\n]+)\r\n/;
    for ( var i = 0; i < mcCount; i ++ ) {
      // path: MacroPath, visible: #int		※ path は相対パスの場合がある
      macroArray[i] = {
        path:    reg4.exec( macroArray[i] )[1],
        visible: + macroArray[i].slice( -1 )
      };
      if ( ! invisible && macroArray[i].visible == 0 ) { invisible = true; }
    }

    // マクロのファイル名一覧を作成 (非表示マクロをサブメニュー化)
    if ( invisible ) {
      menu.AddPopup( "非表示マクロ(&H)", subMenu = CreatePopupMenu() );
      menu.Add( "-----", 0, meMenuSeparator );
    }
    var reg5 = /(?:[^\\]+?\\)*?(?:([^\\]+)(?:\\))?([^\\]+)$/;
    var reg6 = /([^\/]*\/ )?(?:\d+[-._ ]+)?([^\/]+)(?:\.[^.]+?)$/;
    var id,  num,  label,  j = 0,  k = 0;
    var mcWidth = ( "" + mcCount ).length;
    for ( var i = 0; i < mcCount; i ++ ) {
      // "親フォルダ名/ ファイル名"
      label = ( showParent )
            ? macroArray[i].path.replace( reg5, "$1/ $2" )
            : /([^\\]+)$/.exec( macroArray[i].path )[1];
      if ( label.charAt( 0 ) == "/" ) {
        label = meryDirName + "/ " + label.slice( 1 );
      }
      // 起動モードでは ファイル名先頭の連番 と 拡張子 を削除
      // 編集モードでは拡張子を大文字に
      label = ( ( trimExt && ! $ctrl ) ? label.replace( reg6, "$1$2" )
              : ( $ctrl ) ? label.replace( /[^.\\]+$/, function( tmp ) {
                                  return tmp.toUpperCase(); } )
              : label
              ).replace( /&/g, "&&" );

      // 可視マクロと不可視マクロの振り分け (Visible= 1 or 0)
      id = i + 6144;
      if ( macroArray[i].visible == 1 ) {
        num = ( b3 + ( ++ j ) ).slice( - mcWidth ).replace( /\d$/, "&$&:\u2002" );
        menu.Add( num + label, id );
      }
      else {
        num = ( b3 + ( ++ k ) ).slice( - mcWidth ).replace( /\d$/, "&$&:\u2002" );
        subMenu.Add( num + label, id );
      }
    }
    menu.Add( "-----", 0, meMenuSeparator );
    if ( invisible ) {
      subMenu.Add( "-----", 0, meMenuSeparator );
      subMenu.Add( "キャンセル\t& ", 0 );
    }
    if ( gksEnable ) {
      menu.Add( b3 + "▲ 選択した"
                + ( $ctrl ? "ソースコードを編集" : "マクロを実行" )
                + " ▲", 0, meMenuGrayed );
      menu.Add( "-----", 0, meMenuSeparator );
    }
  }

  // 標準コマンド
  menu.Add( "編集(&E)  " + ScriptName, 2173 );
  menu.Add( "選択(&L)...", 2174 );
  menu.Add( "これを選択(&T)", 2175, ! d.Name *2 );
  if ( d.FullName != ScriptFullName ) {
    menu.Add( "このマクロを実行(&G)*  " + macroName, 1, runFlag );
  }
  menu.Add( "カスタマイズ(&C)...", 2176 );
  menu.Add( "-----", 0, meMenuSeparator );
  menu.Add( "Macros フォルダを開く(&F)*", 2 );
  menu.Add( "-----", 0, meMenuSeparator );
  menu.Add( "キャンセル\t& ", 0 );

  // ステータスを表示
  Status = " 「マクロメニュー」 "
         + "** " + ( $ctrl ? "編集" : "起動" ) + "モード **  "
         + j + " 件 + " + k + " 件  [ "
         + ( ( new Date() - start ) / 1000 ).toFixed( 3 ).replace( /\./, ". " )
         + " 秒 ]";
  return { menu: menu, macros: macroArray };
}
スポンサーリンク