中堅プログラマーの備忘録

忘れっぽくなってきたので備忘録として・・・

【Unity】Windowsアプリの起動ポジションの設定とツールバーを非表示にする方法

1.概要

WindowsをターゲットにしたデスクトップアプリケーションをUnityで作成した時に
起動ポジションの指定とツールーバーを消す方法です。
実現方法ですが【windowAPI】関数を呼び出しています。


開発環境:Unity 2018.3.8f1 (64-bit)
開発言語:C#

2.何もせずビルドしてみる

特に何も意識せずアプリケーションをビルドしてみます。
【File】→【Build Setting...】
を選択します。
f:id:tsu--kun:20190924134534p:plain


【Build Setting】ウィンドウが開くので
下図の設定で【Build】をクリックします。
f:id:tsu--kun:20190924134548p:plain


適当なフォルダを選択して【OK】をクリックすると
ビルドが始まります。


【Build】したexeを起動すると
下図のように【Simple Configuration】といウィンドウが表示されます。
f:id:tsu--kun:20190924134602p:plain


これは何かというとアプリケーションのサイズなどを
設定したりできます。
これは毎回アプリケーションを起動するたびに表示されます。
このままでは非常に邪魔なので
まずはこれを表示しない設定にしてみます。


3.【PlayerSetting】の設定をする

では早速設定していきます。
【Build Setting】ウィンドウにある【Player Setting...】をクリックします。
そうすると【Inspector】に【PlayerSettings】が表示されるので
ここにある【Resolution and Presentation】に項目を設定してきます。
まずは
【Standalone Player Options】
Display Resolution Dialog:Disabled
に設定します。

これで【Simple Configuration】が表示されなくなります。

更に

【Resolution】
Fullscreen Mode:Windowed
に設定します。
デフォルトの【Fullscreen Window】だと
全画面でアプリが表示されてしまいます。

変更した結果が下図のとおりとなります。
f:id:tsu--kun:20190924134636p:plain

4.スクリプト

空の【GameObject】を作成し下記のスクリプトを追加します。

アプリケーション起動時に処理したいので
Awake関数内に処理を記述しています。

動作としては
アプリケーションのサイズが
width:500
height:500
にリサイズされ、ツールバーが非表示になります。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public class changeSize : MonoBehaviour
{
    string windowName = "sample"; // アプリケーションウィンドウの名前
    bool hideTitleBar = true;

    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    private static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

    [DllImport("user32.dll", EntryPoint = "FindWindow")]
    public static extern IntPtr FindWindow(System.String className, System.String windowName);

    // Sets window attributes
    [DllImport("user32.dll")]
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    // Gets window attributes
    [DllImport("user32.dll")]
    public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    // assorted constants needed
    public static int GWL_STYLE = -16;
    public static int WS_CHILD = 0x40000000;            //child window
    public static int WS_BORDER = 0x00800000;           //window with border
    public static int WS_DLGFRAME = 0x00400000;         //window with double border but no title
    public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar

    public static int WINDOW_X = 0;
    public static int WINDOW_Y = 0;
    public static int WINDOW_WIDTH = 500;
    public static int WINDOW_HEIGHT = 500;

    void Awake()
    {
        var window = FindWindow(null, windowName);
        if (hideTitleBar)
        {
            int style = GetWindowLong(window, GWL_STYLE);
            SetWindowLong(window, GWL_STYLE, (style & ~WS_CAPTION));
        }
        // アプリケーションの座標、サイズの変更
        SetWindowPos(window, 0, WINDOW_X, WINDOW_Y, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH * WINDOW_HEIGHT == 0 ? 1 : 0);
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

5.実行する

簡単に出来るだろうと思っていたのですが
実行してみたら、アプリケーションのサイズが
全画面の状態から一切変わりませんでした。

スクリプトが効いてないのか???
と色々と調べていたのですがどうやら前回の起動時のステータスが
レジストリに保存されているようです。

多分なのですが2項でとりあえずビルドして
実行したのがいけなかったのかなと思います。
ですのでレジストリを丸ごと削除するといいようなので
これを削除しました。
(今回はsampleという名前なのでこれをフォルダ毎全部削除しました)

レジストリの場所は下記になります。
HKCU\Software\[company name]\[product name]
f:id:tsu--kun:20190924134657p:plain

6.再度実行する

レジストリを削除して再度実行してみました。
結果は下図のとおりです。

f:id:tsu--kun:20190924134712p:plain


何とか思った通りの動作を実現できました。