秀丸本体からExportした新関数挙動報告No.09039
天翔記.jp さん 16/08/29 15:14
 
今回新たに加わった3つの新関数についての挙動の報告となります。
(残る1つの「CheckQueueStatus」は「動かしてみた」というだけで自分のソース内
では試していません)

■Hidemaru_GetTotalTextUnicode
 ネイティブ(string)のままでも、マネージド(String^)にするのも、両方容易であり、
 使いやすいと思います。
 
 ものすごいデカいファイルというのは、試していませんが、
 5M程度のテキストでも問題ありませんでした。
 
 
■Hidemaru_GetCursorPosUnicode
 問題ありません。
 1オリジンなので、プログラム視点ではちょっと
 ナニですが、マクロのxやyと一致していることも考慮すると、
 これで正しいと思います。

■Hidemaru_GetLineTextUnicode
 こちらは若干問題があるかもしれません。

 この関数の使い道は
 @現在カーソルがある行の1行だけのデータを得る
 A1行だけを得る
 Bデータがでかいので、1行ずつ先頭から最後まで得る

 に3分されそうに思えますが、

 nLineNoのMAXを直接得る手段がないため、
 今のところは事実上@に使用方法が限定されそうです。
 
 (現在GetLineTextUnicodeは、引数の nLineNo に本来の行数より
  大きな数が指定されると、行数の数値へと修正している、といった挙動も
  どこで行が終わるのか判断が付きにくいことと関係しています)

 というわけで、Hidemaru_GetLineTextUnicode を活かすには、
  「現在編集しているテキストは 『何行目が最大』なのか?」を
 得る関数が必要かな〜 と思いました。

   
以上、ご報告まで。

[ ]
RE:09039 秀丸本体からExportした新関数挙No.09041
秀丸担当 さん 16/08/29 16:34
 

ご確認ありがとうございます。
Hidemaru_GetLineTextUnicodeについては(1)の使い方が目的というつもりでした。
単語補完的なことをマクロを介さずに行うとしたら、カーソル位置の単語を取得
する必要があるのではないかと思っていました。

一行ずつ取得して全部取得することは想定していなかったです。もし必要であれ
ば、最大行数を返すのも作ります。
Hidemaru_GetTotalTextUnicodeで十分ということであればいらないかもしれない
ですが。

行数を超えた場合はNULLを返したほうがいいかもしれないです。ここは、NULLを
返すようにように変更しようと思います。(β4以降で)

[ ]
RE:09041 Exportで SetTotalTextUnicode No.09049
天翔記.jp さん 16/09/01 15:02
 
hmPyなどにもラッパーを実装したのですが、

・Hidemaru_GetTotalTextUnicode
というGetに対応するものとして、

・int Hidemaru_SetTotalTextUnicode(wchar_t* totaltxt [or HGLOBAL]);
というSetがあった方が俄然便利だと思いました。

使用の幅が広がるな〜と。
(あと、なんといっても、エディタ面を扱う難易度がかなり下がるといいますか。)

hmPyでもhmRbでもhmLJでも同様な感じですが、
dllfunc( #RB, R"IRONRUBY(
    totaltext = $hm::GetTotalText(); // 秀丸の現在編集中の全テキストGet(コピー)
    totaltext.gsub(/(表示|掲示)/, "提示") // 何か文字変更
    $hm::SetTotalText(totaltext); // 編集中のテキストへと反映。今は存在しな
い。
)IRONRUBY"
);

もちろんC++層でもメリットは同じです。

ファイルの文字コードはSJIS指定なのに、音符記号挿入など、
使用不可能な文字コードが挿入される可能性もありますが、

その当たりは、変換モジュールでも同じ問題がありますので、
同様の処理へと流してよいかと思います。

いかがでしょうか?



[ ]
RE:09049 Exportで SetTotalTextUnicode No.09050
秀丸担当 さん 16/09/01 15:49
 

エクスポートされた関数は、どういうタイミングで呼ばれるか予想がつかないの
で、Setがあるのはいろいろ危険なことになりそうです。

一応ネイティブのレベルでそういうことを行う目的のものとして、変換モジュー
ルがあります。

以下のページの「変換モジュール開発キットおよびサンプル変換モジュールはこ
ちら」のところにサンプルがあります。
http://hide.maruo.co.jp/software/hidemaru.html

変換モジュールは[その他]→[動作環境]→[編集]→[変換]で作成したものを追加
しておくと、[編集]→[変換]のメニューに出てきます。

マクロから呼び出す場合は、filter文またはfilter関数を使います。
マクロの場合は動作環境で登録しなくても使えるはずです。
すべて選択してからfilterを呼び出すことで、高速な置換もできると思います。

[ ]
RE:09050 制限付けるとどうですか?No.09051
天翔記.jp さん 16/09/01 19:04
 
>変換モジュール
「変換モジュール自体」はもちろん存じ上げているのですが、全体を俯瞰すると目的
とはちょっと目指しているところとは違うのです。

では制限を加えて

@マクロ内で呼びだされたdll内である。
AHIDEMAC.DLLでいうところの、BeginMacro〜EndMacro」の間である
B該当のBeginMacro〜EndMacroで実行しているマクロと同じスレッドである

という3つの条件であれば、SetTotalTextUnicodeInMacro みたいな関数であったと
したら安全ですか?


狙いは「サクっ」っと一発でアクティブな(編集中)の秀丸に(64Kを超える文字を)代
入できないだろうか? というものです。

もし、秀丸マクロが文字列にバッファー制限等が無いのであれば、
--------------------------------------------------------------
// cur_totaltextといった、アクティブな秀丸の文字列シンボルのような役目のよう
なものがあると仮定
cur_totaltext = edited_long_long_multi_line_string;
--------------------------------------------------------------

