hoge diary - October 2009

October 16, 2009

[PC環境改善] PuTTY + Drag&Drop (2)

前回の続きです。

PuTTY にファイルやフォルダをドロップすると、パスが入力されるようにするパッチです。前回は Cygwin 1.5 のみの対応でしたが、今回は Cygwin 1.7 にも対応しました。

以下の環境にて使用できます。

October 11, 2009

[PC環境改善] PuTTY + Drag&Drop

コマンドプロンプトでは、ファイルやフォルダをドロップすると、パス名が入力されるようになっています (Vista 以降はセキュリティ強化の一環で使用できなくなりましたが…)。これを PuTTY にも実装しました。

以下の環境にて使用できます。

  • 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() を呼び出したときには内部メッセージループに入ることは知っていましたが、まさかウィンドウの移動やサイズ変更でも内部のループに入ることは知りませんでした。おそらく、別のループに入る条件はほかにもたくさんあるでしょう(あったような気がしますが、思い出せません…)。それを踏まえると、定期的な処理をしたいがためにアプリのメッセージループを使うのは、あまりよい方法ではなく、そういう処理をしたいのであれば、素直にタイマーを使いなさい、ということでしょう。


Valid XHTML 1.1! Valid CSS!
© 2004-2009 ぱくちゃん.
Last modified: Fri Oct 16 02:26:53 JST 2009