布団が俺を呼んでいる

丘山大一のぶろぐ

他のアプリケーションウィンドウを操作する

この前出した「ぷるまど」の内部実装の話。

やっぱWinAPIだよね

他のアプリケーションを操作する場合、基本的にはウィンドウハンドルをどうやって取得するか、という問題に絞られます。
プロセスが分かっている場合はもちろんプロセスから攻めるわけですが、今回は「ウィンドウ」があるものをを取得したい。
というわけで、それを取得するAPIがEnumWindowsです。

    public class WinAPI
    {
        [DllImport("user32")]
        public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, IntPtr lParam);
        [DllImport("user32")]
        public static extern bool IsWindowVisible(IntPtr hWnd);
        [DllImport("USER32.DLL", SetLastError = true)]
        public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
    }

みたいな感じでテキトーに定義して、EnumWindowsを呼び出してくるくる回せば色々できます。

        WinAPI.EnumWindows((h, i) =>
        {
            if (WinAPI.IsWindowVisible(h))
            {
                WinAPI.GetWindowThreadProcessId(h,out int id);
                result.Add((h, Process.GetProcessById(id).ProcessName)); //このresultに結果を蓄えているので、後はご随意に
            }
            return true;//Trueを返すと処理が継続する
        },
        IntPtr.Zero);

「WinAPI.IsWindowVisible」を呼び出して、ウィンドウが表示されているかどうかを判定していますが、「ウィンドウは持っているけど表示されない」みたいな例外動作をするアプリケーションもあります。
代表例がexplorerのProgram Manager。
こういった特殊なアプリケーションをどう扱うかは仕様次第だと思います。
「ぷるまど」は汎用的、かつ雑なアプリということもあり、そのあたりはあまり考えないことにしました。「ぷるまど」には、他のアプリケーションの都合が分からないから、とりあえず表示しておけ、てな動作をしています。


ウィンドウ操作系API等

