/ src / modules / launcher / PowerLauncher / Helper / NativeMethods.cs
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  }