マクロ内から変換モジュールをBOX...No.09159
天翔記.jp さん 16/10/26 02:01
 
「秀丸マクロ内」から、「filter文」にて、「変換モジュール」を呼び出した場合な
のですが、

変換モジュール用の関数の型が

using HIDEMARUFILTERFUNC = HGLOBAL (_cdecl* )( HWND hwndHidemaru, WCHAR* pws
zIn, char* pszParam, int cbParamBuffer );

と与えられていますが、、

「BOX選択」や「複数選択」の際って、「pwszInに文字列」はわたってきますか?

HIDEMARUFILTERINFO の fMustLineUnit は意味が違いますし、
メニューから実行したときしかBOXや複数は反映されないですか?


(メニューからの変換モジュール)ではなく、
マクロ内(もしくはマクロ実行中のC層)から、
「BOX選択のテキスト」と「複数選択のテキスト」の取得、
および、それらの置き換えを、どのように実装するのが一番速度が速いか、悩んでい
ます。

複数選択は「Hidemaru_TotalText」で全文字列ガバっと取った後、
columntoxやlinenotoyで、クリクリクリと位置だけ回して得てしまった方が
早いのかな? とも思っています。

[ ]
RE:09159 マクロ内から変換モジュールをBONo.09160
秀丸担当 さん 16/10/26 09:21
 

BOX選択や複数選択でも変換モジュールは呼ばれますが、マクロの場合はそのま
までは互換性の配慮ため単一選択扱いになってしまいます。
setcompatiblemode 0x00100000;をしておくと、filter文も含めて、各種の文は
複数選択に対応した振る舞いになります。
例:
setcompatiblemode 0x00100000;
filter "","ToUpper";

filter文だけでなくcopy文やinsert文など、範囲選択に関わるところはほぼ全て
影響します。
処理の内容によりますが、おそらくfilter文が速いと思います。
選択個所が非常に多い場合は全テキストをごっそり入れ替えたほうが速い場合も
あるとお思います。

[ ]
RE:09160 マクロ内から変換モジュールをBONo.09162
天翔記.jp さん 16/10/26 11:39
 
  >setcompatiblemode 0x00100000;
 >filter "","ToUpper";
なるほど、ありがとうございます。

となると、
setcompatiblemode値によって挙動が変わるのであれば、

 「ライブラリ提供者」にとって都合の良い 「setcompatiblemode値」へと切り替え
した後で、
値を元に戻す手段が現状存在しないように思えます。

これを実現するには、現在の「compatiblemode値」を示すcompatiblemodeといったシ
ンボルが必要のように思えます。

■ライブラリ内部

// 処理を実行した後、設定をライブラリ利用者がしていたものへと戻しておく必要
がある
hm.Macro.Eval(r"""
     ##_org_compat_mode = compatiblemode;
     ##_mod_compat_mode = compatiblemode | 0x100000 // 好きなところのビット
を立てて・・・
     setcompatiblemode ##_mod_compat_mode

     filter(....)
     copy....

     setcompatiblemode ##org_compat_mode

     ##_mod_compat_mode = 0; // 勝手に生成した変数は消滅
     ##_org_compat_mode = 0; // 勝手に生成した変数は消滅
""");

みたいな感じです。

[ ]
RE:09162 マクロ内から変換モジュールをBONo.09163
秀丸担当 さん 16/10/26 14:50
 

setcompatiblemode文の状態は確かに取得できないです。
元に戻すために取得できるようになっているべきだと思います。
compatiblemodeキーワードとしてもあってもいいですが、似たものとして
seterrormodeという文と関数もあり、こちらはもともとseterrormode文だけだっ
たのを、直前の状態を取得するためにseterrormode関数もできるようにしていま
す。
それに合わせたほうがいいので、まずはsetcompatiblemode関数を追加しようと
思います。
それはそれとして、compatiblemodeキーワードでもどちらでもできてもいいとは
思うので、これも検討したいと思います。

