2020年05月23日

ver.1.21は、いってんにじゅういち と読むのが正しいらしいな

最近、ソフトウェア制作をしていて、ふと思ったこと。

ver.1.21は、「いってんにじゅういち」と読むのが正しいらしいな。

MS-DOS ver.3.3のころ、「ver.3.3」と「ver.3.30」は同じことを意味しており、いわゆる普通の小数点の表記と同じだったような気がする。

これであれば、さんてんさんれい と読むのが正しいんだと思うんだけど、最近では、さらにその下のマイナーナンバーを示したければ3.3.0と書くようなのが一般的らしいから、1.21はいってんにじゅういちであって、最後の1が1.2のさらにマイナーな(小数点第二位相当の)バージョンアップということを意味したいなら、1.2.1と書くのが一般的っぽい。

所説あるはず。

posted by ayacy at 23:25 | Comment(0) | TrackBack(0) | プログラミング

2020年04月23日

「マウスふるふる」と同じ機能をPowerShellでも作れないかな?という試み

DIYプログラミングのお時間ですね。

リモートワークブームのおかげで、なぜだかSNS上で話題をよく見かけるようになったマウスふるふるなのですが、そもそもインターネットからファイルをダウンロードすることが許されないとか、許可されたexe以外を実行できない環境もあるとかで、ExcelだったかVBSだったかで同じような機能を作った、みたいな話も聞こえてきました。

となると、PowerShell版も作れるのかな?とふと思い浮かんで、試してみました。
50秒おきにマウスを左右に1ピクセルゆらす感じの。

# .NETのCursorクラスを利用するためにSystem.Windows.Formsをロード
add-type -AssemblyName System.Windows.Forms


while ($true) {

    # 50秒スリープ
    echo "50秒スリープ"
    Start-Sleep 50

    # 現在のマウスのX,Y座標を取得
    $x = [System.Windows.Forms.Cursor]::Position.X
    $y = [System.Windows.Forms.Cursor]::Position.Y
    echo "マウス座標:($x, $y)"

    # マウス座標を少し左にずらす
    $x++;
    [System.Windows.Forms.Cursor]::Position = new-object System.Drawing.Point($x, $y)
    $x = [System.Windows.Forms.Cursor]::Position.X
    $y = [System.Windows.Forms.Cursor]::Position.Y
    echo "→マウス座標:($x, $y)"

    # マウス座標を少し右にずらす
    $x--;
    [System.Windows.Forms.Cursor]::Position = new-object System.Drawing.Point($x, $y)
    $x = [System.Windows.Forms.Cursor]::Position.X
    $y = [System.Windows.Forms.Cursor]::Position.Y
    echo "→マウス座標:($x, $y)"
}



あれ?うまく動かない。スクリーン セーバーを1分に設定したら、60秒ちょっと経過したところでスクリーン セーバーが起動しちゃいました。
もしかして管理者権限で動かさないとダメとか…?とか思いましたが、管理者権限でもダメでした。

もしかして、もっとはっきり、かつ、時間をおいてマウスを動かさないとダメ?とか思いまして、1秒おいて10ピクセル右、また1秒おいて10ピクセル左、という動きを永久ループさせてみることにしました。


# .NETのCursorクラスを利用するためにSystem.Windows.Formsをロード
add-type -AssemblyName System.Windows.Forms


while ($true) {

    # 1秒スリープ
    echo "1秒スリープ"
    Start-Sleep 1

    # 現在のマウスのX,Y座標を取得
    $x = [System.Windows.Forms.Cursor]::Position.X
    $y = [System.Windows.Forms.Cursor]::Position.Y

    # マウス座標を少し左にずらす
    $x+=16;
    [System.Windows.Forms.Cursor]::Position = new-object System.Drawing.Point($x, $y)
    $x = [System.Windows.Forms.Cursor]::Position.X
    $y = [System.Windows.Forms.Cursor]::Position.Y
    echo "→マウス座標:($x, $y)"

    echo "1秒スリープ"
    Start-Sleep 1

    # マウス座標を少し右にずらす
    $x-=16;
    [System.Windows.Forms.Cursor]::Position = new-object System.Drawing.Point($x, $y)
    $x = [System.Windows.Forms.Cursor]::Position.X
    $y = [System.Windows.Forms.Cursor]::Position.Y
    echo "→マウス座標:($x, $y)"
}



