InteropMethods.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. using System;
  2. using System.ComponentModel;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.IO;
  5. using System.Runtime.CompilerServices;
  6. using System.Runtime.ConstrainedExecution;
  7. using System.Runtime.InteropServices;
  8. using System.Runtime.Versioning;
  9. using System.Security;
  10. using System.Security.Permissions;
  11. using System.Text;
  12. using System.Threading;
  13. namespace HandyControl.Tools.Interop;
  14. internal class InteropMethods
  15. {
  16. #region common
  17. internal const int E_FAIL = unchecked((int) 0x80004005);
  18. internal static readonly IntPtr HRGN_NONE = new(-1);
  19. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto)]
  20. [ResourceExposure(ResourceScope.None)]
  21. internal static extern int RegisterWindowMessage(string msg);
  22. [DllImport(InteropValues.ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
  23. internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, out InteropValues.TBBUTTON lpBuffer,
  24. int dwSize, out int lpNumberOfBytesRead);
  25. [DllImport(InteropValues.ExternDll.Kernel32, SetLastError = true)]
  26. internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, out InteropValues.RECT lpBuffer,
  27. int dwSize, out int lpNumberOfBytesRead);
  28. [DllImport(InteropValues.ExternDll.Kernel32, SetLastError = true)]
  29. internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, out InteropValues.TRAYDATA lpBuffer,
  30. int dwSize, out int lpNumberOfBytesRead);
  31. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto)]
  32. internal static extern uint SendMessage(IntPtr hWnd, uint Msg, uint wParam, IntPtr lParam);
  33. [DllImport(InteropValues.ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto)]
  34. internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
  35. [DllImport(InteropValues.ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto)]
  36. internal static extern bool AttachThreadInput(in uint currentForegroundWindowThreadId,
  37. in uint thisWindowThreadId, bool isAttach);
  38. [DllImport(InteropValues.ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto)]
  39. internal static extern IntPtr GetForegroundWindow();
  40. [DllImport(InteropValues.ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
  41. internal static extern IntPtr OpenProcess(InteropValues.ProcessAccess dwDesiredAccess,
  42. [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);
  43. [DllImport(InteropValues.ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
  44. internal static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize,
  45. InteropValues.AllocationType flAllocationType, InteropValues.MemoryProtection flProtect);
  46. [DllImport(InteropValues.ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
  47. internal static extern int CloseHandle(IntPtr hObject);
  48. [DllImport(InteropValues.ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
  49. internal static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, InteropValues.FreeType dwFreeType);
  50. [DllImport(InteropValues.ExternDll.User32, SetLastError = true)]
  51. internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
  52. [DllImport(InteropValues.ExternDll.User32, SetLastError = true)]
  53. internal static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass,
  54. string lpszWindow);
  55. [DllImport(InteropValues.ExternDll.User32)]
  56. internal static extern bool GetWindowRect(IntPtr hwnd, out InteropValues.RECT lpRect);
  57. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto)]
  58. internal static extern bool GetCursorPos(out InteropValues.POINT pt);
  59. [DllImport(InteropValues.ExternDll.User32)]
  60. internal static extern IntPtr GetDesktopWindow();
  61. [DllImport(InteropValues.ExternDll.User32, SetLastError = true)]
  62. [return: MarshalAs(UnmanagedType.Bool)]
  63. internal static extern bool AddClipboardFormatListener(IntPtr hwnd);
  64. [DllImport(InteropValues.ExternDll.User32, SetLastError = true)]
  65. [return: MarshalAs(UnmanagedType.Bool)]
  66. internal static extern bool RemoveClipboardFormatListener(IntPtr hwnd);
  67. [DllImport(InteropValues.ExternDll.User32)]
  68. internal static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
  69. [DllImport(InteropValues.ExternDll.User32)]
  70. internal static extern bool EnableMenuItem(IntPtr hMenu, int UIDEnabledItem, int uEnable);
  71. [DllImport(InteropValues.ExternDll.User32)]
  72. internal static extern bool InsertMenu(IntPtr hMenu, int wPosition, int wFlags, int wIDNewItem, string lpNewItem);
  73. [DllImport(InteropValues.ExternDll.User32, ExactSpelling = true, EntryPoint = "DestroyMenu", CharSet = CharSet.Auto)]
  74. [ResourceExposure(ResourceScope.None)]
  75. internal static extern bool IntDestroyMenu(HandleRef hMenu);
  76. [SecurityCritical]
  77. [SuppressUnmanagedCodeSecurity]
  78. [DllImport(InteropValues.ExternDll.User32, SetLastError = true, ExactSpelling = true, EntryPoint = nameof(GetDC),
  79. CharSet = CharSet.Auto)]
  80. internal static extern IntPtr IntGetDC(HandleRef hWnd);
  81. [SecurityCritical]
  82. internal static IntPtr GetDC(HandleRef hWnd)
  83. {
  84. var hDc = IntGetDC(hWnd);
  85. if (hDc == IntPtr.Zero) throw new Win32Exception();
  86. return HandleCollector.Add(hDc, CommonHandles.HDC);
  87. }
  88. [SecurityCritical]
  89. [SuppressUnmanagedCodeSecurity]
  90. [DllImport(InteropValues.ExternDll.User32, ExactSpelling = true, EntryPoint = nameof(ReleaseDC), CharSet = CharSet.Auto)]
  91. internal static extern int IntReleaseDC(HandleRef hWnd, HandleRef hDC);
  92. [SecurityCritical]
  93. internal static int ReleaseDC(HandleRef hWnd, HandleRef hDC)
  94. {
  95. HandleCollector.Remove((IntPtr) hDC, CommonHandles.HDC);
  96. return IntReleaseDC(hWnd, hDC);
  97. }
  98. [SecurityCritical]
  99. [SuppressUnmanagedCodeSecurity]
  100. [DllImport(InteropValues.ExternDll.Gdi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
  101. internal static extern int GetDeviceCaps(HandleRef hDC, int nIndex);
  102. [SecurityCritical]
  103. [SuppressUnmanagedCodeSecurity]
  104. [DllImport(InteropValues.ExternDll.User32)]
  105. internal static extern int GetSystemMetrics(InteropValues.SM nIndex);
  106. [SecurityCritical]
  107. [SuppressUnmanagedCodeSecurity]
  108. [DllImport(InteropValues.ExternDll.User32, EntryPoint = nameof(DestroyIcon), CharSet = CharSet.Auto, SetLastError = true)]
  109. private static extern bool IntDestroyIcon(IntPtr hIcon);
  110. [SecurityCritical]
  111. internal static bool DestroyIcon(IntPtr hIcon)
  112. {
  113. var result = IntDestroyIcon(hIcon);
  114. return result;
  115. }
  116. [SecurityCritical]
  117. [SuppressUnmanagedCodeSecurity]
  118. [DllImport(InteropValues.ExternDll.Gdi32, EntryPoint = nameof(DeleteObject), CharSet = CharSet.Auto, SetLastError = true)]
  119. private static extern bool IntDeleteObject(IntPtr hObject);
  120. [SecurityCritical]
  121. internal static bool DeleteObject(IntPtr hObject)
  122. {
  123. var result = IntDeleteObject(hObject);
  124. return result;
  125. }
  126. [SecurityCritical]
  127. internal static BitmapHandle CreateDIBSection(HandleRef hdc, ref InteropValues.BITMAPINFO bitmapInfo, int iUsage,
  128. ref IntPtr ppvBits, SafeFileMappingHandle hSection, int dwOffset)
  129. {
  130. hSection ??= new SafeFileMappingHandle(IntPtr.Zero);
  131. var hBitmap = PrivateCreateDIBSection(hdc, ref bitmapInfo, iUsage, ref ppvBits, hSection, dwOffset);
  132. return hBitmap;
  133. }
  134. [DllImport(InteropValues.ExternDll.Kernel32, EntryPoint = "CloseHandle", CharSet = CharSet.Auto, SetLastError = true)]
  135. internal static extern bool IntCloseHandle(HandleRef handle);
  136. [SecurityCritical]
  137. [SuppressUnmanagedCodeSecurity]
  138. [DllImport(InteropValues.ExternDll.Gdi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto,
  139. EntryPoint = nameof(CreateDIBSection))]
  140. private static extern BitmapHandle PrivateCreateDIBSection(HandleRef hdc, ref InteropValues.BITMAPINFO bitmapInfo, int iUsage,
  141. ref IntPtr ppvBits, SafeFileMappingHandle hSection, int dwOffset);
  142. [SecurityCritical]
  143. [SuppressUnmanagedCodeSecurity]
  144. [DllImport(InteropValues.ExternDll.User32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto,
  145. EntryPoint = nameof(CreateIconIndirect))]
  146. private static extern IconHandle PrivateCreateIconIndirect([In] [MarshalAs(UnmanagedType.LPStruct)]
  147. InteropValues.ICONINFO iconInfo);
  148. [SecurityCritical]
  149. internal static IconHandle CreateIconIndirect([In] [MarshalAs(UnmanagedType.LPStruct)]
  150. InteropValues.ICONINFO iconInfo)
  151. {
  152. var hIcon = PrivateCreateIconIndirect(iconInfo);
  153. return hIcon;
  154. }
  155. [SecurityCritical]
  156. [SuppressUnmanagedCodeSecurity]
  157. [DllImport(InteropValues.ExternDll.Gdi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto,
  158. EntryPoint = nameof(CreateBitmap))]
  159. private static extern BitmapHandle PrivateCreateBitmap(int width, int height, int planes, int bitsPerPixel,
  160. byte[] lpvBits);
  161. [SecurityCritical]
  162. internal static BitmapHandle CreateBitmap(int width, int height, int planes, int bitsPerPixel, byte[] lpvBits)
  163. {
  164. var hBitmap = PrivateCreateBitmap(width, height, planes, bitsPerPixel, lpvBits);
  165. return hBitmap;
  166. }
  167. [SecurityCritical]
  168. [SuppressUnmanagedCodeSecurity]
  169. [DllImport(InteropValues.ExternDll.Kernel32, EntryPoint = "GetModuleFileName", CharSet = CharSet.Unicode,
  170. SetLastError = true)]
  171. private static extern int IntGetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
  172. [SecurityCritical]
  173. internal static string GetModuleFileName(HandleRef hModule)
  174. {
  175. var buffer = new StringBuilder(InteropValues.Win32Constant.MAX_PATH);
  176. while (true)
  177. {
  178. var size = IntGetModuleFileName(hModule, buffer, buffer.Capacity);
  179. if (size == 0) throw new Win32Exception();
  180. if (size == buffer.Capacity)
  181. {
  182. buffer.EnsureCapacity(buffer.Capacity * 2);
  183. continue;
  184. }
  185. return buffer.ToString();
  186. }
  187. }
  188. [SecurityCritical]
  189. [SuppressUnmanagedCodeSecurity]
  190. [DllImport(InteropValues.ExternDll.Shell32, CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)]
  191. internal static extern int ExtractIconEx(string szExeFileName, int nIconIndex, out IconHandle phiconLarge,
  192. out IconHandle phiconSmall, int nIcons);
  193. [DllImport(InteropValues.ExternDll.Shell32, CharSet = CharSet.Auto)]
  194. internal static extern int Shell_NotifyIcon(int message, InteropValues.NOTIFYICONDATA pnid);
  195. [SecurityCritical]
  196. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  197. [DllImport(InteropValues.ExternDll.User32, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateWindowExW")]
  198. internal static extern IntPtr CreateWindowEx(
  199. int dwExStyle,
  200. [MarshalAs(UnmanagedType.LPWStr)] string lpClassName,
  201. [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName,
  202. int dwStyle,
  203. int x,
  204. int y,
  205. int nWidth,
  206. int nHeight,
  207. IntPtr hWndParent,
  208. IntPtr hMenu,
  209. IntPtr hInstance,
  210. IntPtr lpParam);
  211. [SecurityCritical]
  212. [SuppressUnmanagedCodeSecurity]
  213. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]
  214. internal static extern short RegisterClass(InteropValues.WNDCLASS4ICON wc);
  215. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto)]
  216. internal static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
  217. [DllImport(InteropValues.ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)]
  218. internal static extern bool SetForegroundWindow(IntPtr hWnd);
  219. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
  220. internal static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
  221. [DllImport(InteropValues.ExternDll.Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
  222. internal static extern IntPtr GetModuleHandle(string lpModuleName);
  223. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
  224. internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
  225. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
  226. internal static extern IntPtr SetWindowsHookEx(int idHook, InteropValues.HookProc lpfn, IntPtr hMod, uint dwThreadId);
  227. [DllImport(InteropValues.ExternDll.User32, SetLastError = true)]
  228. internal static extern IntPtr GetWindowDC(IntPtr window);
  229. [DllImport(InteropValues.ExternDll.Gdi32, SetLastError = true)]
  230. internal static extern uint GetPixel(IntPtr dc, int x, int y);
  231. [DllImport(InteropValues.ExternDll.User32, SetLastError = true)]
  232. internal static extern int ReleaseDC(IntPtr window, IntPtr dc);
  233. [DllImport(InteropValues.ExternDll.Gdi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
  234. internal static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
  235. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto)]
  236. internal static extern IntPtr GetDC(IntPtr ptr);
  237. [DllImport(InteropValues.ExternDll.User32, SetLastError = true)]
  238. [return: MarshalAs(UnmanagedType.Bool)]
  239. private static extern bool GetWindowPlacement(IntPtr hwnd, InteropValues.WINDOWPLACEMENT lpwndpl);
  240. internal static InteropValues.WINDOWPLACEMENT GetWindowPlacement(IntPtr hwnd)
  241. {
  242. InteropValues.WINDOWPLACEMENT wINDOWPLACEMENT = InteropValues.WINDOWPLACEMENT.Default;
  243. if (GetWindowPlacement(hwnd, wINDOWPLACEMENT))
  244. {
  245. return wINDOWPLACEMENT;
  246. }
  247. throw new Win32Exception(Marshal.GetLastWin32Error());
  248. }
  249. internal static int GetXLParam(int lParam) => LoWord(lParam);
  250. internal static int GetYLParam(int lParam) => HiWord(lParam);
  251. internal static int HiWord(int value) => (short) (value >> 16);
  252. internal static int LoWord(int value) => (short) (value & 65535);
  253. [DllImport(InteropValues.ExternDll.User32)]
  254. internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
  255. [DllImport(InteropValues.ExternDll.User32)]
  256. [return: MarshalAs(UnmanagedType.Bool)]
  257. internal static extern bool EnumThreadWindows(uint dwThreadId, InteropValues.EnumWindowsProc lpfn, IntPtr lParam);
  258. [DllImport(InteropValues.ExternDll.Gdi32)]
  259. [return: MarshalAs(UnmanagedType.Bool)]
  260. internal static extern bool DeleteDC(IntPtr hdc);
  261. [DllImport(InteropValues.ExternDll.Gdi32, SetLastError = true)]
  262. internal static extern IntPtr CreateCompatibleDC(IntPtr hdc);
  263. [DllImport(InteropValues.ExternDll.Gdi32, ExactSpelling = true, SetLastError = true)]
  264. internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
  265. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Unicode, SetLastError = true)]
  266. internal static extern IntPtr SendMessage(IntPtr hWnd, int nMsg, IntPtr wParam, IntPtr lParam);
  267. [DllImport(InteropValues.ExternDll.User32)]
  268. internal static extern IntPtr MonitorFromPoint(InteropValues.POINT pt, int flags);
  269. [DllImport(InteropValues.ExternDll.User32)]
  270. internal static extern IntPtr GetWindow(IntPtr hwnd, int nCmd);
  271. [DllImport(InteropValues.ExternDll.User32)]
  272. internal static extern IntPtr GetActiveWindow();
  273. [DllImport(InteropValues.ExternDll.User32)]
  274. [return: MarshalAs(UnmanagedType.Bool)]
  275. internal static extern bool IsWindowVisible(IntPtr hwnd);
  276. [DllImport(InteropValues.ExternDll.User32)]
  277. [return: MarshalAs(UnmanagedType.Bool)]
  278. internal static extern bool IsIconic(IntPtr hwnd);
  279. [DllImport(InteropValues.ExternDll.User32)]
  280. [return: MarshalAs(UnmanagedType.Bool)]
  281. internal static extern bool IsZoomed(IntPtr hwnd);
  282. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto, ExactSpelling = true)]
  283. [return: MarshalAs(UnmanagedType.Bool)]
  284. internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, int flags);
  285. internal static System.Windows.Point GetCursorPos()
  286. {
  287. var result = default(System.Windows.Point);
  288. if (GetCursorPos(out var point))
  289. {
  290. result.X = point.X;
  291. result.Y = point.Y;
  292. }
  293. return result;
  294. }
  295. [DllImport(InteropValues.ExternDll.User32)]
  296. private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
  297. internal static int GetWindowLong(IntPtr hWnd, InteropValues.GWL nIndex) => GetWindowLong(hWnd, (int) nIndex);
  298. internal static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong) => IntPtr.Size == 4
  299. ? SetWindowLongPtr32(hWnd, nIndex, dwNewLong)
  300. : SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
  301. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto, EntryPoint = "SetWindowLong")]
  302. internal static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
  303. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Auto, EntryPoint = "SetWindowLongPtr")]
  304. internal static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
  305. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Unicode)]
  306. private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
  307. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Unicode)]
  308. private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
  309. internal static IntPtr SetWindowLongPtr(IntPtr hWnd, InteropValues.GWLP nIndex, IntPtr dwNewLong)
  310. {
  311. if (IntPtr.Size == 8)
  312. {
  313. return SetWindowLongPtr(hWnd, (int) nIndex, dwNewLong);
  314. }
  315. return new IntPtr(SetWindowLong(hWnd, (int) nIndex, dwNewLong.ToInt32()));
  316. }
  317. internal static int SetWindowLong(IntPtr hWnd, InteropValues.GWL nIndex, int dwNewLong) => SetWindowLong(hWnd, (int) nIndex, dwNewLong);
  318. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Unicode)]
  319. internal static extern ushort RegisterClass(ref InteropValues.WNDCLASS lpWndClass);
  320. [DllImport(InteropValues.ExternDll.Kernel32)]
  321. internal static extern uint GetCurrentThreadId();
  322. [DllImport(InteropValues.ExternDll.User32, CharSet = CharSet.Unicode, SetLastError = true)]
  323. internal static extern IntPtr CreateWindowEx(int dwExStyle, IntPtr classAtom, string lpWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
  324. [DllImport(InteropValues.ExternDll.User32)]
  325. [return: MarshalAs(UnmanagedType.Bool)]
  326. internal static extern bool DestroyWindow(IntPtr hwnd);
  327. [DllImport(InteropValues.ExternDll.User32)]
  328. [return: MarshalAs(UnmanagedType.Bool)]
  329. internal static extern bool UnregisterClass(IntPtr classAtom, IntPtr hInstance);
  330. [DllImport(InteropValues.ExternDll.User32)]
  331. [return: MarshalAs(UnmanagedType.Bool)]
  332. internal static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDest, ref InteropValues.POINT pptDest, ref InteropValues.SIZE psize, IntPtr hdcSrc, ref InteropValues.POINT pptSrc, uint crKey, [In] ref InteropValues.BLENDFUNCTION pblend, uint dwFlags);
  333. [DllImport(InteropValues.ExternDll.User32)]
  334. internal static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, InteropValues.RedrawWindowFlags flags);
  335. [DllImport(InteropValues.ExternDll.User32)]
  336. [return: MarshalAs(UnmanagedType.Bool)]
  337. internal static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, InteropValues.EnumMonitorsDelegate lpfnEnum, IntPtr dwData);
  338. [DllImport(InteropValues.ExternDll.User32)]
  339. [return: MarshalAs(UnmanagedType.Bool)]
  340. internal static extern bool IntersectRect(out InteropValues.RECT lprcDst, [In] ref InteropValues.RECT lprcSrc1, [In] ref InteropValues.RECT lprcSrc2);
  341. [DllImport(InteropValues.ExternDll.User32)]
  342. [return: MarshalAs(UnmanagedType.Bool)]
  343. internal static extern bool GetMonitorInfo(IntPtr hMonitor, ref InteropValues.MONITORINFO monitorInfo);
  344. [DllImport(InteropValues.ExternDll.User32, ExactSpelling = true)]
  345. [ResourceExposure(ResourceScope.None)]
  346. public static extern IntPtr MonitorFromRect(ref InteropValues.RECT rect, int flags);
  347. [DllImport(InteropValues.ExternDll.Gdi32, SetLastError = true)]
  348. internal static extern IntPtr CreateDIBSection(IntPtr hdc, ref InteropValues.BITMAPINFO pbmi, uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
  349. [DllImport(InteropValues.ExternDll.MsImg)]
  350. [return: MarshalAs(UnmanagedType.Bool)]
  351. internal static extern bool AlphaBlend(IntPtr hdcDest, int xoriginDest, int yoriginDest, int wDest, int hDest, IntPtr hdcSrc, int xoriginSrc, int yoriginSrc, int wSrc, int hSrc, InteropValues.BLENDFUNCTION pfn);
  352. internal static int GET_SC_WPARAM(IntPtr wParam) => (int) wParam & 65520;
  353. [DllImport(InteropValues.ExternDll.User32)]
  354. internal static extern IntPtr ChildWindowFromPointEx(IntPtr hwndParent, InteropValues.POINT pt, int uFlags);
  355. [DllImport(InteropValues.ExternDll.Gdi32)]
  356. internal static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int width, int height);
  357. [DllImport(InteropValues.ExternDll.Gdi32)]
  358. internal static extern bool BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
  359. [DllImport(InteropValues.ExternDll.User32)]
  360. [ResourceExposure(ResourceScope.None)]
  361. internal static extern bool EnableWindow(IntPtr hWnd, bool enable);
  362. [DllImport(InteropValues.ExternDll.User32)]
  363. public static extern bool ShowWindow(IntPtr hwnd, InteropValues.SW nCmdShow);
  364. [ReflectionPermission(SecurityAction.Assert, Unrestricted = true), SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)]
  365. internal static object PtrToStructure(IntPtr lparam, Type cls) => Marshal.PtrToStructure(lparam, cls);
  366. [ReflectionPermission(SecurityAction.Assert, Unrestricted = true),
  367. SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)]
  368. internal static void PtrToStructure(IntPtr lparam, object data) => Marshal.PtrToStructure(lparam, data);
  369. [DllImport(InteropValues.ExternDll.Shell32, CallingConvention = CallingConvention.StdCall)]
  370. internal static extern uint SHAppBarMessage(int dwMessage, ref InteropValues.APPBARDATA pData);
  371. [SecurityCritical]
  372. [DllImport(InteropValues.ExternDll.DwmApi, EntryPoint = "DwmGetColorizationColor", PreserveSig = true)]
  373. internal static extern int DwmGetColorizationColor(out uint pcrColorization, out bool pfOpaqueBlend);
  374. [DllImport(InteropValues.ExternDll.DwmApi, ExactSpelling = true, SetLastError = true)]
  375. internal static extern int DwmSetWindowAttribute(IntPtr hwnd, InteropValues.DwmWindowAttribute dwAttribute,
  376. in int pvAttribute, uint cbAttribute);
  377. [DllImport(InteropValues.ExternDll.User32, EntryPoint = "GetWindowLong")]
  378. private static extern IntPtr GetWindowLongPtr32(IntPtr hWnd, int nIndex);
  379. [DllImport(InteropValues.ExternDll.User32, EntryPoint = "GetWindowLongPtr")]
  380. private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
  381. internal static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex) =>
  382. IntPtr.Size == 8 ? GetWindowLongPtr64(hWnd, nIndex) : GetWindowLongPtr32(hWnd, nIndex);
  383. [DllImport(InteropValues.ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)]
  384. [ResourceExposure(ResourceScope.None)]
  385. internal static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref InteropValues.WINDOWPLACEMENT placement);
  386. #endregion
  387. internal class Gdip
  388. {
  389. private const string ThreadDataSlotName = "system.drawing.threaddata";
  390. private static IntPtr InitToken;
  391. private static bool Initialized => InitToken != IntPtr.Zero;
  392. internal const int
  393. Ok = 0,
  394. GenericError = 1,
  395. InvalidParameter = 2,
  396. OutOfMemory = 3,
  397. ObjectBusy = 4,
  398. InsufficientBuffer = 5,
  399. NotImplemented = 6,
  400. Win32Error = 7,
  401. WrongState = 8,
  402. Aborted = 9,
  403. FileNotFound = 10,
  404. ValueOverflow = 11,
  405. AccessDenied = 12,
  406. UnknownImageFormat = 13,
  407. FontFamilyNotFound = 14,
  408. FontStyleNotFound = 15,
  409. NotTrueTypeFont = 16,
  410. UnsupportedGdiplusVersion = 17,
  411. GdiplusNotInitialized = 18,
  412. PropertyNotFound = 19,
  413. PropertyNotSupported = 20,
  414. E_UNEXPECTED = unchecked((int) 0x8000FFFF);
  415. static Gdip()
  416. {
  417. Initialize();
  418. }
  419. [StructLayout(LayoutKind.Sequential)]
  420. private struct StartupInput
  421. {
  422. private int GdiplusVersion;
  423. private readonly IntPtr DebugEventCallback;
  424. private bool SuppressBackgroundThread;
  425. private bool SuppressExternalCodecs;
  426. public static StartupInput GetDefault()
  427. {
  428. var result = new StartupInput
  429. {
  430. GdiplusVersion = 1,
  431. SuppressBackgroundThread = false,
  432. SuppressExternalCodecs = false
  433. };
  434. return result;
  435. }
  436. }
  437. [StructLayout(LayoutKind.Sequential)]
  438. private readonly struct StartupOutput
  439. {
  440. private readonly IntPtr hook;
  441. private readonly IntPtr unhook;
  442. }
  443. [ResourceExposure(ResourceScope.None)]
  444. [ResourceConsumption(ResourceScope.AppDomain, ResourceScope.AppDomain)]
  445. [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals")]
  446. private static void Initialize()
  447. {
  448. var input = StartupInput.GetDefault();
  449. var status = GdiplusStartup(out InitToken, ref input, out _);
  450. if (status != Ok)
  451. {
  452. throw StatusException(status);
  453. }
  454. var currentDomain = AppDomain.CurrentDomain;
  455. currentDomain.ProcessExit += OnProcessExit;
  456. if (!currentDomain.IsDefaultAppDomain())
  457. {
  458. currentDomain.DomainUnload += OnProcessExit;
  459. }
  460. }
  461. [PrePrepareMethod]
  462. [ResourceExposure(ResourceScope.AppDomain)]
  463. [ResourceConsumption(ResourceScope.AppDomain)]
  464. private static void OnProcessExit(object sender, EventArgs e) => Shutdown();
  465. [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")]
  466. [ResourceExposure(ResourceScope.AppDomain)]
  467. [ResourceConsumption(ResourceScope.AppDomain)]
  468. private static void Shutdown()
  469. {
  470. if (Initialized)
  471. {
  472. ClearThreadData();
  473. // unhook our shutdown handlers as we do not need to shut down more than once
  474. var currentDomain = AppDomain.CurrentDomain;
  475. currentDomain.ProcessExit -= OnProcessExit;
  476. if (!currentDomain.IsDefaultAppDomain())
  477. {
  478. currentDomain.DomainUnload -= OnProcessExit;
  479. }
  480. }
  481. }
  482. [MethodImpl(MethodImplOptions.NoInlining)]
  483. private static void ClearThreadData()
  484. {
  485. var slot = Thread.GetNamedDataSlot(ThreadDataSlotName);
  486. Thread.SetData(slot, null);
  487. }
  488. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  489. [ResourceExposure(ResourceScope.None)]
  490. internal static extern int GdipImageGetFrameDimensionsCount(HandleRef image, out int count);
  491. internal static Exception StatusException(int status)
  492. {
  493. return status switch
  494. {
  495. GenericError => new ExternalException("GdiplusGenericError"),
  496. InvalidParameter => new ArgumentException("GdiplusInvalidParameter"),
  497. OutOfMemory => new OutOfMemoryException("GdiplusOutOfMemory"),
  498. ObjectBusy => new InvalidOperationException("GdiplusObjectBusy"),
  499. InsufficientBuffer => new OutOfMemoryException("GdiplusInsufficientBuffer"),
  500. NotImplemented => new NotImplementedException("GdiplusNotImplemented"),
  501. Win32Error => new ExternalException("GdiplusGenericError"),
  502. WrongState => new InvalidOperationException("GdiplusWrongState"),
  503. Aborted => new ExternalException("GdiplusAborted"),
  504. FileNotFound => new FileNotFoundException("GdiplusFileNotFound"),
  505. ValueOverflow => new OverflowException("GdiplusOverflow"),
  506. AccessDenied => new ExternalException("GdiplusAccessDenied"),
  507. UnknownImageFormat => new ArgumentException("GdiplusUnknownImageFormat"),
  508. PropertyNotFound => new ArgumentException("GdiplusPropertyNotFoundError"),
  509. PropertyNotSupported => new ArgumentException("GdiplusPropertyNotSupportedError"),
  510. FontFamilyNotFound => new ArgumentException("GdiplusFontFamilyNotFound"),
  511. FontStyleNotFound => new ArgumentException("GdiplusFontStyleNotFound"),
  512. NotTrueTypeFont => new ArgumentException("GdiplusNotTrueTypeFont_NoName"),
  513. UnsupportedGdiplusVersion => new ExternalException("GdiplusUnsupportedGdiplusVersion"),
  514. GdiplusNotInitialized => new ExternalException("GdiplusNotInitialized"),
  515. _ => new ExternalException("GdiplusUnknown")
  516. };
  517. }
  518. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  519. [ResourceExposure(ResourceScope.None)]
  520. internal static extern int GdipImageGetFrameDimensionsList(HandleRef image, IntPtr buffer, int count);
  521. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  522. [ResourceExposure(ResourceScope.None)]
  523. internal static extern int GdipImageGetFrameCount(HandleRef image, ref Guid dimensionId, int[] count);
  524. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  525. [ResourceExposure(ResourceScope.None)]
  526. internal static extern int GdipGetPropertyItemSize(HandleRef image, int propid, out int size);
  527. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  528. [ResourceExposure(ResourceScope.None)]
  529. internal static extern int GdipGetPropertyItem(HandleRef image, int propid, int size, IntPtr buffer);
  530. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  531. [ResourceExposure(ResourceScope.Machine)]
  532. internal static extern int GdipCreateHBITMAPFromBitmap(HandleRef nativeBitmap, out IntPtr hbitmap, int argbBackground);
  533. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  534. [ResourceExposure(ResourceScope.None)]
  535. internal static extern int GdipImageSelectActiveFrame(HandleRef image, ref Guid dimensionId, int frameIndex);
  536. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  537. [ResourceExposure(ResourceScope.Machine)]
  538. internal static extern int GdipCreateBitmapFromFile(string filename, out IntPtr bitmap);
  539. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  540. [ResourceExposure(ResourceScope.None)]
  541. internal static extern int GdipImageForceValidation(HandleRef image);
  542. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, EntryPoint = "GdipDisposeImage", CharSet = CharSet.Unicode)]
  543. [ResourceExposure(ResourceScope.None)]
  544. private static extern int IntGdipDisposeImage(HandleRef image);
  545. internal static int GdipDisposeImage(HandleRef image)
  546. {
  547. if (!Initialized) return Ok;
  548. var result = IntGdipDisposeImage(image);
  549. return result;
  550. }
  551. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  552. [ResourceExposure(ResourceScope.Process)]
  553. private static extern int GdiplusStartup(out IntPtr token, ref StartupInput input, out StartupOutput output);
  554. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  555. [ResourceExposure(ResourceScope.None)]
  556. internal static extern int GdipGetImageRawFormat(HandleRef image, ref Guid format);
  557. [DllImport(InteropValues.ExternDll.User32)]
  558. internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref InteropValues.WINCOMPATTRDATA data);
  559. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  560. [ResourceExposure(ResourceScope.Machine)]
  561. internal static extern int GdipCreateBitmapFromStream(InteropValues.IStream stream, out IntPtr bitmap);
  562. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  563. [ResourceExposure(ResourceScope.Machine)]
  564. internal static extern int GdipCreateBitmapFromHBITMAP(HandleRef hbitmap, HandleRef hpalette, out IntPtr bitmap);
  565. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  566. [ResourceExposure(ResourceScope.None)]
  567. internal static extern int GdipGetImageEncodersSize(out int numEncoders, out int size);
  568. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  569. [ResourceExposure(ResourceScope.None)]
  570. internal static extern int GdipGetImageDecodersSize(out int numDecoders, out int size);
  571. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  572. [ResourceExposure(ResourceScope.None)]
  573. internal static extern int GdipGetImageDecoders(int numDecoders, int size, IntPtr decoders);
  574. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  575. [ResourceExposure(ResourceScope.None)]
  576. internal static extern int GdipGetImageEncoders(int numEncoders, int size, IntPtr encoders);
  577. [DllImport(InteropValues.ExternDll.GdiPlus, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
  578. [ResourceExposure(ResourceScope.None)]
  579. internal static extern int GdipSaveImageToStream(HandleRef image, InteropValues.IStream stream, ref Guid classId, HandleRef encoderParams);
  580. [DllImport(InteropValues.ExternDll.NTdll)]
  581. internal static extern int RtlGetVersion(out InteropValues.RTL_OSVERSIONINFOEX lpVersionInformation);
  582. }
  583. }