Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 94 additions & 10 deletions Assets/Scripts/ControlWPFWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,33 @@ public class ControlWPFWindow : MonoBehaviour

public EasyDeviceDiscoveryProtocolManager easyDeviceDiscoveryProtocolManager;

public ModManager modManager;

public ModManager modManager;

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void SetDpiAwareness()
{
// From https://note.com/taqssoft/n/n69521402e39e
#if UNITY_STANDALONE_WIN
try
{
// Windows 8.1 以降に対応
NativeMethods.SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_Per_Monitor_DPI_Aware);
}
catch
{
try
{
// 古いWindows向けフォールバック(Vista以降)
NativeMethods.SetProcessDPIAware();
}
catch
{
Debug.LogWarning("DPI設定の適用に失敗しました。");
}
}
#endif
}

private void Awake()
{
Application.targetFrameRate = 60;
Expand Down Expand Up @@ -118,6 +143,11 @@ private void Awake()
server.Start(pipeName);

externalMotionSender = ExternalMotionSenderObject.GetComponent<ExternalSender>();

#if !UNITY_EDITOR // エディタ上では動きません。
var hwnd = GetUnityWindowHandle();
SetWindowLong(hwnd, GWL_STYLE, defaultWindowStyle | WS_CLIPCHILDREN);
#endif
}

void Start()
Expand Down Expand Up @@ -237,7 +267,7 @@ private void Server_Received(object sender, DataReceivedEventArgs e)
if (IsPreRelease)
{
modManager.ImportMods();
}
}
}
else if (e.CommandType == typeof(PipeCommands.LoadVRM))
{
Expand Down Expand Up @@ -364,6 +394,9 @@ private void Server_Received(object sender, DataReceivedEventArgs e)
LoadSettings(d.Path);
//イベントを登録(何度呼び出しても1回のみ)
RegisterEventCallBack();

// ウィンドウ情報を反映
SendWindowInfo();
}
else if (e.CommandType == typeof(PipeCommands.SaveSettings))
{
Expand Down Expand Up @@ -512,7 +545,10 @@ await server.SendCommandAsync(new PipeCommands.SetEyeTracking_ViveProEyeEnable
{
//現在の設定を再適用する
ApplySettings();
}
}

// ウィンドウ情報を反映
SendWindowInfo();
}
else if (e.CommandType == typeof(PipeCommands.EnableExternalMotionSender))
{
Expand Down Expand Up @@ -862,7 +898,22 @@ await server.SendCommandAsync(new PipeCommands.ReturnModList
else if (e.CommandType == typeof(PipeCommands.Alive))
{
await server.SendCommandAsync(new PipeCommands.Alive { });
}
else if (e.CommandType == typeof(PipeCommands.GetUnityChildWindowEnable))
{
await server.SendCommandAsync(new PipeCommands.SetUnityChildWindowEnable
{
enable = Settings.Current.UnityChildWindowEnable
}, e.RequestId);
SendWindowInfo();
}
else if (e.CommandType == typeof(PipeCommands.SetUnityChildWindowEnable))
{
var d = (PipeCommands.SetUnityChildWindowEnable)e.Data;
Settings.Current.UnityChildWindowEnable = d.enable;
SendWindowInfo();
}

}, null);
}

Expand Down Expand Up @@ -1195,13 +1246,13 @@ void HideWindowBorder(bool enable)
}
if (enable)
{
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE); //ウインドウ枠の削除
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN); //ウインドウ枠の削除
SetUnityWindowFrameChanged();
WaitOneFrameAction(() => SetUnityWindowSize(clientrect.width, clientrect.height));
}
else
{
SetWindowLong(hwnd, GWL_STYLE, defaultWindowStyle);
SetWindowLong(hwnd, GWL_STYLE, defaultWindowStyle | WS_CLIPCHILDREN);
SetUnityWindowFrameChanged();
WaitOneFrameAction(() => SetUnityWindowSize(clientrect.width + windowBorderWidth.Value, clientrect.height + windowBorderHeight.Value));
}
Expand Down Expand Up @@ -2032,13 +2083,18 @@ void Update()
private Vector2 OldMousePos;
private bool isWindowDragging = false;

private DateTime lastWindowMoveTime = DateTime.MinValue;
private bool windowPositionSent = true;
private int lastWindowLeft = 0;
private int lastWindowTop = 0;

void LateUpdate()
{
{
var r = GetUnityWindowPosition();
//Windowの移動操作
//ドラッグ開始
if (Input.GetMouseButtonDown((int)MouseButtons.Left) && Input.GetKey(KeyCode.LeftAlt) == false && Input.GetKey(KeyCode.RightAlt) == false)
{
var r = GetUnityWindowPosition();
WindowX = r.left;
WindowY = r.top;
OldMousePos = GetWindowsMousePosition();
Expand All @@ -2061,7 +2117,35 @@ void LateUpdate()
if (Input.GetMouseButtonUp((int)MouseButtons.Left) && isWindowDragging)
{
isWindowDragging = false;
}
}
}

// 位置が変わったら時刻を記録し、送信済みフラグをリセット
if (r.left != lastWindowLeft || r.top != lastWindowTop)
{
lastWindowMoveTime = DateTime.Now;
windowPositionSent = false;
lastWindowLeft = r.left;
lastWindowTop = r.top;
}

// 指定ミリ秒間動きがなければ、まだ送信していなければ送信
if (!windowPositionSent && (DateTime.Now - lastWindowMoveTime).TotalMilliseconds >= 200)
{
SendWindowInfo();
windowPositionSent = true;
}
}