他にはこの辺りを、こんな感じで定義して使っています。

        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll")]
        public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        public const int SW_RESTORE = 9;  // 画面を元の大きさに戻す
        public const int SW_SHOWNORMAL = 1;
        [DllImport("User32.dll")]
        public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
        [DllImport("user32.dll")]
        public static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, int bRepaint);
        [DllImport("USER32.DLL", CharSet = CharSet.Auto)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

何をするAPIかは、名前を見てもらえば大体わかるかと……

窓断熱シート マジックミラー フィルム ガラス透明断熱フィルム 建築建物ガラスフィルム 目隠しフィルム 窓のサングラス省エネフィルム めかくしシート 窓フィルム マジックミラー 紫外線カット 飛散防止 ミラー(90cm×200cm, シルバー)

新品価格
¥2,378から
(2018/7/20 17:14時点)

コメントを書く

布団が俺を呼んでいる | MacBookに親しもう 4

布団が俺を呼んでいる

丘山大一のぶろぐ

MacBookに親しもう 4

現時点の、感想や問題点・疑問点・不満を書いていきたいと思います。
現時点なので、使い込んでいるうちに解決したり違う意見になったりすると思います。


トラックパッドについて

よく「トラックパッドが使いやすい!」という記事を見ましたが、正直「すごく使いやすい!」とは感じていないです。なんていうか普通。大きいのはちょっとうれしい、くらい。
これは、MacBook を真似したSurfaceのトラックパッドを使っていたせいでこういう感想になっているのだと思います。


電源アダプタ

自分で使ってみると思いのほか邪魔。電源タップに差すには、端っこに差すしかない。
しかもデカい割にはSurfaceのようなUSB充電機能があるわけでもない。
これ、なんとかならなかったのかな。


ウィンドウの×-+ボタンの位置が悪い

macのUIはそーいうものなんだー、としか最初は思っていなかったんですが、使ってみると思いのほか具合が悪い。
特に「< 戻る」が画面左上に配置されていることが多い関係上、必然的に×ボタンとの押し間違いに気を付けなくてはならなくなっている。×はアプリ終了時、最後にしか使わないので、押しやすい位置にある必要性が全くない。これはクソUIですわ。
と思ったのですが、web検索するとこれが「いい!」とする意見が散見されました。むむ。
これもようは「慣れ」、なので、使っていくうちに私もこれが「いい!」となるのかもしれません。


アプリ機能のメニューバーへの統合について

アプリを起動すると、メニューバーが切り替わる。のはいいんですが、これのせいでメニューを触るときに「今、どのアプリがアクティブなのか?」を気にしなくてはならないのが面倒くさい。
Windows的には「操作したいアプリを選択」→「メニュー操作」の2ステップ。
Mac的では「操作したいアプリを選択」→「メニューバーに移動」→「メニュー操作」の3ステップ。
そもそもメニューバーに専用メニューが表示されているかどうかも、初めて見るアプリでは判別がつかないので辛いですね。
ただ、アプリのUIが共通化されてもいるので、慣れれば楽なのかな、という気もしています。


かな/英数 による入力切り替え

まだ操作慣れしていませんが、これは良いなーと思っています。キーとその動作が一貫している。
改めて考えても、Windowsの半角/全角で切り替えって意味分からんですよ。


標準エディタが無い?

いわゆるメモ帳、もしくはVi。
とりあえずテキストがパッと開けるヤツ。単純なプレーンテキストとしてしか読み込めないヤツ。
テキストエディットがそれなのかと思いましたが、表が入れられたりして(リッチテキスト?)逆に不便。「テキストしか開けない」がゆえに「常にテキストで表示してくれる」ものが欲しいですね。
※設定で変えられるみたいなんですが、そういう設定すら無いものがあると嬉しい、ということです。


標準ドローソフトはどれ?

いわゆるペイントがどれだか分からなかった。1からただのお絵描きーしたいー、という時に使うヤツ。


標準でチェスオンリーはダメだろ

これは語るぜ。

Windows の標準ゲームといえば、マインスイーパ、ソリティア。(ピンボール? オジサンその時代のことは知らないっていう設定だから分からないなあハハハ)
これらのゲームは何が重要だったかと考えると、
すぐ始められて、
すぐ終わりにできて、
終了時間の予測が立ちやすく、
繰り返し挑戦が容易で、
頭を使わなくて済む
ことだと思います。
マインスイーパは、1分もあれば十分に遊べるし、10分もあればソリティアは終わる。両方ともマスとカードの残りが分かるので、終了までの時間予測が各々立てられる。ミスった際のやり直しも簡単なので、ストレスもたまりにくい。
「頭を使わなくて済む」のもかなり重要で、頭を使う作業の息抜きには頭を使いたくないというニーズを満たせる。

もっと言ってしまうと、これらのゲームは仕事の息抜きに丁度良いのです。
断じてサボリではない。息抜きによいのです。
ふっと息抜き、頭が回り始めたら仕事に戻る。
なにより標準なので、マシンを変更されても変わらず遊べる。
業務OSとしてあるべき正しい標準ゲームです(標準でゲームが無かったWindows 8は大問題だった.。こんな記事が出るくらいには問題だったhttps://msdn.microsoft.com/ja-jp/magazine/mt238411.aspx?f=255&MSPPError=-2147217396)。

チェスはすべてにおいて逆です。
じっくり取り組む必要がある。ゲーム性が高すぎる。息抜きのゲームのはずなのに、逆に仕事中にチェスを思い浮かべてしまう。
チェスという選択肢があるのは実に良いと思うのですが、標準では違うゲームが必要だと思うのです(力説)。

あとな、チェス全然知らないから勝てないんだヨ(泣)


アップデートの意味が分からなかった

画面右上に出てきたコレ。


選択肢が「今はしない」「オンにする」とありますが、これが意味不明。
普通に捉えると、
「今はしない」=>アップデートを実行しない。
「オンにする」=>アップデートの機能を有効化する。
という意味になります。
しかしこれでは、二つの選択肢が背反するものになっていない。
選択肢が「今はしない」「今すぐする」のペア、あるいは「オフのままにする」「オンにする」なら理解できます。

おそらくタイトルが間違っていて「自動アップデートにしますか?」もしくは「自動アップデートを有効にしますか?」だと思うのですが、いかんせん断定できるほどmacに詳しいわけでもなく。

と長々書いたのですが、これも結局「慣れ」の範疇。
文章や選択肢がおかしいことは他のOSでもままあること。
私もおかしい文章はよく書きますし、たった一か所の文章で人を責めても���カンですね。


というわけで、色々思うところがあるのですが結論


慣れやな。


Apple MacBook Air (13インチ, 1.6GHzデュアルコアIntel Core i5プロセッサ, 256GB) - スペースグレイ

新品価格
¥159,183から
(2019/1/14 17:05時点)

コメントを書く