[ ]
RE:09163 マクロ内から変換モジュールをBONo.09164
天翔記.jp さん 16/10/26 23:46
 
ちょっと、ついでに質問なのですが、
変換モジュールの
using HIDEMARUFILTERFUNC = const HGLOBAL (*)( HWND hwndHidemaru, const wchar
_t *pwszIn, const char *pszParam, int cbParamBuffer );

のcbParamBufferは、260という値がわたってくるようです。
(MAX_PATHみたいなw)

ということは、

秀丸本体側から、変換モジュール側へと、
char szParam[260] = "";
sctrpy(szParam, その時のパラメタ),

pfn_user_filter_func(hWndHideamru, (wchar_t*)選択対象文章, szParam, _countof
(szParam) );

みたいに変換モジュールへと渡していると思うのですが、
cbParamBuffer が渡ってくる理由がよくわからないのですが、
「何に必要という観点」で渡ってきてるのでしょうか〜

[ ]
RE:09164 マクロ内から変換モジュールをBONo.09165
colder さん 16/10/27 01:06
 
脇から失礼します。colderです。
>pfn_user_filter_func(hWndHideamru, (wchar_t*)選択対象文章, szParam, _counto
>f(szParam) );
>
>みたいに変換モジュールへと渡していると思うのですが、
>cbParamBuffer が渡ってくる理由がよくわからないのですが、
>「何に必要という観点」で渡ってきてるのでしょうか〜
これは単純に変換モジュール内でパラメータを書き換える場合があるからだと思いま
す。
で、これがなぜ必要かというとキー操作の記録をすると分かるのですが、
filter "","Sort","変換モジュール内で書き換えたパラメータ";
みたいな感じで記録されます。

[ ]
RE:09165 マクロ内から変換モジュールをBONo.09166
秀丸担当 さん 16/10/27 09:26
 

colderさんの言われる通り、変換モジュール内でpszParamが指す文字列を書き換
えることがあるためです。

通常、メニュー等から変換を実行するとパラメータはつかないです。
変換モジュール側が何らかのパラメータを格納して返すことができます。
例えば、変換モジュール内でダイアログを出して何か選択した場合、何を選択し
たかを返しておきます。
キー操作の記録をすると、秀丸エディタがこのパラメータを覚えます。
キー操作の再生をすると、秀丸エディタで覚えていたパラメータを付けて変換モ
ジュールを呼び出すようになり、ダイアログを出さずに前回と同じ選択で実行が
できるようになっています。

[ ]
RE:09166 マクロ内から変換モジュールをBONo.09168
天翔記.jp さん 16/10/27 22:56
 
colderさん、秀丸担当さん、了解しました。
ありがとうございます。

[ ]
RE:09168 マクロ内から変換モジュールをBONo.09179
天翔記.jp さん 16/10/28 14:57
 
こちら変換モジュールを試したのですが、(ほぼ実装しをえてから駄目だと気づいた
…orz)、

マクロ内で「範囲選択文字」を得るという目的では、
変換モジュールは不適切なようです。
(少なくとも現行の仕様では)


■そもそも変換モジュールは、「閲覧モード」や「上書き禁止モード」だと機能しな
い。

 ⇒マクロ内filterだと強引に
  ・一瞬編集可能モードに切り替え
  ・実行
  ・戻す
  で、なんとかならなくもないですが、結構不適切な処理。



■変換モジュールを通すと、引数で渡ってきた文字列そのまま返したとしても
更新相当になる。
 一方で、NULL返してしまうと、最初の1回しか関数が呼ばれないため、
 矩形全体の文字列が拾えない。

 undoしても更新されたという履歴が1つ残ってるので変なことに。


とか。


上をふまえると、「矩形選択の文字列情報を配列的状態で得るだけ」っていうのは、
結構やりにくいことになっているのかな?
って思いました。



[ ]
RE:09179 マクロ内から変換モジュールをBONo.09181
秀丸担当 さん 16/10/28 16:43
 

