runsync2とfindhidemaruNo.01927
sT さん 01/03/29 22:24
 
runsync2とfindhidemaruの使い方をお教えください。
(なるべくこちらの状態をお伝えするために長文になってしまいましたが、お許しく
ださい。)

ある一つのファイル上に分散した文字列を、別の一つのファイルにまとめるマクロを
組みました。
しかし、runsync2実行後のfindhidemaruでエラーとなってしまいます。
添付のマクロは(再現に必要な処理の)抜粋で、"c"行を通ってしまいます。

マクロの実行は、取得元となるファイルを開き、そのウィンドウのメニューから行い
ます。
マクロの目的から、取得元と生成先のウィンドウを頻繁にsetactivehidemaruし、
クリップボードで情報を交換します(添付マクロではクリップボード処理は割愛して
あります)。
ここで、コマンドプロンプトから情報を取得する箇所(添付マクロの"a"行)があり、
runsync2を実行しましたが、その後、発行した側のウィンドウをfindhidemaruするこ
とができませんでした。

この件は、一度目のマクロ実行で再現しない場合があり、
そのときは再度実行することで発現する(正確には発現し続ける)ようになります。
(秀丸を常駐設定している場合、一度目は成功し、非常駐の場合は一度目から再現す
るようです。)

この問題を解決する方法は、2つありました。
一つはrunsyncを使用する方法。もう一つは、添付マクロ中の"a"行と"b"行の間に、
messageなどのウィンドウをアクティブにするコマンドを発行する方法です。
しかし、頻繁にコマンドプロンプトから情報を取得するため、
runsyncの発行元ウィンドウが再描画されるのは防ぎたく、
また、度々表示されるウィンドウ(正確にはダイアログ)にユーザが応答することも
避けたいと考えています。
結果として、こちらでの希望する処理を作り出すことができませんでした。

こちらで調べられたことは、この程度でした。
もしこの件についてご存知の方がいらっしゃいましたら、お教えください。


OS   : Windows2000 SP1
秀丸 : 3.08
(他に必要な情報がありましたら、ご指摘ください。)


--ここから--
    $CURNAME = filename2;
    $TMPNAME = "c:\\test.txt";

    if ( findhidemaru( $TMPNAME ) != -1 ) {
        setactivehidemaru findhidemaru( $TMPNAME );
    } else {
        openfile $TMPNAME;
    }

    runsync2 "cmd /c";                                  // a

    if ( findhidemaru( $CURNAME ) != -1 ) {
        setactivehidemaru findhidemaru( $CURNAME );     // b
    } else {
        message $CURNAME + "が見つかりません。";
        endmacro;
    }

    if ( findhidemaru( $TMPNAME ) != -1 ) {
        closehidemaru findhidemaru( $TMPNAME );
    } else {
        message $TMPNAME + "が見つかりません。";        // c
        endmacro;
    }
--ここまで--

[ ]
RE:01927 runsync2とfindhidemaruNo.01928
TAKA さん 01/03/29 23:25
 
TAKA です。

>こちらで調べられたことは、この程度でした。
>もしこの件についてご存知の方がいらっしゃいましたら、お教えください。

Windows ME
秀丸 3.08でテストしてみました。

テストした条件は

c:\test.txtは存在しない状態
マクロを実行する秀丸は今回のテスト用マクロファイル
Windows ME なので、「cmd」となっている所を、「command」に変更。
常駐秀丸を使用。
テスト用マクロファイル以外は開いていない状態

です。


常駐秀丸を使用した場合は、2回目から再現するとのことでしたが、
私の所では、10回ほどマクロを実行しましたが、c:\test.txtを
開いた後直ぐに閉じて、マクロを実行した秀丸がアクティブになり
ました。(つまり、正常に動作しました)


根本的な解決ではありませんが、findhidemaruがうまくいっていな
いとのことですので、findhidemaruを極力使わない方法でマクロを
組んでみてはどうでしょうか?

