ようぼう

  1. プロンプトから、ファイル指定できない無題タブに対しマクロを実行する場合に、個人的に困ったことがあったので要望を出させてください。
    (*計算機の出力をMeryの無題タブに表示→整形マクロ実行。の流れを全てプロンプト側から行うイメージです)

    準備:無題タブに文字列を表示させ、選択状態にしておく。
       あとはプロンプトから /mf でマクロを呼び出す。
    ```cmd
    mery /mf macros/test.js
    // ファイル指定あり(readme)
    //mery /mf macros/test.js mery.txt
    ```


    新たに変更になったポイントの確認。
    ver. 2.5.6まで
    ・自動生成される空タブを消すだけで無題タブに戻り、そのままdocument配下でテキストを取得できる。
    ・ファイル指定ありの場合でもそのまま使える。
    ```js
    if (document.Name == '')
        document.Close();
    alert('選択文字列:' + document.selection.Text);
    ```

    ver. 2.6.0以降
    ・自動生成される空タブを消して無題タブに戻ると、editor.ActiveDocument配下でテキスト取得に変更。
    ・ファイル指定ありの場合は従来のdocument配下。
    ```js
    if (document.Name == '') {
        editor.ActiveDocument.Close();
        alert('無題タブ:' + editor.ActiveDocument.selection.Text);
    } else {
        alert('ファイル指定:' + document.selection.Text);
        // まあ、こっちでも同じですが
        //alert('ファイル指定:' + editor.ActiveDocument.selection.Text);
    }
    ```

    この変更で困るのはdocument配下に戻せないので、
    ・全てeditor.ActiveDocument配下で書き直すか、動作別に処理を記述する必要あり。
    という点です。
    簡単に修正できるのですが、ちょっと数が……ね (>_<)


    要望としては以下になります。
    ・ファイル指定が無い場合、空タブを生成しないで強制的にトップレベル(最前面)のファイルを
     マクロの対象にする起動時引数の導入(自己責任 or 野生開放用)

    セキュリティ上、変なマクロを喰わないための仕様は承知してますが検討よろしくお願いします。


    我々(ひとり)はプロンプトで面倒な対象ファイル名まで、おいそれと打ち込みたくないのです。
    ダメダメなので、中間ファイルを作りたくないのです。
    無題タブのままで、チョイチョイしたいのです。

    ぶっちゃけると、そういうことなのです(笑)
    それでは!



    追伸(に見せかけた不具合報告):
    アウトラインで2階層上位の[-]を閉じると、アウトライン側の定位置にある項目にフォーカスが移動し、
    つられてファイル表示側でも表示が吹っ飛び、結果見ている行を見失います。
    (これは、上の方に項目が沢山ある長めの場合でないと再現できないかも)
    突然前の場所に戻って、まるで迷路にいる気分です。(……まさか試されてる!?)

     |  玄米茶  |  返信
  2. 玄米茶さん、こんにちは
    > 簡単に修正できるのですが、
    こんな関数じゃだめですかね?
      CloseNew_GetNotitle();
      function CloseNew_GetNotitle(){
        var newdoc = editor.ActiveDocument;
        for(var i = 0; i < editor.documents.count; i++){
          editor.documents.Item(i).Activate();
          var currentdoc = editor.ActiveDocument;
          if(!currentdoc.Name && currentdoc != newdoc){
            if(!newdoc.name)newdoc.Close();
            return currentdoc;
          }
        }
      }
    Indexの最も若い無題のドキュメントをアクティブにして返します。SDI は考慮せず。
    無題のドキュメントに関しては 「window オブジェクトに title プロパティが欲しい!」
    と叫んでみる。

     |  今日も匿名で  |  返信
  3. 今日も匿名でさん、はじめまして。
    対策の関数、丁寧にありがとうございます。
    いま、間違いに気がついて投稿するところでした。
    間に合いませんでしたね……。

    > こんな関数じゃだめですかね?
    こちらは後で使えるかもしれませんので、有難くいただきます。


    簡単にいうと、確認不足でした、すみません。

    本体側でマクロを呼び出せば無題タブでも空タブを生成しないので、上で挙げている判定方法では対象の無題タブを閉じてしまいます。
    この動作の違いは、マクロからは確認できません。

    このため、外部呼び出し専用のトラップマクロに分離しているのですが、
    ここでの処理中で、documentが使えないものと誤解していました。

    editor.ActiveDocument配下に変更されたのは、生成された空タブのみでした。
    editor.ActiveDocument.Close() で閉じてしまえば、document配下のままでよかった様です。

    変更は最小限で済みそうです。


    ただ、空タブ処理にマクロ分離しているのは煩雑なので、要望はそのまま有効ということでお願いします。

    改めて、kuroさん、今日も匿名でさんお騒がせしました。

     |  玄米茶さん  |  返信
  4. 名前欄コピペしたら大惨事です。
    けものですので大目にみてください。

     |  玄米茶  |  返信
  5. > 名前欄コピペ
    今回の名前欄のとおりなんで気にせずに。
    掲出の関数は /mf での使用しか想定していないのであしからず。
    /mf での起動か、通常の起動かマクロから判別する方法ってあったっけ?

     |  ハンドル使わない俺が悪い  |  返信
  6. 書き込みありがとうございます。
    うわぁ、なんだか壮大な話に…!

    > 新たに変更になったポイントの確認。

    仕様変更したつもりはなく、高速化のための処理の副作用でたまたまそうなっていただけです… ^^;

    2.6.1 公開翌朝 (17 日の昼頃) にご報告を頂き、こっそり修正版に差し替えちゃってますので、お手数をお掛けしますが再度、2.6.1 をダウンロードしなおしてお試しくださいませ。

    たぶん 2.5.6 の挙動に戻っていると思います。

    > アウトラインで2階層上位の[-]を閉じる

    ご報告ありがとうございます。
    ほんとですね、次のバージョンでは修正しておきますです!

    > /mf での起動か、通常の起動かマクロから判別する方法ってあったっけ?

    たぶん、仕様変更前提でお話が進んでるのだと思いますが、、、仕様変更しませんので… ^^;
    マクロとかの修正は正式版リリースまでお待ちくださいー!

     |  Kuro  |  返信
  7. kuroさんへ
    差し替えでしたか。
    どおりで昼間にやってみたら不完全な修正でも動いたのですね。
    確認不足での報告じゃなかった事にホッとしてます。
    まぁ差し替えの確認は不足してましたがw


    今日も匿名でさんへ
    > 名前欄コピペ
    あっそれ、"玄米茶さん"ってミスったことです。
    他意はないです。
    > /mf での起動か、通常の起動かマクロから判別する方法ってあったっけ?
    無いので現状2つに分けてるのですが、1つにまとめたいなーってのも含めて今回要望してみたんですよ。
    > 無題のドキュメントに関して
    無題のタブはちょっとした鬼門ですよね。わかります。


    それでは

     |  玄米茶  |  返信
  8. > 確認不足での報告じゃなかった事にホッとしてます。
    > まぁ差し替えの確認は不足してましたがw

    すみません、夜にリリースして翌日の午前中だったので、バージョン上げるのも気が引けてこっそり差し替えてしまいましたー <(_ _)>

    起動時マクロは使ったことがないので、ほへー、そういうものなのかー。と、( ゚д゚) な感じです…

    2.5.6 の挙動に戻っただけでは足りない部分があるということなのでしょうか?マクロが苦手なフレンズなので把握できてないのであります ('◇')ゞ

     |  Kuro  |  返信
  9. デフォで空タブを消しておいてくれると捗るのですが、
    動作が前に戻ったし、まぁ要望出すほどでもないかぁ~(スナネコ並感想)

    なので、特に無いであります。(どっち!?)

     |  玄米茶  |  返信
  10. > デフォで空タブを消しておいてくれると捗るのですが、
    > 動作が前に戻ったし、まぁ要望出すほどでもないかぁ~(スナネコ並感想)

    ああー、そういうことでしたか ^^;

    なんか以前に話題にあがっていた気がしますね。秀〇さんと E〇 さんの仕様にならって無題タブ作る仕様にしたのでした。

    アクティブなタブに対してのマクロ発動は私の技術が足りなくて禿げかけたのでやめました!と、回答してました。(2016年9月23日 20:53)

    > なので、特に無いであります。(どっち!?)

    ありがとうございますw
    一応、ご要望一覧に追記しときますです!

     |  Kuro  |  返信
  11. meryさんの仕様
    作動対象指定なしの /mf オプションで開いた新規ドキュメントを閉じると
    直前の ActiveDocument にフォーカスが戻る。かしこーい
    マクロを起動したドキュメントが閉じられるとその時点でマクロが終了す
    る。あんぜん
    ただし、このために
    > アクティブなタブに対してのマクロ発動
    ができないのですね。わかります。

    で挑戦、挑戦。
    WSH(CScript.exe)と環境変数を使って
    try{
      WScript.Sleep(0);
      mf2ActiveDoc();
    }catch(e){
      alert('Meryのマクロじゃないよ');
    }
    function mf2ActiveDoc(){
      var re = /.*"([^"]+)( [ \*\-]+Mery)"/g
      var sh = new ActiveXObject("WScript.Shell");
      var oExec = sh.Exec('tasklist.exe /V /FO CSV /NH /FI "IMAGENAME eq Mery.exe"');
      // WSH がアクティブの時、Meryのタイトルはパスを含まない
      var noActiveTitle = oExec.stdOut.readLine().replace(re,'$1$2');
      if(sh.AppActivate(noActiveTitle)){ //Meryをアクティブにする
        var oExec = sh.Exec('tasklist.exe /V /FO CSV /NH /FI "IMAGENAME eq Mery.exe"');
        var ActiveDoc = oExec.stdOut.readLine().replace(re,'$1');
        if(ActiveDoc.slice(0,2) == '無題'){
          sh.Environment('USER').Item('meryactivetitle') = ActiveDoc;
          var oExec = sh.Exec('meryのパス\\mery.exe /mf マクロのパス\\マクロファイル名.js');
          //'マクロ処理の終了時に空ファイルが閉じられるのを待って環境変数をクリアする
          while(oExec.Status == 0)WScript.Sleep(100);
          sh.Environment('USER').Remove('meryactivetitle');
        }else{
          sh.Exec('meryのパス\\mery.exe /mf マクロのパス\\マクロファイル名.js ' + ActiveDoc);
        }
      }else{
        sh.Exec('meryのパス\\mery.exe /mf マクロのパス\\マクロファイル名.js');
      }
    }

    マクロファイルの方は win32APIを使って
    (function(){
      /* WSHで取得したアクティブドキュメントを環境変数から再現 */
      var activeTitle = new ActiveXObject("WScript.Shell").Environment('USER').Item('meryactivetitle');
      if(activeTitle){
        editors_loop:for(var i = 0; i < editors.count; i++){
          for(var j = 0; j < editors.Item(i).documents.count; j++){
            if(!editors.Item(i).documents.Item(j).name){
              editors.Item(i).documents.Item(j).Activate();
              if(getActiveWindowTitle()==activeTitle){
                break editors_loop;
              }
            }
          }
        }
      }
      /* ActiveDocument対象のマクロの本体を main関数に記述 */
      main();

      /* ファイル指定なしで /mf した時の空ドキュメントを閉じる */
      var d = window.Document;
      if(!d.name && d.Text == "" && (editors.Count > 1 || editor.documents.Count > 1))d.Close();

      //window オブジェクトに title プロパティが追加されれば Win32api は不要になる
      function getActiveWindowTitle(){
        var title = null;
        try {
          var SfcMiniTools = new ActiveXObject("SfcMini.Tools");
          var GetActiveWindow = new ActiveXObject("SfcMini.DynaCall");
          var GetWindowText = new ActiveXObject("SfcMini.DynaCall");
          GetActiveWindow.Declare("user32", "GetActiveWindow");
          GetWindowText.Declare("user32", "GetWindowTextA");
        } catch(e) {
          return title;
        }
        var hWnd = GetActiveWindow();
        var windowText = new ActiveXObject("SfcMini.Structure");
        windowText("str", "String*256");
        if (GetWindowText(hWnd, windowText, 256)) {
          windowText = windowText.str.toString();
          title = windowText.replace(/[ \*]*- Mery/,'');
        }
        return title;
      }
      
      function main(){
        /* 本体 */;
      }
    })();
    で一応は動作可能です。
    ※Win32API を Excel で処理しようとしたら別の問題を発見。別スレッドに起こします。

     |  匿名です  |  返信
  12. WSHの方の無題判定、アクティブドキュメントが grep 結果画面だと悲惨な
    結果を招くのでした。
    >     if(ActiveDoc.slice(0,2) == '無題'){

        if( ActiveDoc.indexOf('\\',0) < 0 || ActiveDoc.indexOf('*',0) > 0 ){
    に修正。

     |  匿名だよ  |  返信
  13. 連投ごめんなさい
    そして WSH の標準出力切り出しの正規表現は 
    >  var re = /.*"([^"]+)( [ \*\-]+Mery)"/g

      var re = /^(?:"[^"]*",){8}"(.+)( [ \*\-]+Mery)"/g
    に修正。

     |  匿名だよ  |  返信