KENTEM TechBlog

建設業のDXを実現するKENTEMの技術ブログです。

Windows API 使ってみた:SetWindowPos でウィンドウを移動してみる

この記事は、 KENTEM TechBlog アドベントカレンダー2025 19日目、12月19日の記事です。

こんにちは。新卒1年目エンジニアのY・Mです。
普段クラウドアプリを担当している私は、デスクトップアプリの知識がほとんどありません。
そこで、とにかく初歩的なことから勉強したいと思い、調べてみると Windowsには Windows API(Win32 API) という、アプリからウィンドウ操作などWindowsの機能を呼び出すための API があることを知りました。
今回は Windows APISetWindowPos を使って、起動中のアプリのウィンドウを指定した位置・サイズに動かしてみます。

画面座標を理解する

普段は意識していませんが、Windowsの画面は巨大なキャンバスのような座標空間として扱われています。

  • 左上が(0, 0)

  • 右に行くほどXが増える

  • 下に行くほどYが増える

このようなルールがあります。
※マルチモニターでは、配置によって X / Y が負になることがあります。

画面座標(1920 x 1080の画面の場合)

たとえば、ウィンドウを画面左上の方に置きたいなら「X=100, Y=100」などの座標をOSに渡してあげれば動く、という仕組みです。
「それなら、この座標をプログラムから指定できたら?」
そう、ウィンドウを自由に動かせるわけです。

ウィンドウを動かす「SetWindowPos」

Windows API の中には、ウィンドウの位置やサイズを変更するための関数がいくつか提供されています。今回使うのはそのうちの一つである SetWindowPos です。

  • ウィンドウのハンドル(IDのようなもの)
  • 他のウィンドウとの前後関係(前面・背面などの重なり順)
  • X座標
  • Y座標
  • 幅(ピクセル単位の横幅)
  • 高さ(ピクセル単位の高さ)
    ※DPIスケーリング設定によっては、指定したサイズの見え方が変わることがあります。
  • 動作の細かい指示(アクティブにしない、サイズ変更しないなど)

これらを渡すと、ウィンドウを好きな位置、大きさに変更できます。
今回はこれをC#から呼び出します。

ウィンドウ移動アプリの作成

ウィンドウを動かすには、まずそのアプリがどんな名前のプロセスとして動いているかを知る必要があります。
これはタスクマネージャーの「詳細」タブで確認することができます。
例えばVisual Studio Codeのプロセス名はCode.exeです(環境により異なる場合があります)。ここから.exeを除いたCodeを使います。

プロセス名の確認方法
以下が今回作成した最小構成のサンプルアプリです。プロジェクト自体は WinForms ですが、ここでは必要な部分だけを抜き出しています。
このサンプルでは、ウィンドウの座標とサイズの指定を中心にし、前後関係や細かいオプションについては詳細には踏み込まず、標準的な指定にとどめています。また、戻り値は bool なので実用する場合は失敗時の処理を追加すると安全です。

using System.Diagnostics;
using System.Runtime.InteropServices;

namespace VsCodeMover
{
    public partial class MainForm : Form
    {
        // SetWindowPos を使う準備
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool SetWindowPos(
            IntPtr hWnd,
            IntPtr hWndInsertAfter,
            int X,
            int Y,
            int cx,
            int cy,
            uint uFlags);

        // Zオーダーを変更しないフラグ
        private const uint SWP_NOZORDER = 0x0004;

        public MainForm()
        {
            InitializeComponent();
        }

        private void btnMove_Click(object sender, EventArgs e)
        {
            // 該当するプロセス全てを配列として取得
            var vscode = Process.GetProcessesByName("Code");
            if (vscode.Length == 0)
            {
                MessageBox.Show("VSCodeが起動していません。");
                return;
            }

            // 最初の1つのメインウィンドウハンドルを取得
            IntPtr handle = vscode[0].MainWindowHandle;

            SetWindowPos(
                handle,
                IntPtr.Zero,  // SWP_NOZORDER のため影響なし
                100,          // X 座標
                100,          // Y 座標
                1200,         // 幅
                800,          // 高さ
                SWP_NOZORDER); // フラグ - Zオーダー変更なし

            MessageBox.Show("VSCode を移動しました。");
        }
    }
}

※VS Code は内部的に複数のプロセスで動作するため、取得できたプロセスによってはMainWindowHandleが取れず移動できない場合があります。

このコードを実行すると指定したウィンドウが指定した位置とサイズに変更されます。

「SetWindowPos」の活用

今回は基本として一つのウィンドウだけ動かしましたが、これを応用すると、

  • 画面中のウィンドウを配置

  • 左右に配置

  • グリッド状に配置

  • よく使うアプリを固定位置に配置

といった自分好みにカスタマイズしたウィンドウ整理アプリを作ることができます。

まとめ

今回はウィンドウを移動させることができる SetWindowPos を紹介しましたが、 Windows API を使うことで、開いているウィンドウを自動で整列させたり、よく使うショートカット操作を自動化したりと、日々の自分の作業を効率化するツールを作れるようです。

まだまだ勉強途中ではありますが、今後も Windows API について理解を深めていき、自分やチームの作業をちょっと楽にするデスクトップツールを作っていきたいです!

おわりに

KENTEMでは、様々な拠点でエンジニアを大募集しています! 建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。 recruit.kentem.jp career.kentem.jp