// マクロ(ここから)
    $TmpName = "c:\\test.txt";
    #FH = hidemaruhandle( 0 );
    #TmpNo = findhidemaru( $TmpName );
    if( #TmpNo == -1 )
    {
        openfile $TmpName;
        #TmpFH = hidemaruhandle( 0 );
    }
    else
    {
        #TmpFH = hidemaruhandle( #TmpNo );
    }

    runsync2 "cmd /c";

    setactivehidemaru #FH;
    closehidemaru #TmpFH;

    endmacro;
// マクロ(ここまで)

解決になってなくて、すみません。

[ ]
RE:01927 runsync2とfindhidemaruNo.01929
杉浦 まさき さん 01/03/29 23:40
 
sT さん、はじめまして。
杉浦 まさき と申します。

既に開いているウィンドウ間を頻繁に移動する場合は、
findhidemaru() をいちいち呼ぶより、
hidemaruhandle() でウィンドウハンドルを取得して、
以降はそれを setactivehidemaru に渡した方が
早い&動作も若干?安定すると思います。
#それでも切り替えが頻繁に起こると処理が追いつかない?で
 こける事があります。

以下はそのサンプルです。

// ------------------
$CURFILE = filename2;
$TMPFILE = "tempfile.txt";

#hwnd = hidemaruhandle(0); // 現在のウィンドウのウィンドウハンドル

#order = findhidemaru($TMPFILE);
if (#order == -1) {
    openfile $TMPFILE;
} else {
    setactivehidemaru #order;
}
#hwnd_tmp = hidemaruhandle(0); // $TMPFILE を開いた秀丸のウィンドウハンドル

setactivehidemaru #hwnd; // 元のファイルに戻る
// ... (色々な処理)

setactivehidemaru #hwnd_tmp; // $TMPFILE に移動
// ...

//----------------------


[ ]
RE:01927 runsync2とfindhidemaruNo.01931
ひろ さん 01/03/30 00:19
 
 sT さん今日は、ひろです。
> runsync2とfindhidemaruの使い方をお教えください。
 ヘルプに
> runsync,runsync2文はrunと同様にプログラムを実行しますが,runと異な
> る点は起動したコマンドが終了するまでマクロの実行を待機させる点です。
と記載がありますが、ここで「コマンドと終了」とは run 型の文で起動し
たアプリケーションが終了するまでです。runsync2 で実際にどの様なコマ
ンドを発行しているか不明なので、詳細は解りませんが、この事が関係して
いるのではないでしょうか。

[ ]
RE:01928 runsync2とfindhidemaruNo.01932
TAKA さん 01/03/30 11:18
 
TAKA です。

>Windows ME
>秀丸 3.08でテストしてみました。

ちなみに、私がテストしたのは、サンプル通りにコマンドを何も指
定しない状態でテストしました。
「cmd」を「command」に変更しただけです。
sTさんの所でも、コマンドを何も指定しない(サンプルマクロ通り)
状態で、不具合は再現しているのでしょうか?

[ ]
RE:01928 runsync2とfindhidemaruNo.01933
sT さん 01/03/30 14:36
 
ご回答いただいた皆さん、ありがとうございました。
原因がわかりました。はじめに、この解決方法を書きます。

直接の原因は、TweakUIというカスタマイズ ツールにより、
[アプリケーションにフォーカスを横取りさせない]という項目を
有効にしていたことです。
マクロに汎用性を持たせるため、以下のようなコードをマクロの先頭に追加しました。

// ここから
openreg "CURRENTUSER", "Control Panel\\Desktop";
#LOCK = getregnum( "ForegroundLockTimeout" );
closereg;
if ( #LOCK != 0 ) {
    message "このシステムは、ウィンドウのアクティブ化を抑止する設定になって
います。\n" +
            "setactivehidemaruなどの秀丸管理マクロが正常に動作しないケースが
あるため、\n" +
            "マクロを終了します。";
    endmacro;
}
// ここまで


TAKAさんには、実際に試験を行っていただいたようですね。
また、詳細な試験環境を書いていただき、大変参考になりました。
特に、WindowsMEでは正常、とあったため、原因に気が付きました。
(WindowsMEは、(リリース時期から)Windows2000とほぼ同一のシステム環境を持っている
と考えられたためです。)
秀丸には多くの設定項目があり、その設定によって他のシステムでは再現しないかも
しれない、
とは考えていました。しかし、システム側の設定に問題があるとは、気付きませんで
した。
TAKAさんからのコメントをきっかけに「何かシステムの設定を変えたかな?」と
考えられるようになりました。

> 解決になってなくて、すみません。

と言われていますが、とんでもありません。
解決の糸口をお教えいただいたため、感謝しています。


TAKAさんのコメントにもありましたが、杉浦 まさきさんからのコメントをきっかけに
ウィンドウハンドルでの制御方法をその利点を知りました。

> hidemaruhandle() でウィンドウハンドルを取得して、
> 以降はそれを setactivehidemaru に渡した方が
> 早い&動作も若干?安定すると思います。

解決するまでの間、暫定的にrunsyncを使用していたのですが、
(秀丸とは無関係の)別のプロセスがシステムに過負荷をかけたとき、
同時に実行していたマクロ中のfindhidemaruがエラーになってしまいました。
しかし、ウィンドウハンドルでsetactivehidemaruすると、
エラーになるケースはありませんでした。


皆さんにお教えいただいた知識から、個々のシステム環境に依存せず、
より安定した動作を行う良いマクロを作ることができそうです。
本当にありがとうございました。

[ ]
RE:01932 runsync2とfindhidemaruNo.01934
sT さん 01/03/30 14:39
 
>ちなみに、私がテストしたのは、サンプル通りにコマンドを何も指
>定しない状態でテストしました。
>「cmd」を「command」に変更しただけです。
>sTさんの所でも、コマンドを何も指定しない(サンプルマクロ通り)
>状態で、不具合は再現しているのでしょうか?

実際には、copyコマンドを実行させていました。
ただ、再現性には無関係でしたので、割愛いたしました。

[ ]