Skip to content

Commit fc9daf7

Browse files
Working on automatic positioning
#5
1 parent 515b6e6 commit fc9daf7

File tree

2 files changed

+147
-4
lines changed

2 files changed

+147
-4
lines changed

ShortDev.Uwp.FullTrust/ShortDev.Uwp.FullTrust/Activation/CoreWindowActivator.cs

Lines changed: 146 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
using ShortDev.Uwp.FullTrust.Interfaces;
2+
using ShortDev.Uwp.FullTrust.Types;
23
using System;
4+
using System.ComponentModel;
5+
using System.Diagnostics;
36
using System.Runtime.InteropServices;
7+
using Windows.Foundation;
48
using Windows.UI.Core;
59

610
namespace ShortDev.Uwp.FullTrust.Activation
@@ -18,7 +22,7 @@ public enum WindowType : int
1822
NOT_IMMERSIVE
1923
}
2024

21-
public const int CW_USEDEFAULT = (unchecked((int)0x80000000));
25+
2226

2327
[DllImport("windows.ui.dll", EntryPoint = "#1500")]
2428
static extern int PrivateCreateCoreWindow(
@@ -34,11 +38,150 @@ static extern int PrivateCreateCoreWindow(
3438
out ICoreWindowInterop windowRef
3539
);
3640

37-
public static CoreWindow CreateCoreWindow(WindowType windowType, string windowTitle, IntPtr hOwnerWindow, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int width = CW_USEDEFAULT, int height = CW_USEDEFAULT, uint dwAttributes = 0)
41+
public static CoreWindow CreateCoreWindow(WindowType windowType, string windowTitle)
42+
{
43+
var rect = GenerateDefaultWindowPosition();
44+
return CreateCoreWindow(windowType, windowTitle, rect, IntPtr.Zero);
45+
}
46+
47+
public static CoreWindow CreateCoreWindow(WindowType windowType, string windowTitle, Rect dimensions, IntPtr hOwnerWindow, uint dwAttributes = 0)
3848
{
3949
Guid iid = typeof(ICoreWindowInterop).GUID;
40-
Marshal.ThrowExceptionForHR(PrivateCreateCoreWindow(windowType, windowTitle, x, y, (uint)width, (uint)height, dwAttributes, ref hOwnerWindow, ref iid, out ICoreWindowInterop windowRef));
50+
Marshal.ThrowExceptionForHR(PrivateCreateCoreWindow(windowType, windowTitle, (int)dimensions.Left, (int)dimensions.Top, (uint)dimensions.Width, (uint)dimensions.Height, dwAttributes, ref hOwnerWindow, ref iid, out ICoreWindowInterop windowRef));
4151
return (windowRef as object as CoreWindow)!;
4252
}
53+
54+
/// <summary>
55+
/// <see href="https://devblogs.microsoft.com/oldnewthing/20131122-00/?p=2593"/>
56+
/// </summary>
57+
/// <returns></returns>
58+
public static Rect GenerateDefaultWindowPosition()
59+
{
60+
const int CW_USEDEFAULT = (unchecked((int)0x80000000));
61+
const string CLASS_NAME = "tmp";
62+
63+
Wndproc wndproc = (a, b, c, d) => (IntPtr)1;
64+
65+
IntPtr hInstance = Process.GetCurrentProcess().Handle;
66+
67+
WNDCLASSEX wc = new();
68+
wc.cbSize = Marshal.SizeOf(wc);
69+
70+
wc.lpfnWndProc = Marshal.GetFunctionPointerForDelegate(wndproc);
71+
wc.hInstance = hInstance;
72+
wc.lpszClassName = CLASS_NAME;
73+
74+
var atom = RegisterClassEx(ref wc);
75+
76+
IntPtr hwnd = CreateWindowEx(
77+
0, // Optional window styles.
78+
CLASS_NAME, // Window class
79+
CLASS_NAME, // Window text
80+
WindowStyles.WS_OVERLAPPEDWINDOW, // Window style
81+
82+
// Size and position
83+
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
84+
85+
IntPtr.Zero, // Parent window
86+
IntPtr.Zero, // Menu
87+
hInstance, // Instance handle
88+
IntPtr.Zero // Additional application data
89+
);
90+
if (hwnd == IntPtr.Zero)
91+
throw new Win32Exception();
92+
93+
GetWindowRect(hwnd, out var _bounds);
94+
95+
DestroyWindow(hwnd);
96+
97+
return new(_bounds.Left, _bounds.Top, _bounds.Right - _bounds.Left, _bounds.Bottom - _bounds.Top);
98+
}
99+
100+
public abstract class WindowStyles
101+
{
102+
public const uint WS_OVERLAPPED = 0x00000000;
103+
public const uint WS_POPUP = 0x80000000;
104+
public const uint WS_CHILD = 0x40000000;
105+
public const uint WS_MINIMIZE = 0x20000000;
106+
public const uint WS_VISIBLE = 0x10000000;
107+
public const uint WS_DISABLED = 0x08000000;
108+
public const uint WS_CLIPSIBLINGS = 0x04000000;
109+
public const uint WS_CLIPCHILDREN = 0x02000000;
110+
public const uint WS_MAXIMIZE = 0x01000000;
111+
public const uint WS_CAPTION = 0x00C00000; /* WS_BORDER | WS_DLGFRAME */
112+
public const uint WS_BORDER = 0x00800000;
113+
public const uint WS_DLGFRAME = 0x00400000;
114+
public const uint WS_VSCROLL = 0x00200000;
115+
public const uint WS_HSCROLL = 0x00100000;
116+
public const uint WS_SYSMENU = 0x00080000;
117+
public const uint WS_THICKFRAME = 0x00040000;
118+
public const uint WS_GROUP = 0x00020000;
119+
public const uint WS_TABSTOP = 0x00010000;
120+
121+
public const uint WS_MINIMIZEBOX = 0x00020000;
122+
public const uint WS_MAXIMIZEBOX = 0x00010000;
123+
124+
public const uint WS_TILED = WS_OVERLAPPED;
125+
public const uint WS_ICONIC = WS_MINIMIZE;
126+
public const uint WS_SIZEBOX = WS_THICKFRAME;
127+
public const uint WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW;
128+
129+
// Common Window Styles
130+
131+
public const uint WS_OVERLAPPEDWINDOW =
132+
(WS_OVERLAPPED |
133+
WS_CAPTION |
134+
WS_SYSMENU |
135+
WS_THICKFRAME |
136+
WS_MINIMIZEBOX |
137+
WS_MAXIMIZEBOX);
138+
}
139+
140+
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
141+
static extern IntPtr CreateWindowEx(
142+
uint dwExStyle,
143+
string lpClassName,
144+
string lpWindowName,
145+
uint dwStyle,
146+
int x,
147+
int y,
148+
int nWidth,
149+
int nHeight,
150+
IntPtr hWndParent,
151+
IntPtr hMenu,
152+
IntPtr hInstance,
153+
IntPtr lpParam
154+
);
155+
156+
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
157+
static extern bool DestroyWindow(IntPtr hwnd);
158+
159+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
160+
public struct WNDCLASSEX
161+
{
162+
[MarshalAs(UnmanagedType.U4)]
163+
public int cbSize;
164+
[MarshalAs(UnmanagedType.U4)]
165+
public int style;
166+
public IntPtr lpfnWndProc;
167+
public int cbClsExtra;
168+
public int cbWndExtra;
169+
public IntPtr hInstance;
170+
public IntPtr hIcon;
171+
public IntPtr hCursor;
172+
public IntPtr hbrBackground;
173+
public string lpszMenuName;
174+
public string lpszClassName;
175+
public IntPtr hIconSm;
176+
}
177+
178+
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
179+
[return: MarshalAs(UnmanagedType.U2)]
180+
static extern short RegisterClassEx([In] ref WNDCLASSEX lpwcx);
181+
182+
[DllImport("user32.dll")]
183+
static extern bool GetWindowRect(IntPtr hWnd, out Win32Rect rect);
184+
185+
delegate IntPtr Wndproc(IntPtr a, IntPtr b, IntPtr c, IntPtr d);
43186
}
44187
}

ShortDev.Uwp.FullTrust/ShortDev.Uwp.FullTrust/Xaml/XamlWindowActivator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ internal static (CoreApplicationView coreAppView, XamlWindow window) CreateNewIn
2828
if (XamlApplicationWrapper.Current == null)
2929
throw new InvalidOperationException($"No instance of \"{nameof(XamlApplicationWrapper)}\" was found!");
3030

31-
CoreWindow coreWindow = CoreWindowActivator.CreateCoreWindow(CoreWindowActivator.WindowType.NOT_IMMERSIVE, config.Title, IntPtr.Zero, 30, 30, 1024, 768, 0);
31+
CoreWindow coreWindow = CoreWindowActivator.CreateCoreWindow(CoreWindowActivator.WindowType.NOT_IMMERSIVE, config.Title);
3232

3333
// Create CoreApplicationView
3434
var coreApplicationPrivate = InteropHelper.RoGetActivationFactory<ICoreApplicationPrivate2>("Windows.ApplicationModel.Core.CoreApplication");

0 commit comments

Comments
 (0)