やっぱりうまく動かない。スクリーン セーバーは動いてしまいました。
もしかすると、.NET Frameworkだとサンドボックス的なところの中で動くからうまく行かないとかでしょうか?よくわかりませんでした。

最初に触れた、ExcelだったかVBSだったかで同じような機能を作った方は、その後うまく動いたのかが気になりますね。
…と、ここまで書いて、ふと、マウスのポインタの移動ではダメで、マウスイベントを偽装させる必要があったことに気づきました。


続きを読む
posted by ayacy at 00:00 | Comment(0) | TrackBack(0) | プログラミング

2020年02月20日

Windows10を1909アップデートしたら、エクスプローラーの検索窓のIME状態の挙動が変わった?

一昨日、フィードバックから、Windows10をver.1909にアップデートしたら、エクスプローラーの検索窓のIME状態を変えられなくなった、というご意見をいただきました。

NumLockLockでIME状態を自動でONにする設定をしていたのだが、どうも、そうならなくなったとのこと。(もちろん手動では変えられる)

実際、手元の環境で試してみると、再現できました。
最近のWindowsでの挙動の変化ということらしいですが、詳細は不明です。

202002_NLLIME1.png

NumLockLockを常駐させ、IMEが常にONになるように設定した場合、普通のウィンドウ上(管理者権限で動作しているウィンドウを除く)であれば、IMEを常にONにする機能が働きますが、上記の画像のように、エクスプローラ右上の検索窓にカーソルを置いた場合に限り、この機能が働きません。

これは何が起きているのか?

実際、プログラム中で何が起きているのかと思い、デバッグ用のコードを仕込んでみました。

202002_NLLIME2.png

hActiveWindowは、GetForegroundWindow() APIで取得したウィンドウハンドルです。
これに対し、SendMessageでWM_IME_CONTROLで0x05(IMC_GETOPENSTATUS)を送ると、IME状態がONなのかOFFなのかを取得することができます。

上記の画面のような状態で、WM_IME_CONTROLの5(IMC_GETOPENSTATUS)が何を返しているのか調べました。
デバッグ用の仕込みを入れることで、IMEがONであると認識していれば、Windowsの標準の警告音が鳴り続けます。

で、実際動かしてみたら、Windowsの標準の警告音が鳴り続けました。
(画面上、IME状態はOFFであるにも関わらず!)

というわけで、画面上のステータスと、Windows APIが返すステータスが不一致であるという、よくわからない現象に遭遇していることが分かりました。
ユーザーの情報によれば、この現象はWindows10を1909にアップデートしたら起きるようになったとのことなので、他のバージョンでは起きないものと思われます。

さて、何が起きているのか? 例えば、次のようなことが考えられます。

  • エクスプローラーの検索窓だけ、管理者権限で動いているため、外部のウィンドウメッセージを受け付けてくれない。
  • カーソルが置かれている窓と、GetForegroundWindow()が返すウィンドウハンドルが、実は異なっている。例えば、編集ボックス自体と、プルダウン表示している最近入力した選択肢のウィンドウが別で管理されており、画面上のIME状態表示とWM_IME_CONTROLが返す値が異なっている、あるいは、見た目カーソルの置かれているアクティブな入力窓とGetForegroundWindow()が返すウィンドウハンドルがそれぞれ別のものを指した状態になってしまっている。

フィードバックでは、ユーザーからは状況の改善を依頼されているのですが、悪化したのはOSの側(プログラムに画面状態とは異なるウソ情報を返している?)な感じがするため、ちょっと一介の日曜プログラマの手には負えない感じがしています。OSの次回アップデートで状況が改善するのを祈るのみな気がします。



posted by ayacy at 00:00 | Comment(4) | TrackBack(0) | プログラミング