複数選択時にマクロの Get 系メソッドでインデックスを省略すると正しく取得できない

  1. 複数選択時にマクロの Get 系メソッドで引数のインデックスを省略すると、通常選択(最後に選択した選択範囲)の位置が取得できる仕様かと思います。

    ・GetActivePointX, Y
    ・GetActivePos

    などのカーソル位置を取得するメソッドは、通常選択のカーソル位置がちゃんと取得できるのですが、

    ・GetAnchorPointX, Y
    ・GetAnchorPos
    ・GetBottomPointX, Y
    ・GetTopPointX, Y

    などでは、複数選択している場合、開始位置等ではなくカーソル位置が取得されてしまうようです。

    GetAnchorPos の例だとこんな感じです。

    var getPos = function() {
      var AnchorPos = document.selection.GetAnchorPos();
      var ActivePos = document.selection.GetActivePos();
      return AnchorPos + ', ' + ActivePos;
    };
    
    // 選択範囲が一つの場合
    document.selection.SetAnchorPos(4);
    document.selection.SetActivePos(10, true);
    alert(getPos());
    // 4, 10 と GetAnchorPos は開始位置が取得される
    
    // 選択範囲が複数の場合
    document.selection.SetAnchorPos(13);
    document.selection.SetActivePos(21, true);
    document.selection.AddPos(0, 3);
    document.selection.AddPos(4, 10);
    alert(getPos());
    // 10, 10 と GetAnchorPos もカーソル位置が取得されてしまう
    

    【環境】
    ・Windows 10 21H2 (19044.1348、64 ビット)
    ・Mery Ver 3.3.1 (64 ビット)

     |  ucky  |  返信
  2. ご報告ありがとうございます。

    そうなんですよね。現在のところ、そういった仕様になっています。

    というのも、複数選択は選択範囲が複数あるわけではなく、実際のカーソル (システムキャレット) は "選択範囲ゼロ" として動作しており、複数あるように見える選択範囲は目印としてただ色を付けてるだけなので、GetAnchorPos などの選択範囲を取得するメソッドで引数を省略した場合はシステムキャレットの位置が返るだけとなっています。

    また、GetActivePos も同様、必ずしも最後に選択した位置が返ってくるとは限らないのでご注意ください。

    Windows の仕様上、システムキャレットは 1 つのウィンドウに対して 1 つしか使えませんから、複数あるように見えるカーソルはすべてダミーカーソルとなっており、その中に 1 つだけ本物のシステムキャレットも溶け込ませていますが、それが必ず最後に選択した位置にあるとは限りません。

    そういうわけで、これらのメソッドを複数選択で使いたい場合は引数を付けてください。

    一応、これらのメソッドで引数を省略した場合の仕様は、本物のシステムキャレットの位置を知ることができるので、用途は少ないかもしれませんがあえてそのまま残しています。

    ちなみに、マクロリファレンス3 はまだ作成途中ですが、これは説明のほうが誤りですね、すみません。

    マルチカーソル系のマクロは仕様を決めかねている部分も多いので、この仕様につきましてはシステムキャレットの位置よりも最後に選択した位置が返ってほしいとかのご意見があれば検討してみたいと思います。

     |  Kuro  |  返信
  3. > ちなみに、マクロリファレンス3 はまだ作成途中ですが、これは説明のほうが誤りですね、すみません。

    よく考えてみると、マクロリファレンス3 に書かれている「省略すると通常選択の開始位置を取得します。」という説明も、通常 (複数選択じゃない場合) はそういった使い方なわけですから、誤っているわけではなかったですね。

    複数選択の場合で引数を省略したときの仕様については特に説明を書いていなかったので、そのあたりの仕様決めと説明の追記をしておくと良さそうですね。

     |  Kuro  |  返信
  4. ご確認ありがとうございます。

    現在の仕様ということで承知しました。過去の言及を見落としていたとしたらすみませんでした。

    複数選択の選択箇所を一つずつ加工した後、最後に選択していた位置に戻るマクロを書いているときに GetAnchorPos がカーソル位置を取得していることに気づき報告した次第です。

    仕様がわかってしまえば対応はできそうなので、リファレンスに説明があれば今の仕様で問題ないと思います。最後に選択した位置が取得できると便利な場面もあるかもしれませんが、仕様変更となると、あちらを立てればこちらが立たずということにもなりかねないので難しそうですね。

    引数を省略したときの仕様といえば、前から気になってたのですが、GetLine メソッドと GetLines メソッドのフラグ meGetLineView を省略しても表示座標で指定(取得)になるというのも意図した仕様なのでしょうか?

    話がそれてしまいすみません。新しく投稿しようか迷ったのですが、仕様であれば問題ないのでここで質問させていただきました。詳細が必要であれば改めて投稿します。

    ちなみに、マクロリファレンス3 では、GetLine メソッドと GetLines メソッドの「meGetLineView」が「meLineView」と間違って記載されているようです。

     |  ucky  |  返信
  5. いえいえー。マクロのマルチカーソル対応の仕様につきましては、開発当時、みなさんからご意見をいただきつつ考えたものですが、従来との互換性を優先しています。

    引数を省略した場合は従来のメソッドが呼ばれるだけなので、複数選択だからといって最後に選択した位置が返るといったような特殊な仕様は用意していませんでした。

    > 仕様変更となると、あちらを立てればこちらが立たずということにもなりかねないので難しそうですね。

    そんなことはありませんよー。

    GetAnchorPos などの仕様についてはブログ記事でも書いているので引用しておきますね。

    > document.selection.GetAnchorPos([Sel = -1])
    > 試験的な実装です。フォーラムでマクロを使ったマルチカーソルの操作についてのご意見をいただいたり、試行錯誤したりしていますが、ある程度動くものがあったほうが分かりやすいと思うので実装してみました。

    > これらのメソッドは従来のマクロと互換性がありますが、実装が確定されたものではありません。

    ということで、特に仕様が決まっていないというだけのものです。

    > GetLine メソッドと GetLines メソッドのフラグ meGetLineView を省略しても表示座標で指定(取得)になるというのも意図した仕様なのでしょうか?

    これは意図していた仕様ではありませんでした。

    ソースコードを確認してみたところ、省略した場合は論理座標を返そうとしていたようで、内部的に meLineLogical (数値の 2) を補完して引数にしていたのですが、そもそもこのメソッドにそんな引数用意してないぞ、ということでたまたま meGetLineView (数値の 2) と数値が一致しちゃって表示座標が返ってました。

    これは修正しておきますね。

    > マクロリファレンス3 では、GetLine メソッドと GetLines メソッドの「meGetLineView」が「meLineView」と間違って記載されているようです。

    ありがとうございます、こちらは修正しておきました。

    凡ミスばかりでお恥ずかしい限りですが、ご報告ありがとうございました!

     |  Kuro  |  返信
スポンサーリンク