NativeMethods.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.ComponentModel; 7 using System.Runtime.InteropServices; 8 using System.Security; 9 using System.Text; 10 11 using static PowerLauncher.Helper.WindowsInteropHelper; 12 13 // http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/ 14 // modified to allow single instance restart 15 namespace PowerLauncher.Helper 16 { 17 [SuppressUnmanagedCodeSecurity] 18 internal static class NativeMethods 19 { 20 /// <summary> 21 /// Delegate declaration that matches WndProc signatures. 22 /// </summary> 23 public delegate IntPtr MessageHandler(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled); 24 25 [DllImport("shell32.dll", EntryPoint = "CommandLineToArgvW", CharSet = CharSet.Unicode)] 26 private static extern IntPtr Shell32CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string cmdLine, out int numArgs); 27 28 [DllImport("kernel32.dll", EntryPoint = "LocalFree", SetLastError = true)] 29 internal static extern IntPtr Kernel32LocalFree(IntPtr hMem); 30 31 [DllImport("user32.dll")] 32 internal static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); 33 34 [DllImport("user32")] 35 internal static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); 36 37 [DllImport("user32")] 38 internal static extern bool UnregisterHotKey(IntPtr hWnd, int id); 39 40 [DllImport("user32.dll")] 41 internal static extern IntPtr SetForegroundWindow(IntPtr hWnd); 42 43 [DllImport("user32.dll", SetLastError = true)] 44 internal static extern bool SetProcessDPIAware(); 45 46 [DllImport("user32.dll")] 47 internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 48 49 [DllImport("user32.dll", SetLastError = true)] 50 internal static extern int GetWindowLong(IntPtr hWnd, int nIndex); 51 52 [DllImport("user32.dll")] 53 internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 54 55 [DllImport("user32.dll")] 56 internal static extern IntPtr GetForegroundWindow(); 57 58 [DllImport("user32.dll")] 59 internal static extern IntPtr GetDesktopWindow(); 60 61 [DllImport("user32.dll")] 62 internal static extern IntPtr GetShellWindow(); 63 64 [DllImport("user32.dll", SetLastError = true)] 65 internal static extern int GetWindowRect(IntPtr hwnd, out RECT rc); 66 67 [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 68 internal static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); 69 70 [DllImport("user32.DLL", CharSet = CharSet.Unicode)] 71 internal static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 72 73 [DllImport("shell32.dll")] 74 public static extern int SHQueryUserNotificationState(out UserNotificationState state); 75 76 public static string[] CommandLineToArgvW(string cmdLine) 77 { 78 IntPtr argv = IntPtr.Zero; 79 try 80 { 81 argv = Shell32CommandLineToArgvW(cmdLine, out int numArgs); 82 if (argv == IntPtr.Zero) 83 { 84 throw new Win32Exception(); 85 } 86 87 var result = new string[numArgs]; 88 89 for (int i = 0; i < numArgs; i++) 90 { 91 IntPtr currArg = Marshal.ReadIntPtr(argv, i * Marshal.SizeOf(typeof(IntPtr))); 92 result[i] = Marshal.PtrToStringUni(currArg); 93 } 94 95 return result; 96 } 97 finally 98 { 99 _ = Kernel32LocalFree(argv); 100 101 // Otherwise LocalFree failed. 102 // Assert.AreEqual(IntPtr.Zero, p); 103 } 104 } 105 } 106 107 // https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-registerhotkey 108 internal enum HOTKEY_MODIFIERS : uint 109 { 110 ALT = 0x0001, 111 CONTROL = 0x0002, 112 SHIFT = 0x0004, 113 WIN = 0x0008, 114 NOREPEAT = 0x4000, 115 CHECK_FLAGS = 0x000F, // modifiers to compare between keys. 116 } 117 118 // https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-showwindow 119 internal enum SW : int 120 { 121 HIDE = 0x0000, 122 SHOWNORMAL = 0x0001, 123 SHOWMINIMIZED = 0x0002, 124 SHOWMAXIMIZED = 0x0003, 125 SHOWNOACTIVATE = 0x0004, 126 SHOW = 0x0005, 127 MINIMIZE = 0x0006, 128 SHOWMINNOACTIVE = 0x0007, 129 SHOWNA = 0x0008, 130 RESTORE = 0x0009, 131 SHOWDEFAULT = 0x000A, 132 FORCEMINIMIZE = 0x000B, 133 } 134 135 internal enum WM 136 { 137 NULL = 0x0000, 138 CREATE = 0x0001, 139 DESTROY = 0x0002, 140 MOVE = 0x0003, 141 SIZE = 0x0005, 142 ACTIVATE = 0x0006, 143 SETFOCUS = 0x0007, 144 KILLFOCUS = 0x0008, 145 ENABLE = 0x000A, 146 SETREDRAW = 0x000B, 147 SETTEXT = 0x000C, 148 GETTEXT = 0x000D, 149 GETTEXTLENGTH = 0x000E, 150 PAINT = 0x000F, 151 CLOSE = 0x0010, 152 QUERYENDSESSION = 0x0011, 153 QUIT = 0x0012, 154 QUERYOPEN = 0x0013, 155 ERASEBKGND = 0x0014, 156 SYSCOLORCHANGE = 0x0015, 157 SHOWWINDOW = 0x0018, 158 SETTINGCHANGE = 0x001A, 159 ACTIVATEAPP = 0x001C, 160 SETCURSOR = 0x0020, 161 MOUSEACTIVATE = 0x0021, 162 CHILDACTIVATE = 0x0022, 163 QUEUESYNC = 0x0023, 164 GETMINMAXINFO = 0x0024, 165 166 WINDOWPOSCHANGING = 0x0046, 167 WINDOWPOSCHANGED = 0x0047, 168 169 CONTEXTMENU = 0x007B, 170 STYLECHANGING = 0x007C, 171 STYLECHANGED = 0x007D, 172 DISPLAYCHANGE = 0x007E, 173 GETICON = 0x007F, 174 SETICON = 0x0080, 175 NCCREATE = 0x0081, 176 NCDESTROY = 0x0082, 177 NCCALCSIZE = 0x0083, 178 NCHITTEST = 0x0084, 179 NCPAINT = 0x0085, 180 NCACTIVATE = 0x0086, 181 GETDLGCODE = 0x0087, 182 SYNCPAINT = 0x0088, 183 NCMOUSEMOVE = 0x00A0, 184 NCLBUTTONDOWN = 0x00A1, 185 NCLBUTTONUP = 0x00A2, 186 NCLBUTTONDBLCLK = 0x00A3, 187 NCRBUTTONDOWN = 0x00A4, 188 NCRBUTTONUP = 0x00A5, 189 NCRBUTTONDBLCLK = 0x00A6, 190 NCMBUTTONDOWN = 0x00A7, 191 NCMBUTTONUP = 0x00A8, 192 NCMBUTTONDBLCLK = 0x00A9, 193 194 SYSKEYDOWN = 0x0104, 195 SYSKEYUP = 0x0105, 196 SYSCHAR = 0x0106, 197 SYSDEADCHAR = 0x0107, 198 COMMAND = 0x0111, 199 SYSCOMMAND = 0x0112, 200 201 MOUSEMOVE = 0x0200, 202 LBUTTONDOWN = 0x0201, 203 LBUTTONUP = 0x0202, 204 LBUTTONDBLCLK = 0x0203, 205 RBUTTONDOWN = 0x0204, 206 RBUTTONUP = 0x0205, 207 RBUTTONDBLCLK = 0x0206, 208 MBUTTONDOWN = 0x0207, 209 MBUTTONUP = 0x0208, 210 MBUTTONDBLCLK = 0x0209, 211 MOUSEWHEEL = 0x020A, 212 XBUTTONDOWN = 0x020B, 213 XBUTTONUP = 0x020C, 214 XBUTTONDBLCLK = 0x020D, 215 MOUSEHWHEEL = 0x020E, 216 217 CAPTURECHANGED = 0x0215, 218 219 ENTERSIZEMOVE = 0x0231, 220 EXITSIZEMOVE = 0x0232, 221 222 IME_SETCONTEXT = 0x0281, 223 IME_NOTIFY = 0x0282, 224 IME_CONTROL = 0x0283, 225 IME_COMPOSITIONFULL = 0x0284, 226 IME_SELECT = 0x0285, 227 IME_CHAR = 0x0286, 228 IME_REQUEST = 0x0288, 229 IME_KEYDOWN = 0x0290, 230 IME_KEYUP = 0x0291, 231 232 NCMOUSELEAVE = 0x02A2, 233 234 HOTKEY = 0x0312, 235 236 DWMCOMPOSITIONCHANGED = 0x031E, 237 DWMNCRENDERINGCHANGED = 0x031F, 238 DWMCOLORIZATIONCOLORCHANGED = 0x0320, 239 DWMWINDOWMAXIMIZEDCHANGE = 0x0321, 240 DWMSENDICONICTHUMBNAIL = 0x0323, 241 DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326, 242 USER = 0x0400, 243 244 // This is the hard-coded message value used by WinForms for Shell_NotifyIcon. 245 // It's relatively safe to reuse. 246 TRAYMOUSEMESSAGE = 0x800, // WM_USER + 1024 247 APP = 0x8000, 248 } 249 250 internal enum UserNotificationState : int 251 { 252 QUNS_NOT_PRESENT = 1, 253 QUNS_BUSY, 254 QUNS_RUNNING_D3D_FULL_SCREEN, 255 QUNS_PRESENTATION_MODE, 256 QUNS_ACCEPTS_NOTIFICATIONS, 257 QUNS_QUIET_TIME, 258 QUNS_APP, 259 } 260 }