1using System; 2using System.Runtime.InteropServices; 3 4namespace WindowCapture.Native 5{ 6 public static class WinApi 7 { 8 // Hook constants 9 public const int WH_KEYBOARD_LL = 13; 10 public const int WH_MOUSE_LL = 14; 11 public const int WM_MBUTTONDOWN = 0x0207; 12 public const int WM_MBUTTONUP = 0x0208; 13 public const int WM_MOUSEMOVE = 0x0200; 14 15 [DllImport("user32.dll")] 16 public static extern short GetAsyncKeyState(int vKey); 17 18 public delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam); 19 20 [StructLayout(LayoutKind.Sequential)] 21 public struct MSLLHOOKSTRUCT 22 { 23 public int x, y; 24 public uint mouseData; 25 public uint flags; 26 public uint time; 27 public IntPtr dwExtraInfo; 28 } 29 public const int WM_KEYDOWN = 0x0100; 30 public const int WM_KEYUP = 0x0101; 31 public const int WM_SYSKEYDOWN = 0x0104; 32 public const int WM_SYSKEYUP = 0x0105; 33 public const int VK_LMENU = 0xA4; // Left Alt 34 public const int VK_RMENU = 0xA5; // Right Alt 35 36 // Window style constants 37 public const int GWL_EXSTYLE = -20; 38 public const int GWL_STYLE = -16; 39 public const int WS_EX_TOPMOST = 0x8; 40 public const int WS_EX_TOOLWINDOW = 0x80; 41 public const int WS_CAPTION = 0xC00000; 42 public const int WS_VISIBLE = 0x10000000; 43 public const int WS_POPUP = unchecked((int)0x80000000); 44 public const int WS_CHILD = 0x40000000; 45 46 // Ancestor constants 47 public const uint GA_PARENT = 1; 48 public const uint GA_ROOT = 2; 49 public const uint GA_ROOTOWNER = 3; 50 51 // GetWindow constants 52 public const uint GW_HWNDNEXT = 2; 53 54 [DllImport("user32.dll")] 55 public static extern short GetKeyState(int nVirtKey); 56 57 // Delegates 58 public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); 59 public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 60 61 // Structures 62 [StructLayout(LayoutKind.Sequential)] 63 public struct KBDLLHOOKSTRUCT 64 { 65 public uint vkCode, scanCode, flags, time; 66 public IntPtr dwExtraInfo; 67 } 68 69 [StructLayout(LayoutKind.Sequential)] 70 public struct POINT 71 { 72 public int X, Y; 73 public POINT(int x, int y) { X = x; Y = y; } 74 } 75 76 [StructLayout(LayoutKind.Sequential)] 77 public struct RECT 78 { 79 public int Left, Top, Right, Bottom; 80 public int Width { get { return Right - Left; } } 81 public int Height { get { return Bottom - Top; } } 82 } 83 84 // WM_SETREDRAW for flicker-free updates 85 public const int WM_SETREDRAW = 0x000B; 86 public const int WM_GETTEXT = 0x000D; 87 public const int WM_GETTEXTLENGTH = 0x000E; 88 public const int EM_GETSEL = 0x00B0; 89 90 [DllImport("user32.dll")] 91 public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 92 [DllImport("user32.dll")] 93 public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); 94 [DllImport("user32.dll", CharSet = CharSet.Auto)] 95 public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, System.Text.StringBuilder lParam); 96 [DllImport("user32.dll")] 97 public static extern bool ReleaseCapture(); 98 99 // DLL Imports - Keyboard hooks 100 [DllImport("user32.dll")] 101 public static extern IntPtr SetWindowsHookEx(int id, HookProc proc, IntPtr hMod, uint threadId); 102 [DllImport("user32.dll")] 103 public static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc proc, IntPtr hMod, uint threadId); 104 [DllImport("user32.dll", SetLastError = true)] 105 public static extern IntPtr SetWindowsHookEx(int id, LowLevelMouseProc proc, IntPtr hMod, uint threadId); 106 [DllImport("user32.dll")] 107 public static extern bool UnhookWindowsHookEx(IntPtr hook); 108 [DllImport("user32.dll")] 109 public static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wParam, IntPtr lParam); 110 [DllImport("kernel32.dll")] 111 public static extern IntPtr GetModuleHandle(string name); 112 113 // DLL Imports - Window detection 114 [DllImport("user32.dll")] 115 public static extern IntPtr WindowFromPoint(POINT pt); 116 [DllImport("user32.dll")] 117 public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect); 118 [DllImport("user32.dll")] 119 public static extern IntPtr GetAncestor(IntPtr hWnd, uint gaFlags); 120 [DllImport("user32.dll")] 121 public static extern IntPtr GetParent(IntPtr hWnd); 122 [DllImport("user32.dll")] 123 public static extern bool IsWindowVisible(IntPtr hWnd); 124 [DllImport("user32.dll")] 125 public static extern int GetWindowLong(IntPtr hWnd, int nIndex); 126 [DllImport("user32.dll")] 127 public static extern int GetWindowTextLength(IntPtr hWnd); 128 [DllImport("user32.dll", CharSet = CharSet.Auto)] 129 public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount); 130 [DllImport("user32.dll", CharSet = CharSet.Auto)] 131 public static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder lpClassName, int nMaxCount); 132 [DllImport("user32.dll")] 133 public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); 134 135 // DWM for accurate window bounds 136 [DllImport("dwmapi.dll")] 137 public static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out RECT pvAttribute, int cbAttribute); 138 private const int DWMWA_EXTENDED_FRAME_BOUNDS = 9; 139 140 // GDI for fast screen capture 141 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 142 public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 143 [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] 144 public static extern IntPtr GetDC(IntPtr hWnd); 145 [DllImport("user32.dll", ExactSpelling = true)] 146 public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); 147 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 148 public static extern bool DeleteDC(IntPtr hdc); 149 [DllImport("gdi32.dll", ExactSpelling = true)] 150 public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); 151 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 152 public static extern bool DeleteObject(IntPtr hObject); 153 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 154 public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight); 155 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 156 public static extern bool BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop); 157 public const int SRCCOPY = 0x00CC0020; 158 159 // Cursor capture 160 [StructLayout(LayoutKind.Sequential)] 161 public struct CURSORINFO 162 { 163 public int cbSize; 164 public int flags; 165 public IntPtr hCursor; 166 public POINT ptScreenPos; 167 } 168 [DllImport("user32.dll")] 169 public static extern bool GetCursorInfo(ref CURSORINFO pci); 170 [DllImport("user32.dll")] 171 public static extern bool DrawIconEx(IntPtr hdc, int xLeft, int yTop, IntPtr hIcon, int cxWidth, int cyWidth, uint istepIfAniCur, IntPtr hbrFlickerFreeDraw, uint diFlags); 172 public const uint DI_NORMAL = 0x0003; 173 public const int CURSOR_SHOWING = 0x0001; 174 175 // Window display affinity (Win10 2004+: exclude from screen capture) 176 [DllImport("user32.dll")] 177 public static extern bool SetWindowDisplayAffinity(IntPtr hWnd, uint dwAffinity); 178 public const uint WDA_NONE = 0x0; 179 public const uint WDA_EXCLUDEFROMCAPTURE = 0x11; 180 181 // Helper methods 182 public static IntPtr FindAppWindowAtPoint(POINT pt) 183 { 184 IntPtr hwnd = WindowFromPoint(pt); 185 if (hwnd == IntPtr.Zero) return IntPtr.Zero; 186 return FindTopLevelWindow(hwnd); 187 } 188 189 public static IntPtr FindAppWindowAtPointExcluding(POINT pt, IntPtr excludeHwnd) 190 { 191 IntPtr hwnd = WindowFromPoint(pt); 192 if (hwnd == IntPtr.Zero) return IntPtr.Zero; 193 if (hwnd == excludeHwnd) 194 { 195 hwnd = GetWindow(excludeHwnd, GW_HWNDNEXT); 196 while (hwnd != IntPtr.Zero) 197 { 198 if (IsWindowVisible(hwnd)) 199 { 200 RECT rect; 201 if (GetWindowRect(hwnd, out rect)) 202 { 203 if (pt.X >= rect.Left && pt.X < rect.Right && 204 pt.Y >= rect.Top && pt.Y < rect.Bottom) break; 205 } 206 } 207 hwnd = GetWindow(hwnd, GW_HWNDNEXT); 208 } 209 } 210 return hwnd != IntPtr.Zero ? FindTopLevelWindow(hwnd) : IntPtr.Zero; 211 } 212 213 public static IntPtr FindTopLevelWindow(IntPtr hwnd) 214 { 215 if (hwnd == IntPtr.Zero) return IntPtr.Zero; 216 IntPtr current = hwnd; 217 IntPtr result = hwnd; 218 while (current != IntPtr.Zero) 219 { 220 int style = GetWindowLong(current, GWL_STYLE); 221 if ((style & WS_CHILD) == 0 && IsWindowVisible(current)) 222 { 223 if ((style & WS_CAPTION) != 0 || (style & WS_POPUP) != 0) result = current; 224 } 225 IntPtr parent = GetParent(current); 226 if (parent == IntPtr.Zero) 227 { 228 IntPtr owner = GetAncestor(current, GA_ROOTOWNER); 229 if (owner != IntPtr.Zero && owner != current) { current = owner; continue; } 230 break; 231 } 232 current = parent; 233 } 234 return result; 235 } 236 237 public static System.Drawing.Rectangle GetWindowRectangle(IntPtr hwnd) 238 { 239 RECT rect; 240 if (DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, out rect, Marshal.SizeOf(typeof(RECT))) == 0) 241 return new System.Drawing.Rectangle(rect.Left, rect.Top, rect.Width, rect.Height); 242 if (GetWindowRect(hwnd, out rect)) 243 return new System.Drawing.Rectangle(rect.Left, rect.Top, rect.Width, rect.Height); 244 return System.Drawing.Rectangle.Empty; 245 } 246 247 public static bool HasCaption(IntPtr hwnd) 248 { 249 int style = GetWindowLong(hwnd, GWL_STYLE); 250 return (style & WS_CAPTION) != 0; 251 } 252 253 public static string GetWindowTitle(IntPtr hwnd) 254 { 255 int length = GetWindowTextLength(hwnd); 256 if (length == 0) return string.Empty; 257 var sb = new System.Text.StringBuilder(length + 1); 258 GetWindowText(hwnd, sb, sb.Capacity); 259 return sb.ToString(); 260 } 261 262 public static string GetWindowClassName(IntPtr hwnd) 263 { 264 var sb = new System.Text.StringBuilder(256); 265 GetClassName(hwnd, sb, sb.Capacity); 266 return sb.ToString(); 267 } 268 269 public static IntPtr SetKeyboardHook(LowLevelKeyboardProc proc) 270 { 271 using (var curProcess = System.Diagnostics.Process.GetCurrentProcess()) 272 using (var curModule = curProcess.MainModule) 273 { 274 return SetWindowsHookEx(WH_KEYBOARD_LL, 275 (HookProc)((nCode, wParam, lParam) => proc(nCode, wParam, lParam)), 276 GetModuleHandle(curModule.ModuleName), 0); 277 } 278 } 279 280 [DllImport("user32.dll")] 281 public static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data); 282 283 [StructLayout(LayoutKind.Sequential)] 284 public struct WindowCompositionAttributeData 285 { 286 public WindowCompositionAttribute Attribute; 287 public IntPtr Data; 288 public int SizeOfData; 289 } 290 291 [StructLayout(LayoutKind.Sequential)] 292 public struct AccentPolicy 293 { 294 public AccentState AccentState; 295 public int AccentFlags; 296 public int GradientColor; 297 public int AnimationId; 298 } 299 300 public enum WindowCompositionAttribute { WCA_ACCENT_POLICY = 19 } 301 public enum AccentState 302 { 303 ACCENT_DISABLED = 0, 304 ACCENT_ENABLE_GRADIENT = 1, 305 ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, 306 ACCENT_ENABLE_BLURBEHIND = 3, 307 ACCENT_ENABLE_ACRYLICBLURBEHIND = 4, 308 ACCENT_INVALID_STATE = 5 309 } 310 311 public static void EnableAcrylicBlur(IntPtr hwnd, int tintColor) 312 { 313 var accent = new AccentPolicy { AccentState = AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND, GradientColor = tintColor }; 314 int accentSize = Marshal.SizeOf(accent); 315 IntPtr accentPtr = Marshal.AllocHGlobal(accentSize); 316 Marshal.StructureToPtr(accent, accentPtr, false); 317 var data = new WindowCompositionAttributeData { Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY, Data = accentPtr, SizeOfData = accentSize }; 318 SetWindowCompositionAttribute(hwnd, ref data); 319 Marshal.FreeHGlobal(accentPtr); 320 } 321 322 public static void EnableBlurBehind(IntPtr hwnd, int tintColor) 323 { 324 var accent = new AccentPolicy { AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND, GradientColor = tintColor }; 325 int accentSize = Marshal.SizeOf(accent); 326 IntPtr accentPtr = Marshal.AllocHGlobal(accentSize); 327 Marshal.StructureToPtr(accent, accentPtr, false); 328 var data = new WindowCompositionAttributeData { Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY, Data = accentPtr, SizeOfData = accentSize }; 329 SetWindowCompositionAttribute(hwnd, ref data); 330 Marshal.FreeHGlobal(accentPtr); 331 } 332 333 public static void DisableBlur(IntPtr hwnd) 334 { 335 var accent = new AccentPolicy { AccentState = AccentState.ACCENT_DISABLED }; 336 int accentSize = Marshal.SizeOf(accent); 337 IntPtr accentPtr = Marshal.AllocHGlobal(accentSize); 338 Marshal.StructureToPtr(accent, accentPtr, false); 339 var data = new WindowCompositionAttributeData { Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY, Data = accentPtr, SizeOfData = accentSize }; 340 SetWindowCompositionAttribute(hwnd, ref data); 341 Marshal.FreeHGlobal(accentPtr); 342 } 343 344 [DllImport("user32.dll")] 345 public static extern bool SetProcessDPIAware(); 346 [DllImport("shcore.dll", SetLastError = true)] 347 public static extern int SetProcessDpiAwareness(int value); 348 public const int PROCESS_DPI_UNAWARE = 0; 349 public const int PROCESS_SYSTEM_DPI_AWARE = 1; 350 public const int PROCESS_PER_MONITOR_DPI_AWARE = 2; 351 [DllImport("gdi32.dll")] 352 public static extern int GetDeviceCaps(IntPtr hdc, int nIndex); 353 public const int LOGPIXELSX = 88; 354 public const int LOGPIXELSY = 90; 355 public static float GetDpiScale() 356 { 357 IntPtr hdc = GetDC(IntPtr.Zero); 358 if (hdc == IntPtr.Zero) return 1.0f; 359 int dpiX = GetDeviceCaps(hdc, LOGPIXELSX); 360 ReleaseDC(IntPtr.Zero, hdc); 361 return dpiX / 96f; 362 } 363 364 [DllImport("dwmapi.dll")] 365 public static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, ref int pvAttribute, int cbAttribute); 366 public const int DWMWA_WINDOW_CORNER_PREFERENCE = 33; 367 public const int DWMWCP_ROUND = 2; 368 public static bool TryEnableRoundedCorners(IntPtr hwnd, int preference = 2) 369 { 370 try { return DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, ref preference, sizeof(int)) == 0; } 371 catch { return false; } 372 } 373 374 [DllImport("winmm.dll", CharSet = CharSet.Auto)] 375 public static extern int mciSendString(string lpstrCommand, System.Text.StringBuilder lpstrReturnString, int uReturnLength, IntPtr hwndCallback); 376 377 [DllImport("Ole32.dll")] 378 public static extern int CoCreateInstance(ref Guid rclsid, IntPtr pUnkOuter, int dwClsContext, ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv); 379 public static readonly Guid CLSID_MMDeviceEnumerator = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"); 380 public static readonly Guid IID_IMMDeviceEnumerator = new Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"); 381 public const int CLSCTX_ALL = 0xF; 382 public const int AUDCLNT_STREAMFLAGS_LOOPBACK = 0x00020000; 383 public const int AUDCLNT_SHAREMODE_SHARED = 0; 384 public const int WAVE_FORMAT_IEEE_FLOAT = 3; 385 public const int WAVE_FORMAT_PCM = 1; 386 387 [DllImport("ole32.dll")] 388 public static extern int CoInitializeEx(IntPtr pvReserved, uint dwCoInit); 389 [DllImport("ole32.dll")] 390 public static extern void CoUninitialize(); 391 public const uint COINIT_MULTITHREADED = 0x0; 392 393 [DllImport("mfplat.dll")] 394 public static extern int MFStartup(uint Version, uint dwFlags); 395 [DllImport("mfplat.dll")] 396 public static extern int MFShutdown(); 397 [DllImport("mfplat.dll")] 398 public static extern int MFCreateMediaType([MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppMFType); 399 [DllImport("mfplat.dll")] 400 public static extern int MFCreateSample([MarshalAs(UnmanagedType.Interface)] out IMFSample ppSample); 401 [DllImport("mfplat.dll")] 402 public static extern int MFCreateMemoryBuffer(uint cbMaxLength, [MarshalAs(UnmanagedType.Interface)] out IMFMediaBuffer ppBuffer); 403 [DllImport("mfplat.dll")] 404 public static extern int MFCreateAttributes([MarshalAs(UnmanagedType.Interface)] out IMFAttributes ppAttributes, uint cInitialSize); 405 406 [DllImport("mfreadwrite.dll", CharSet = CharSet.Unicode)] 407 public static extern int MFCreateSourceReaderFromURL(string pwszURL, IMFAttributes pAttributes, [MarshalAs(UnmanagedType.Interface)] out IMFSourceReader ppSourceReader); 408 [DllImport("mfreadwrite.dll", CharSet = CharSet.Unicode, EntryPoint = "MFCreateSourceReaderFromURL")] 409 public static extern int MFCreateSourceReaderFromURL_IntPtr([MarshalAs(UnmanagedType.LPWStr)] string pwszURL, IntPtr pAttributes, out IMFSourceReader ppSourceReader); 410 [DllImport("mfreadwrite.dll", CharSet = CharSet.Unicode)] 411 public static extern int MFCreateSinkWriterFromURL(string pwszURL, IMFAttributes pByteStream, IMFAttributes pAttributes, [MarshalAs(UnmanagedType.Interface)] out IMFSinkWriter ppSinkWriter); 412 413 public const uint MF_VERSION = 0x00020070; 414 public const uint MF_SOURCE_READER_FIRST_AUDIO_STREAM = 0xFFFFFFFD; 415 public const int MF_SOURCE_READERF_ENDOFSTREAM = 0x2; 416 417 public static readonly Guid MFMediaType_Audio = new Guid(0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); 418 public static readonly Guid MFAudioFormat_PCM = new Guid(0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); 419 public static readonly Guid MF_MT_MAJOR_TYPE = new Guid(0x48eba18e, 0xf8c9, 0x4687, 0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f); 420 public static readonly Guid MF_MT_SUBTYPE = new Guid(0xf7e34c9a, 0x42e8, 0x4714, 0xb7, 0x4b, 0xcb, 0x29, 0xd7, 0x2c, 0x35, 0xe5); 421 public static readonly Guid MF_MT_AUDIO_NUM_CHANNELS = new Guid(0x37e48bf5, 0x645e, 0x4c5b, 0x89, 0xde, 0xad, 0xa9, 0xe2, 0x9b, 0x69, 0x6a); 422 public static readonly Guid MF_MT_AUDIO_SAMPLES_PER_SECOND = new Guid(0x5faeeae7, 0x0290, 0x4c31, 0x9e, 0x8a, 0xc5, 0x34, 0xf6, 0x8d, 0x9e, 0xda); 423 public static readonly Guid MF_MT_AUDIO_BITS_PER_SAMPLE = new Guid(0xf2deb57f, 0x40fa, 0x4764, 0xaa, 0x33, 0xed, 0x4f, 0x2d, 0x1f, 0xf6, 0x69); 424 public static readonly Guid MF_MT_AUDIO_BLOCK_ALIGNMENT = new Guid(0x322de230, 0x9eeb, 0x43bd, 0xab, 0x7a, 0xff, 0x41, 0x22, 0x51, 0x54, 0x1d); 425 public static readonly Guid MF_MT_AUDIO_AVG_BYTES_PER_SECOND = new Guid(0x1aab75c8, 0xcfef, 0x451c, 0xab, 0x95, 0xac, 0x03, 0x4b, 0x8e, 0x17, 0x31); 426 427 public static readonly Guid MFMediaType_Video = new Guid(0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); 428 public static readonly Guid MFVideoFormat_H264 = new Guid(0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); 429 public static readonly Guid MFVideoFormat_RGB32 = new Guid(0x00000016, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); 430 431 public static readonly Guid MFVideoFormat_NV12 = new Guid(0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); 432 public static readonly Guid MFVideoFormat_WMV3 = new Guid(0x33564D57, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); 433 public static readonly Guid MF_MT_FRAME_SIZE = new Guid(0x1652c333, 0xd6b2, 0x4d2d, 0x8c, 0x5d, 0x33, 0x40, 0x7e, 0xe5, 0x61, 0x05); 434 public static readonly Guid MF_MT_FRAME_RATE = new Guid(0xc45972d0, 0xd22c, 0x4e4a, 0x9c, 0x5b, 0x25, 0xa1, 0x1e, 0x2d, 0x08, 0x11); 435 public static readonly Guid MF_MT_PIXEL_ASPECT_RATIO = new Guid(0xc63764b4, 0x3e23, 0x4227, 0xad, 0xd8, 0x8f, 0x8d, 0x21, 0x39, 0x45, 0x71); 436 public static readonly Guid MF_MT_INTERLACE_MODE = new Guid(0xe2724330, 0xadba, 0x4e6d, 0x81, 0x35, 0x29, 0x09, 0x7a, 0x45, 0xad, 0x2a); 437 public static readonly Guid MF_MT_AVG_BITRATE = new Guid(0x20503f12, 0xad24, 0x40a2, 0x8a, 0x2d, 0x84, 0x44, 0x38, 0x35, 0xe2, 0x06); 438 public static readonly Guid MF_MT_MPEG2_PROFILE = new Guid(0xad76a80b, 0x2d5c, 0x4e0b, 0xb3, 0x75, 0x64, 0xe5, 0x20, 0x13, 0x70, 0x36); 439 440 public static readonly Guid CODECAPI_AVEncCommonRateControlMode = new Guid(0x1c0608e9, 0x370c, 0x4710, 0x8a, 0x58, 0xcb, 0x61, 0x81, 0xc4, 0x24, 0x23); 441 public static readonly Guid CODECAPI_AVEncCommonQuality = new Guid(0xfcbf57a3, 0x7ea5, 0x4b0c, 0x96, 0x44, 0x69, 0xb4, 0x0c, 0x39, 0xc3, 0x91); 442 public static readonly Guid MF_MT_DEFAULT_STRIDE = new Guid(0x644ad991, 0xec0d, 0x49c8, 0x91, 0x1a, 0xa8, 0x18, 0x06, 0x9a, 0x7e, 0x5b); 443 444 public static readonly Guid MF_SINK_WRITER_DISABLE_THROTTLING = new Guid(0x08430576, 0x2701, 0x4512, 0xaf, 0x4c, 0x8d, 0x24, 0x25, 0xa1, 0x49, 0xee); 445 446 public static ulong PackToUINT64(uint high, uint low) 447 { 448 return ((ulong)high << 32) | low; 449 } 450 451 // ===== Clipboard manager ===== 452 public const int WM_CLIPBOARDUPDATE = 0x031D; 453 [DllImport("user32.dll", SetLastError = true)] 454 public static extern bool AddClipboardFormatListener(IntPtr hwnd); 455 [DllImport("user32.dll", SetLastError = true)] 456 public static extern bool RemoveClipboardFormatListener(IntPtr hwnd); 457 458 // Caret / cursor position 459 [DllImport("user32.dll")] 460 public static extern bool GetCursorPos(out POINT lpPoint); 461 [DllImport("user32.dll")] 462 public static extern bool GetCaretPos(out POINT lpPoint); 463 [DllImport("user32.dll")] 464 public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint); 465 [DllImport("user32.dll")] 466 public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 467 [DllImport("user32.dll")] 468 public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); 469 [DllImport("user32.dll")] 470 public static extern IntPtr GetForegroundWindow(); 471 [DllImport("user32.dll")] 472 public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 473 [DllImport("user32.dll")] 474 public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); 475 [DllImport("user32.dll")] 476 public static extern IntPtr GetFocus(); 477 [DllImport("kernel32.dll")] 478 public static extern uint GetCurrentThreadId(); 479 480 [StructLayout(LayoutKind.Sequential)] 481 public struct GUITHREADINFO 482 { 483 public int cbSize; 484 public uint flags; 485 public IntPtr hwndActive; 486 public IntPtr hwndFocus; 487 public IntPtr hwndCapture; 488 public IntPtr hwndMenuOwner; 489 public IntPtr hwndMoveSize; 490 public IntPtr hwndCaret; 491 public RECT rcCaret; 492 } 493 [DllImport("user32.dll")] 494 public static extern bool GetGUIThreadInfo(uint idThread, ref GUITHREADINFO lpgui); 495 496 // ===== Keyboard layout (language switcher) ===== 497 [DllImport("user32.dll")] 498 public static extern IntPtr GetKeyboardLayout(uint idThread); 499 [DllImport("user32.dll")] 500 public static extern IntPtr ActivateKeyboardLayout(IntPtr hkl, uint flags); 501 public const uint KLF_SETFORTHREAD = 0x00000100; 502 [DllImport("user32.dll")] 503 public static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); 504 public const uint WM_INPUTLANGCHANGEREQUEST = 0x0050; 505 506 // SendInput for typing corrected text 507 [DllImport("user32.dll", SetLastError = true)] 508 public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); 509 510 [StructLayout(LayoutKind.Sequential)] 511 public struct INPUT 512 { 513 public uint type; 514 public INPUTUNION u; 515 } 516 517 [StructLayout(LayoutKind.Explicit)] 518 public struct INPUTUNION 519 { 520 [FieldOffset(0)] public KEYBDINPUT ki; 521 } 522 523 [StructLayout(LayoutKind.Sequential)] 524 public struct KEYBDINPUT 525 { 526 public ushort wVk; 527 public ushort wScan; 528 public uint dwFlags; 529 public uint time; 530 public IntPtr dwExtraInfo; 531 } 532 533 public const uint INPUT_KEYBOARD = 1; 534 public const uint KEYEVENTF_KEYUP = 0x0002; 535 public const uint KEYEVENTF_UNICODE = 0x0004; 536 public const ushort VK_BACK = 0x08; 537 public const ushort VK_CONTROL = 0xA2; 538 public const ushort VK_SHIFT = 0xA0; 539 public const ushort VK_LEFT = 0x25; 540 } 541}