とスパっと書けるハズが、なんとか少しでもこれに近づけられないか、
といったことになります。




[ ]
RE:09051 制限付けるとどうですか?No.09052
秀丸担当 さん 16/09/02 09:37
 

4KBや64KBというのは、マクロファイル中に""などの文字列を直接書いたときの
ことで、変数にはそれより大きなサイズを入れることができます。
変数の制限は[その他]→[動作環境]→[環境]の「マクロ変数の上限」によります。

例えば以下のようなマクロでは、1MBなどの大きめのファイルでも簡単に変数で
扱うことができます。
selectall;
$a=gettext(seltopx,seltopy,selendx,selendy);
newfile;
insert $a;
endmacro;

DLLでも扱うことができます。
$a=dllfuncstrw(#dll,"test");
insert $a;
または
insert dllfuncstrw(#dll,"test");
(DLLの場合はDLL側はポインタを返すので確保や解放の注意が必要です)

変換モジュールはもともとの目的は違いますが、結果としては期待されるものが
得られると思います。
変換モジュールの場合は変数の上限はなしで使うことができます。

利用シーンを限定してSetのエクスポート関数を作ることは不可能ではないと思
いますが、マクロに限定されないためのエクスポート関数なので、マクロに限定
されるのであれば、そこまで無理して作ることはない気がします。

[ ]
RE:09052 これは勘違いしていました…No.09053
天翔記.jp さん 16/09/02 12:47
 
「変数合計の要領制限」と、「1つずつの要領制限」の2重の制限を受けていると
思っていたのですが、そうではなく、合計の要領制限だけだったのですね。
これは私が大きく勘違いしていたようです。失礼しました。


>insert dllfuncstrw(#dll,"test");
>(DLLの場合はDLL側はポインタを返すので確保や解放の注意が必要です)
今までいくつか実装した分では、ここは、staticなstring型のdata()を
返しておくのが一番自然で楽なようです。


■「変数合計の要領制限」を確認させてください。
上記、insert dllfuncstrw(#dll,"test"); のような場合は、
変数を経由しませんが、この場合は、「変数合計の要領制限」に
カウントされないですか? それとも暗黙の「_mystr」のような
内部変数が裏で生成され、「変数合計の容量制限」のカウントに含めていますか?

[ ]
RE:09053 確認できましたNo.09054
天翔記.jp さん 16/09/02 13:29
 
確認できました。


変数を経由しなければ、特に制限にひっかからないので、
いろいろ杞憂であったことがわかりました。


・マクロの変数の上限は1Mと設定してみる

・C側を以下のようにしてみる。返り値は、最終的に2M程度の文字列へのポインタ(pi
n相当)
----------------------------------------------------------------------------
-----
#include <string>

using namespace std;

string result;
extern "C" __declspec(dllexport) const char *getabc(int a) {
 result = "(In the form below, enter your eight-digit ID number written on t
he upper right of your test sheet, and click ‘View the Test Result’.\n)";
        // 2Mほどのデータへと増幅
 for (int i = 0; i < 14; i++) {
  result = result + result;
 }
return (char *)result.data();
}
----------------------------------------------------------------------------
-----


・マクロを以下のように設定してみる
----------------------------------------------------------------------------
-----
#dll = loaddll( hidemarudir + @"\Win32Project8.dll" );

if (#dll) {
 // 「マクロの変数の上限1M」に設定していても、2Mのデータであるが、問題なくエ
ディタへと反映される。
 insert dllfuncstr( #dll, "getabc" );
} else {
 message("無い");
}

freedll( #dll );



[ ]
RE:09054 確認できましたNo.09055
秀丸担当 さん 16/09/02 13:44
 

変数を経由せず、直接パラメータに指定した場合は、言われているように内部的
な変数を使っています。
ここの量も上限に含まれます。

以下の場合、内部用の見えない変数と、実際の$aの2つを使用しています。
$a=dllfunc(#dll,"test");
insert $a;
設定で1MBを指定していても、実際にはその倍を確保しています。この例のよう
に、2倍使うためです。

以下の場合、内部用だけなので節約になります。
insert dllfunc(#dll,"test");

1MBの設定で2MBのデータで大丈夫だったのは、実際には内部用も含めて2MBなの
で、直接指定で節約しているためだと思います。

[ ]
RE:09055 確認できましたNo.09056
天翔記.jp さん 16/09/02 13:48
 
>1MBの設定で2MBのデータで大丈夫だったのは、実際には内部用も含めて2MBなの
>で、直接指定で節約しているためだと思います。

なんと!?
実験の境界線がたまたまギリッギリのセーフラインを踏んでいたとはw

ご説明のようになっている旨了解しました。



[ ]
RE:09056 うむむ?No.09057
天翔記.jp さん 16/09/02 14:10
 
う〜む、返す文字列を8M級や32M級などにしても、

「マクロの変数の上限」が1Mにもかかわらず、
比較的短時間でスパっと秀丸に文字列が挿入されます。


やはり制限チェックは、事実上入っていないないか、
別の制限チェック(例えば、秀丸のMAXの64Mでチェックとか)である
ってことはないでしょうか?

[ ]
RE:09057 うむむ?No.09058
秀丸担当 さん 16/09/02 14:34
 

すみません。その通りでした。
V8.30より前はそうだったのですが、V8.30以降で改善して内部用の受け渡しにつ
いては制限を無くしていました。
失礼しました。

insert dllfunc(#dll,"test");
のような方法であれば制限に関係なく使えると思います。

[ ]