非同期でプログラムを実行するバッチを、パイプする

start コマンドを使い、非同期でプログラムを実行するバッチを作成し、そのバッチの出力をパイプすると、実行したプログラムが終了するまでパイプの処理が返らない。

pause.cmd

@echo pause
@exit /b

process.cmd

@echo off
Echo 処理1開始
Rem 処理1
Echo 処理2開始
start "" cmd /s /c "pause.cmd"
exit /b

と作成し、コマンドプロンプトで単に

process.cmd

とすれば、pause.cmd を閉じなくても次の処理に進めるのだが、

process.cmd | sort

などとパイプしたとたん、処理が返らなくなってしまう。

これの対処法はいくつかある。 続きを読む

[Powershell] UTF-8 でエンコードされた標準出力を受け取る

2バイト目に ASCII コードがくることを想定していないコンソールアプリなど、標準出力を UTF-8 として使用するコンソールアプリは少なくない。
しかし、PowerShell は標準では UTF-8 の標準出力をそのまま読み取ることができない。
(後述するが、単純な方法はある)

そういった場合でも、.NET Framework を駆使すれば、ちゃんと文字列として取得できる。

続きを読む

XPath で、Doctype 宣言以外のコメントだけ抜き出す

DOM level3 に対応したブラウザで使える、 javascript の document.evaluate であれば、XPath ですべてのコメントを抜き出すときに、

var result = document.evaluate("//comment()", document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);

等としておけば問題ないが、一部の HTML パーサでは、HTML の DOCTYPE 宣言もコメントとして扱ってしまうものがある。
…と言うより、 "<!" で始まって、">" で終わるものはすべてコメントとして扱ってしまうような場合について。

続きを読む

IEではhtmlのid属性がwindowのプロパティになる

JavaScriptでは、varによる変数宣言をしていない場合、グローバルオブジェクト(window)のプロパティとして扱われる。
IEでは、htmlのid属性が、このグローバルオブジェクトのプロパティになってしまうらしい。

以下のコードで、「click!」というアラートが出たら、 window.btn01 に button の DomElement が入っているということになる。(Firefox や Chrome 等では、エラーになってなにも表示されないはず)

<button id="btn01" onclick="alert(btn01.innerHTML);">click!</button>

しかも jQuery が有効な状態で、

btn01 = null;

などとやろうとすると、btn01 変数にはすでに button の DOM が入っているのと、IE8とjQueryの相性の問題で、IEではエラーになってしまう。

まぁ、

var btn01 = null;

と、var つけてやるだけでOKだし、そもそもIE9ではエラーにならないので、古いブラウザ使うなってコトでFAでもよい気がしないでもないけどね…
とはいえ、9/1現在、IE8がシェア35%と圧倒的なので無視できないのよねぇ
参考: 日本のバージョン別ブラウザシェアグラフ (StatCounter Global Statsより)

[powershell]引数が配列のメソッドが呼べない

PowerShellのなにが便利って、.NETアセンブリが読み込めちゃうので、
もう何でもかんでもできてしまうところ。
Windows7から標準で入っているので、業務用ツール作るのに最近よく使う。
それは置いといて…
表題の、引数が配列のメソッドが呼べない件。

続きを読む

コマンドプロンプトのcompコマンドが、いちいち「ほかのファイルを比較しますか」と聞いてきてウザい

2019-06-12 追記:

いつからか不明だが、少なくとも Windows 10 の最近のバージョンでは、 comp.exe/M その他のファイルを比較するメッセージを表示しない オプションが追加されている。

以下は、 Windows 7 当時の話。


コマンドプロンプトで、2つのファイルまたはファイルセットの内容を比較するコマンド、comp.exe

しかしこのコマンド、終了時にいちいち
「ほかのファイルを比較しますか」
と聞いてきてかなりウザい。

これを表示させないオプションがなぜか存在しないのだ。

特にバッチでループさせ対するときに、毎回毎回停止してしまうので、
すこぶる迷惑なのだが…

で、これを回避する方法だが、 "N" を自動で入力させるほか無い。
つまるところ、

echo n | comp Data1 Data2

という風に、echoを使って "n" と改行をパイプしてやれば、めでたくcompでループすることができる。

仕組みがわかればなんてことはないのだが、気づかないとちょっと悩んでしまうところだ。

エディットコントロールの高さを、文字列や横幅にあわせて自動的に変更する

横幅がぐりぐり変わり、複数行表示可能なエディットコントロールを、文字列にあわせて、高さを調節したい。

DrawText 関数に、 DT_CALCRECT フラグを設定することで、指定した幅に収まる文字列を表示するのに必要な矩形の取得だけをすることができる(描画されない)。
コレを使ってコントロールの高さを計算し直せば実現できる。

上のエディットコントロールを書き換えると、その文字列が下のエディットコントロールに反映され、サイズが変更されるようなサンプルを作った。

ばりばり ATL/WTL 使ったコードだが、基本的に普通にWin32API呼んでも同じようにできる。

続きを読む

継承するなら、基本・派生どちらにもデストラクタを書かないとしても、仮想デストラクタが必要!?

継承されるクラスに仮想デストラクタを書かなくてはならない理由として、
よく、ポリモーフィズムを使った場合に、派生クラスのデストラクタが実行されない理由が挙げられる。
"継承 仮想デストラクタ" でググった結果

そうすると、「派生クラスにデストラクタ書かなければ当然仮想デストラクタでなくてもいい」と思いがちだが、
実はそんなことは全然無い。

続きを読む

WM_SIZEをハンドルしないCDialogResizeを作る

前回突然オーバーライドと隠ぺいの話をしたのは、
今回の話につなげるため。

CDialogResizeは便利だが、
チェインを使ってコレを処理してしまうと、
その後にWM_SIZEの処理をすることができなくなってしまう。
(チェインする前に捕まえて、 bHadled=FALSE することは可能)

じゃあCDialogResizeを継承して、処理した後にreturnしないようにすればよいのだが、
OnSize関数は仮想関数ではないので、書き換えることができない。

ところが、そのOnSizeを呼んでいるメッセージマップの実態である、
ProcessWindowMessage関数は、(BEGIN_MSG_MAPマクロの中身)
チェインからのみで、CDialogResize内部からは呼ばれていないので、
これを隠ぺいしてしまえば、CDialogResizeのProcessWindowMessageは呼ばれない。

つまり、WM_SIZEを捕まえてもreturnしないProcessWindowMessageを書けばいいのだ。

続きを読む