update : 2023/02/23 (Thu)
マクロのデバッグ方法はとしては、message 文を使う方法があります。
条件分岐で分岐先を調べる場合
if(#a == 0){
・・・
message "0 です。";
・・・
}else if(#a == 1){
・・・
message "1 です。";
・・・
}else if
・・・
変数の内容を知りたい場合
#hoge = 0;
・・・
・・・
message str(#hoge);
お手軽ですが「OK」を押すのが結構面倒です。特にループ内で使うと結構疲れます。
という事で、"debuginfo" 命令とデバッグツールの DBCon を使用したデバッグ方法を紹介します。
"debuginfo" は引数をデバッグツール(ここではDBCon)に出力します。注意しなければいけないのは、初期状態ではデバッグツールへの出力が禁止されている為、最初に出力を許可する必要がある事です。
出力を許可するには"debuginfo" に"0"以外の数字を数値を指定します。
debuginfo 1;
あとはマクロで、
debuginfo "これは実験です。";
という一文をいれておけば、デバッグツールに出力されます。
秀丸エディタ Ver.8.77以降、"debuginfo" に 数値の「2」 を指定した場合、アウトプット枠にもメッセージを出力するようになりました。 (デバッガとアウトプット枠の両方にメッセージが出力される。)
debuginfo の詳細はマクロのヘルプ debuginfo文を、参照して下さい。
例)
debuginfo 1;
$ret = input("数字を入力して下さい。","");
debuginfo "入力されたのは " + $ret +"です。\n";
endmacro;
というマクロを実行すると、DBConには以下のように出力されます。(数字はinput 命令で入力した値。)
ここで公開しているマクロは先頭に
//デバッグ時は、以下の2行のコメントを外すこと
debuginfo 1; //デバッグ出力許可
#debug = 1; //デバッグフラグ
の3行を入れて、サブルーチンとして、
DBOUT:
if(#debug == 1 && findwindowclass("DBConClass") != 0) debuginfo $$1 + "\n";
return;
を入れて、必要に応じてサブルーチンコールし、DBConに出力しています。
call DBOUT "出力したい文字列"
サブルーチンでfindwindowclass命令を使っているのはDBConが起動していることを確認しているためです。デバッグ出力を有効にしても、DBConが起動していないと出力しないようにしています。
デバッグしない場合は、
debuginfo 1;
#debug = 1;
をコメントにすればDBConに出力しません。それと、call命令があると実際には何もしない不要なサブルーチンコールをすることになるので、
call DBOUT "出力したい文字列"
もコメントにしています。
手作業でコメント・コメント解除するのは面倒なので、実際にはコメントon/offするマクロを作成し、それを使っています。
単純に秀丸を新たに開いて、出力しているだけです。これなら、OSを問いません。が、秀丸をパタパタと切り換えるので、鬱陶しいかもしれません。タブモードで使っている人は、新規のタブグループを開くようにしたほうがいいかな?
//初期設定
#dbout_hidemaru = 0;
#debug = 1;
call DBOUT2 "実験です!";
endmacro;
//
DBOUT2:
##main = hidemaruhandle(0);
if(#debug == 1){
if(#dbout_hidemaru == 0){
##ret = findhidemaru("Hidemaru_Macro_Debug_Output_Window");
if(##ret == -1){
openfile "/i";
changename "Hidemaru_Macro_Debug_Output_Window";
#dbout_hidemaru = hidemaruhandle(0);
}else{
#dbout_hidemaru = ##ret;
}
}
setactivehidemaru(#dbout_hidemaru);
gofileend;
insert "[" + time + "] " + $$1 + "\n";
setactivehidemaru(##main);
}
return;
Ver.8.77
Ver.8から、アウトプット枠が追加されています。Ver.8.77からdebuginfo でアウトプット枠にメッセージ出力が可能になりました。
call DBOUT_INIT;
DBOUT_INIT サブルーチンで初期化(?)を行っています。
デバッグツールが不要ですが、秀丸エディタが異常終了するような場合は、ログも一緒になくなります。
call DBOUT "デバッグメッセージ!!";
DBOUT サブルーチンで、メッセージを出力します。引数に文字列を指定してください。
//初期化処理
call DBOUT_INIT;
//実際に出力する
call DBOUT "デバッグ出力1!!:" + time + "\n";
newfile;
call DBOUT "デバッグ出力2!!:" + time + "\n";
settabgroup -1;
call DBOUT "デバッグ出力3!!:" + time + "\n";
endmacro;
//----------------------//
// デバック出力
//----------------------//
DBOUT:
if(#Debug_OutputFlg == 1 ){
##main = hidemaruhandle(0);
##focus = getfocus;
if(#Debug_TabMode == 0 && ##main != #Debug_Hidemaru){
//非タブモードの場合、ウィンドウ毎にアウトプット枠が存在するので、同じウィンドウに出力する。
setactivehidemaru #Debug_Hidemaru;
}else if(#Debug_TabMode == 1 && #Debug_TabGroup != tabgroup){
//タブモードで、グループIDが初期化時と違っていたら、同じタブに出力する。
setactivehidemaru getcurrenttab(false, #Debug_TabGroup);
}
debuginfo $$1;
//元に戻す
if(##main != hidemaruhandle(0)) setactivehidemaru ##main;
if(getfocus != ##focus) setfocus ##focus;
}
return;
//----------------------//
// デバック初期化
//----------------------//
DBOUT_INIT:
#Debug_TabMode = tabmode;
#Debug_TabGroup = tabgroup;
#Debug_Hidemaru = hidemaruhandle(0);
debuginfo 2;
debuginfo "";
//アウトプット枠をクリアする場合は有効にする。
//ここから
##Debug_OutputPanel = loaddll("HmOutputPane.dll");
if(##Debug_OutputPanel == 0){
#Debug_OutputFlg = 0;
return;
}
##outputhandle = dllfunc(##Debug_OutputPanel, "GetWindowHandle", hidemaruhandle(0));
##ret = sendmessage(##outputhandle, 0x111, 1009, 0);//1009=クリア
//ここまで
#Debug_OutputFlg = 1;
return;
エラー時など、ダイアログにメッセージが表示されます。ダイアログがアクティブ状態のまま、 "CTRL+C"を押すと、表示されている内容が、クリップボードにコピーされます。この方法はWindows NT系OS(NT、2000、XP、Vista、7)でしか使用できません。
Windows9x系で、同じ事を行うには、外部ツールが必要になります。
など。
秀丸エディタ Ver.8.10β3から、常駐秀丸のメニューに、「マクロ中断!」が追加されました。
秀丸エディタを強制終了させるWSH(VBS)です。無限ループに陥った場合、普通なら"ESC"キーで中断が出来ますが、効かない場合もあります。 keypressed を使用するため、disablebreak した場合など) マクロを暴走させた時に使ってください。普通に終了させることの出来る秀丸や、常駐秀丸を終了させてから、実行した方がいいでしょう。
WMIを使っているので、Windows2000、XP以降でしか動きません。あまり使うことがないようにしましょう・・・。
Ver.7.08βより、秀丸エディタ ハングアップチェッカー (HmHang.exe)が添付されるようになりました。秀丸エディタがハングアップした場合に、保護違反を発生させ、強制的に異常終了させるツールです。可能な場合は最後に一度だけ保存を試みることが出来るようです。