// 現在のウィンドウハンドル、子ウィンドウ有効可否を送信し、ウィンドウ情報の更新を促す
void SendWindowInfo() {
context.Post(async s =>
{
await server.SendCommandAsync(new PipeCommands.WindowInfo
{
Hwnd = GetUnityWindowHandle(),
Child = Settings.Current.UnityChildWindowEnable,
});
}, null);
}
}
}
8 changes: 6 additions & 2 deletions Assets/Scripts/Setting/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,10 @@ public class Settings
[OptionalField]
public float PelvisOffsetAdjustY;
[OptionalField]
public float PelvisOffsetAdjustZ;

public float PelvisOffsetAdjustZ;

[OptionalField]
public bool UnityChildWindowEnable;

//初期値
[OnDeserializing()]
Expand Down Expand Up @@ -862,6 +864,8 @@ internal void OnDeserializingMethod(StreamingContext context)
OverrideBodyHeight = 1.7f;
PelvisOffsetAdjustY = 0;
PelvisOffsetAdjustZ = 0;

UnityChildWindowEnable = false;
}

/// <summary>
Expand Down
17 changes: 15 additions & 2 deletions Assets/Scripts/Utils/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ public struct RECT

public int width => right - left;
public int height => bottom - top;
}

public enum PROCESS_DPI_AWARENESS
{
Process_DPI_Unaware = 0,
Process_System_DPI_Aware = 1,
Process_Per_Monitor_DPI_Aware = 2
}

[DllImport("user32.dll")]
Expand Down Expand Up @@ -77,7 +84,12 @@ public static bool IsWindowActive()
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll")]
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[DllImport("Shcore.dll")]
public static extern int SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness);
[DllImport("user32.dll")]
public static extern bool SetProcessDPIAware();

public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
public static readonly IntPtr HWND_TOP = new IntPtr(0);
Expand Down Expand Up @@ -109,7 +121,7 @@ public enum SetWindowPosFlags : uint
public static void SetUnityWindowSize(int width, int height) => SetWindowPos(GetUnityWindowHandle(), IntPtr.Zero, 0, 0, width, height, SetWindowPosFlags.IgnoreMove);
public static void SetUnityWindowFrameChanged() => SetWindowPos(GetUnityWindowHandle(), IntPtr.Zero, 0, 0, 0, 0, SetWindowPosFlags.IgnoreMoveAndResize | SetWindowPosFlags.IgnoreZOrder | SetWindowPosFlags.FrameChanged | SetWindowPosFlags.ShowWindow);
public static void SetUnityWindowTopMost(bool enable) => SetWindowPos(GetUnityWindowHandle(), enable ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SetWindowPosFlags.IgnoreMoveAndResize);
public static void SetUnityWindowTitle(string title) => SetWindowText(GetUnityWindowHandle(), title);
public static void SetUnityWindowTitle(string title) => SetWindowText(GetUnityWindowHandle(), title);

[DllImport("Dwmapi.dll")]
public static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref DwmMargin margins);
Expand All @@ -122,6 +134,7 @@ public static void SetDwmTransparent(bool enable)
public const int GWL_STYLE = -16;
public const uint WS_POPUP = 0x80000000;
public const uint WS_VISIBLE = 0x10000000;
public const uint WS_CLIPCHILDREN = 0x02000000;
public const int GWL_EXSTYLE = -20;
public const uint WS_EX_LAYERED = 0x00080000;
public const uint WS_EX_TRANSPARENT = 0x00000020;
Expand Down
74 changes: 70 additions & 4 deletions ControlWindowWPF/ControlWindowWPF/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
Expand All @@ -23,6 +24,39 @@ namespace VirtualMotionCaptureControlPanel
/// </summary>
public partial class MainWindow : Window
{
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;

public int width => right - left;
public int height => bottom - top;
}

public const int GWL_STYLE = -16;
public const uint WS_MINIMIZEBOX = 0x00020000;
public const uint WS_SYSMENU = 0x00080000;
public const uint WS_CAPTION = 0x00C00000;
public const uint WS_CHILD = 0x40000000;
public const uint WS_POPUP = 0x80000000;
public const uint WS_VISIBLE = 0x10000000;

[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll")]
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong); /*x uint o int unchecked*/
[DllImport("user32.dll")]
public static extern uint GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);


