windowcapture
исходный код / Native/WinApi.cs

WinApi.cs

541 строк · 26,894 байт · модуль Native
  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}