October 16, 2009
[PC環境改善] PuTTY + Drag&Drop (2)
前回の続きです。
PuTTY にファイルやフォルダをドロップすると、パスが入力されるようにするパッチです。前回は Cygwin 1.5 のみの対応でしたが、今回は Cygwin 1.7 にも対応しました。
- パッチ: putty-0.60-file-dnd-src-for-cygwin1.7.patch (5,005 バイト)
- パッチ適用済み実行ファイル: putty-0.60-file-dnd-src-for-cygwin1.7.zip (429,568 バイト)
- License: PuTTY License
以下の環境にて使用できます。
- PuTTY 0.60 ごった煮版 (2007/8/6 版)
- Cygwin 1.7 (Cygwin の /bin にパスが通っていること)
- Cygterm 1.07 (1.05 でも動くはず)
October 11, 2009
[PC環境改善] PuTTY + Drag&Drop
コマンドプロンプトでは、ファイルやフォルダをドロップすると、パス名が入力されるようになっています (Vista 以降はセキュリティ強化の一環で使用できなくなりましたが…)。これを PuTTY にも実装しました。
- パッチ: putty-0.60-file-dnd-src-for-cygwin1.5.patch (4,049 バイト)
- パッチ適用済み実行ファイル: putty-0.60-file-dnd-src-for-cygwin1.5.zip (429,431 バイト)
- License: PuTTY License
以下の環境にて使用できます。
- PuTTY 0.60 ごった煮版 (2007/8/6 版)
- Cygwin 1.5 (
1.7 は文字コードが EUC-JP になっているために(2009/10/12 追記) 1.7 では環境変数 LANG が未設定の場合に UTF-8 でパスを返すので2バイト文字が扱えません。1.7 用は現在作成中) - Cygterm 1.07 (1.05 でも動くはず)
Windows から渡されたフルパス名を、cygpath コマンドを使って Cygwin パス名に変換しています。ですので、Cygwin の bin ディレクトリにパスが通っている必要があります。
なお、PuTTY でリモートマシンに接続している場合にも、ファイルやフォルダをドロップすることはできますが、そこで入力されるパスは、あくまでローカル PC のパスです。
October 10, 2009
[プログラミング] ウィンドウ移動中のメッセージループは別物
MFC や Windows フォームを使わずに、ウィンドウを使うアプリを作るときは、メッセージループが出てきます。でも、このメッセージループで何か処理をしよう、というのは Windows から見たら邪道のようです。
Windows プログラムをスクラッチから書いていたときの話です。
メッセージループが動いている様子を確認するために、PeekMessage() API を使って以下のコードを書きました。
MSG msg;
for (;;)
{
BOOL msg_arrived = ::PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE );
if ( msg_arrived )
{
if ( msg.message == WM_QUIT )
break;
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
// メッセージループが動いていることを確認する何かの処理
SomeOperationInEveryMessageLoop();
}
RegisterClassEx, CreateWindow を呼び出してウィンドウを作った後、メッセージループに入り、SomeOperationInEveryMessageLoop() 関数がちゃんと呼ばれていました。
ところが、そのウィンドウのタイトルバーの上でマウスの左ボタンを押したままにすると…、メッセージループ中の SomeOperationInEveryMessageLoop() が呼ばれなくなりました。おや?
「titlebar drag message loop」でググってみると、MSDN のフォーラムがヒットしました。
それによれば、マウスクリックによって Windows 内部のモーダルループに制御が移ってしまうとのこと。なんと。ちなみに下記はその書き込みの引用。
Clicking on the title bar starts a modal message loop inside of windows to allow the user to move the window.
自作のメッセージループが回らない今回の謎は解けましたが…、これで終わるのもなかなかもったいないので、解決法はないものかと、同じキーワードで続けてググってみて、もっともそれらしい解決法を発見。
メッセージループそのものには割り込めないから、タイマーでメッセージを送らせて処理するしかない、ってことです。
DialogBox() や MessageBox() を呼び出したときには内部メッセージループに入ることは知っていましたが、まさかウィンドウの移動やサイズ変更でも内部のループに入ることは知りませんでした。おそらく、別のループに入る条件はほかにもたくさんあるでしょう(あったような気がしますが、思い出せません…)。それを踏まえると、定期的な処理をしたいがためにアプリのメッセージループを使うのは、あまりよい方法ではなく、そういう処理をしたいのであれば、素直にタイマーを使いなさい、ということでしょう。