private ObservableCollection<string> DefaultFaces = new ObservableCollection<string> {
"通常(NEUTRAL)",
"喜(JOY)",
Expand All @@ -49,7 +83,8 @@ public partial class MainWindow : Window
private ObservableCollection<string> LipSyncDevices = new ObservableCollection<string>();

private int CurrentWindowNum = 0;
CalibrationResultWindow calibrationResultWindow;
CalibrationResultWindow calibrationResultWindow;
bool isChildWindow = false;

public MainWindow()
{
Expand All @@ -65,7 +100,8 @@ public MainWindow()
this.Close();
return;
}
InitializeComponent();
InitializeComponent();

Globals.Connect(App.CommandLineArgs[1]);
Globals.Client.ReceivedEvent += Client_Received;
DefaultFaceComboBox.ItemsSource = DefaultFacesBase;
Expand Down Expand Up @@ -159,7 +195,7 @@ private void CheckVMCCameraVersion()
}

private async void Window_Loaded(object sender, RoutedEventArgs e)
{
{
if (Globals.CurrentCommonSettingsWPF.FirewallChecked == false && App.CommandLineArgs[1] != "VMCTest")
{
var (successExecute, exitCode) = AdminExecute.RestartAsAdmin(new[] { "/firewall" });
Expand Down Expand Up @@ -555,7 +591,37 @@ private void Client_Received(object sender, DataReceivedEventArgs e)
else if (e.CommandType == typeof(PipeCommands.OpenVRStatus))
{
var d = (PipeCommands.OpenVRStatus)e.Data;
OpenVRAlertStatusTextBlock.Visibility = d.DashboardOpened? Visibility.Visible : Visibility.Collapsed;
OpenVRAlertStatusTextBlock.Visibility = d.DashboardOpened ? Visibility.Visible : Visibility.Collapsed;
}
else if (e.CommandType == typeof(PipeCommands.WindowInfo))
{
var d = (PipeCommands.WindowInfo)e.Data;

var wih = new System.Windows.Interop.WindowInteropHelper(this);
var hWnd = wih.Handle;
if (d.Child && !isChildWindow)
{
var n = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, WS_VISIBLE | WS_CHILD);

// Unityを親にする
SetParent(hWnd, d.Hwnd);
isChildWindow = true;

MoveWindow(hWnd, 0, 0, 460, 204, true); // DPIの影響を受ける
}
if (!d.Child && isChildWindow) {
var n = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, WS_VISIBLE | WS_POPUP | WS_CAPTION| WS_SYSMENU| WS_MINIMIZEBOX);

// デスクトップを親にする
SetParent(hWnd, IntPtr.Zero);
isChildWindow = false;

MoveWindow(hWnd, 0, 0, 460, 204, true); // DPIの影響を受ける
}
this.Width = 460;
this.Height = 204;
}
}));
}
Expand Down
2 changes: 2 additions & 0 deletions ControlWindowWPF/ControlWindowWPF/Resources/Chinese.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@
<system:String x:Key="SettingWindow_ReceiveBonesEnable">手骨接收</system:String>
<system:String x:Key="SettingWindow_VMCMod">VMC Mod(不保证可用/不受支持)</system:String>
<system:String x:Key="SettingWindow_VMCModSetting">已加载 MOD 列表</system:String>
<system:String x:Key="SettingWindow_Other">Other</system:String>
<system:String x:Key="SettingWindow_UnityChildWindow">Display Control Panel in Unity</system:String>

<!-- CalibrationSettingWindow -->
<system:String x:Key="CalibrationSettingWindow_BodyHeight">身高</system:String>
Expand Down
2 changes: 2 additions & 0 deletions ControlWindowWPF/ControlWindowWPF/Resources/English.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@
<system:String x:Key="SettingWindow_ReceiveBonesEnable">Receive hand bone</system:String>
<system:String x:Key="SettingWindow_VMCMod">VMC Mod (No warranty/no support)</system:String>
<system:String x:Key="SettingWindow_VMCModSetting">Loaded MOD List</system:String>
<system:String x:Key="SettingWindow_Other">Other</system:String>
<system:String x:Key="SettingWindow_UnityChildWindow">Display Control Panel in Unity</system:String>

<!-- CalibrationSettingWindow -->
<system:String x:Key="CalibrationSettingWindow_BodyHeight">Body Height</system:String>
Expand Down
4 changes: 3 additions & 1 deletion ControlWindowWPF/ControlWindowWPF/Resources/Japanese.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,10 @@
<system:String x:Key="SettingWindow_ReceiveBonesEnable">手ボーン取得</system:String>
<system:String x:Key="SettingWindow_VMCMod">VMC Mod (無保証/無サポート)</system:String>
<system:String x:Key="SettingWindow_VMCModSetting">ロード済みModリスト</system:String>
<system:String x:Key="SettingWindow_Other">その他</system:String>
<system:String x:Key="SettingWindow_UnityChildWindow">コントロール画面をUnity内に表示する</system:String>

<!-- CalibrationSettingWindow -->
<!-- CalibrationSettingWindow -->
<system:String x:Key="CalibrationSettingWindow_BodyHeight">身長設定</system:String>
<system:String x:Key="CalibrationSettingWindow_OverrideBodyHeight">身長を上書き</system:String>
<system:String x:Key="CalibrationSettingWindow_Height">身長 :</system:String>
Expand Down
Loading