取得することだけが目的の場合、確かに変換モジュールではやりにくいことにな
ると思います。
上書き禁止等はなんとか可能としても、更新されることは不可欠になると思いま
す。
一応undoはできないことはないと思いますが、できていなかったでしょうか。

ちなみに何らかの理由で(更新)の状態を無くす場合はclearupdatedという文もあ
ります。(ただ変換モジュールの例で使えるわけではないと思います)

[ ]
RE:09181 マクロ内から変換モジュールをBONo.09185
天翔記.jp さん 16/10/28 17:41
 
>一応undoはできないことはないと思いますが、できていなかったでしょうか。
誤解させてしまってすみません。
undoはできます。

そして、それによって、「更新状態ではなくなる」のですが、
秀丸はしっかり「更新履歴は覚えている」ので、
redoの状態が変わってしまうのです。(文字列が変化しないのに更新状態となる)
当然といえば当然といいますか…

矩形選択自体はそれなりに使用頻度はあるものの、
矩形選択を「置き換え」「カット」「貼り付け」以外の
目的で使うといったことはあまり無いので、
ちょっとしばらく寝かしてみます〜

ありがとうございました。

[ ]
RE:09185 マクロ内から変換モジュールをBONo.09190
天翔記.jp さん 16/10/30 00:26
 
とりあえず、変換モジュールに取り組むとほどんとの人が
同じ疑問にぶち当たりそうですので、

http://秀丸マクロ.net/?page=nobu_tool_hm_filter_src_commentary

あたりにまとめました。

http://秀丸マクロ.net/?page=nobu_tool_hm_filter_micro
└ こちら変換モジュール(の小さなSDK)として申請しました

http://hide.maruo.co.jp/software/hidemaru.html
└ サイトー企画さんの方で出されているSDKの
「変換モジュールについての簡単な説明」に、
上記(秀丸マクロ.net)ページにあるような

・メニューからの実行はpszParamはNULL
・filterとの関係
・キーマクロ操作との関係

は追記されたほうがよろしいように思えます。





[ ]
RE:09190 マクロ内から変換モジュールをBONo.09193
秀丸担当 さん 16/10/31 11:35
 

変換モジュール開発キットについてのご指摘ありがとうございます。
確かに説明不足のように思います。
追記して更新したいと思います。

>・メニューからの実行はpszParamはNULL
ここは、正確には文字列を指すポインタはNULLではなく、空の文字列のポインタ
を指しています。
(ご理解されているとは思いますが、他の方も読むかもしれないので)
文字数ゼロの空の文字列として呼び出されますが、cbParamBufferの長さのバッ
ファが確保されていて、変換モジュール側で文字列を書き換えることができます。

[ ]
RE:09193 マクロ内から変換モジュールをBONo.09195
天翔記.jp さん 16/10/31 15:42
 
>文字数ゼロの空の文字列として呼び出されますが、cbParamBufferの長さのバッ
>ファが確保されていて、変換モジュール側で文字列を書き換えることができます。
おや、これは私が書き方が悪いですね。>今晩にも訂正します。
(Bufferの中しか頭になかったというか…)

pszParamBufferは、
・長さがcbParamBuffer
・Bufferの中身が全部0クリアされているよ。(ZeroMemory) → (これしてます?)
 (文字列として見ると空文字"")
・メニューから選択すると、このクリアされた空文字状態だよ、

という書き方が「あーはいはい」と一番正確に伝わりそうでしょうか。


[ ]
RE:09195 マクロ内から変換モジュールをBONo.09197
秀丸担当 さん 16/10/31 17:20
 

>・長さがcbParamBuffer
>・Bufferの中身が全部0クリアされているよ。(ZeroMemory) → (これしてます?)
> (文字列として見ると空文字"")
>・メニューから選択すると、このクリアされた空文字状態だよ、

こういう書き方で正確に伝わるのではないかと思います。
pszParamBufferは、cbParamBufferの長さ分、0クリアされています。

[ ]