private void RegisterWindowClass() { _wndProcDelegate = WndProc; var wc = new WindowClassEx { Styles = WindowClassStyles.CS_HREDRAW | WindowClassStyles.CS_VREDRAW | WindowClassStyles.CS_OWNDC, WindowProc = _wndProcDelegate, InstanceHandle = Kernel32.GetModuleHandle(null), CursorHandle = User32.LoadCursor(IntPtr.Zero, (IntPtr)SystemCursor.IDC_ARROW), ClassName = CLASS_NAME }; wc.Size = (uint)Marshal.SizeOf(wc); // Load user icon - if any. wc.IconHandle = User32.LoadImage(Kernel32.GetModuleHandle(null), "#32512", ResourceImageType.IMAGE_ICON, 0, 0, LoadResourceFlags.LR_DEFAULTSIZE | LoadResourceFlags.LR_SHARED); if (wc.IconHandle == IntPtr.Zero) { Kernel32.SetLastError(0); // None loaded - load default. wc.IconHandle = User32.LoadImage(IntPtr.Zero, (IntPtr)SystemIcon.IDI_APPLICATION, ResourceImageType.IMAGE_ICON, 0, 0, LoadResourceFlags.LR_DEFAULTSIZE | LoadResourceFlags.LR_SHARED); } ushort windowClass = User32.RegisterClassEx(ref wc); if (windowClass == 0) { CheckError("Win32: Failed to register window class.", true); } CheckError("Win32: Could not register class."); }
public static bool GetIsProcessorAMD64() { SystemInfo info; Kernel32Methods.GetNativeSystemInfo(out info); return(info.ProcessorArchitecture == (uint)ProcessArchitecture.PROCESSOR_ARCHITECTURE_AMD64); }
/// <summary> /// Check for a Win32 error. /// </summary> /// <param name="msg">A message to display with the error.</param> /// <param name="sureError">Whether you are sure an error occured.</param> public static void CheckError(string msg, bool sureError = false) { uint errorCheck = Kernel32.GetLastError(); if (errorCheck == 0 && !sureError) { return; } // Check predefined errors. switch (errorCheck) { case ERROR_INVALID_VERSION_ARB: Engine.SubmitError(new Exception($"Driver doesn't support version of {msg}")); break; case ERROR_INVALID_PROFILE_ARB: Engine.SubmitError(new Exception($"Driver doesn't support profile of {msg}")); break; default: Engine.SubmitError(new Exception(msg, new Win32Exception((int)errorCheck))); break; } }
public static Version GetVersion() { var dwVersion = Kernel32Methods.GetVersion(); var build = dwVersion < 0x80000000 ? dwVersion.HighAsUInt() : 0; // (DWORD) (HIWORD(dwVersion)) var v = new Version( (byte)dwVersion.Low(), // (DWORD)(LOBYTE(LOWORD(dwVersion))) (dwVersion.Low() >> 8) & 0xff, (int)build // (DWORD)(HIBYTE(LOWORD(dwVersion))) ); return(v); }
/// <summary> /// Updates key names according to the current keyboard layout. /// </summary> private void PopulateKeyNames() { var state = new byte[256]; // Initialize the key names array. _keyNames = new string[_scanCodes.Length]; for (var key = (int)Key.Space; key < (int)Key.Last; key++) { uint vk; int scanCode = _scanCodes[key]; if (scanCode == -1) { continue; } if (key >= (int)Key.Kp0 && key <= (int)Key.KpAdd) { uint[] vks = { (uint)VirtualKey.NUMPAD0, (uint)VirtualKey.NUMPAD1, (uint)VirtualKey.NUMPAD2, (uint)VirtualKey.NUMPAD3, (uint)VirtualKey.NUMPAD4, (uint)VirtualKey.NUMPAD5, (uint)VirtualKey.NUMPAD6, (uint)VirtualKey.NUMPAD7, (uint)VirtualKey.NUMPAD8, (uint)VirtualKey.NUMPAD9, (uint)VirtualKey.DECIMAL, (uint)VirtualKey.DIVIDE, (uint)VirtualKey.MULTIPLY, (uint)VirtualKey.SUBTRACT, (uint)VirtualKey.ADD }; vk = vks[key - (int)Key.Kp0]; } else { vk = User32.MapVirtualKey((uint)scanCode, VirtualKeyMapType.MAPVK_VSC_TO_VK); } var chars = new StringBuilder(16); int length = User32.ToUnicode(vk, (uint)scanCode, state, chars, chars.Capacity, 0); if (length == -1) { length = User32.ToUnicode(vk, (uint)scanCode, state, chars, chars.Capacity, 0); } if (length < 1) { continue; } var keyName = new char[5]; Kernel32.WideCharToMultiByte(CodePage.CpUtf8, 0, chars, 1, keyName, keyName.Length, IntPtr.Zero, out bool _); _keyNames[key] = NativeHelpers.StringFromNullTerminated(keyName); } }
private void CreateHelperWindow() { HelperWindowHandle = User32.CreateWindowEx( WindowExStyles.WS_EX_OVERLAPPEDWINDOW, CLASS_NAME, "Emotion Helper Window", WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN, 0, 0, 100, 100, IntPtr.Zero, IntPtr.Zero, Kernel32.GetModuleHandle(null), IntPtr.Zero ); if (HelperWindowHandle == IntPtr.Zero) { CheckError("Win32: Failed to create helper window.", true); } // HACK: The command to the first ShowWindow call is ignored if the parent // process passed along a STARTUPINFO, so clear that with a no-op call User32.ShowWindow(HelperWindowHandle, ShowWindowCommands.SW_HIDE); // Register for HID device notifications var dbi = new DevBroadcastDeviceInterfaceW(); dbi.DbccSize = (uint)Marshal.SizeOf(dbi); dbi.DbccDeviceType = DeviceType.DeviceInterface; dbi.DbccClassGuid = User32Guids.GuidDevInterfaceHid; _deviceNotificationHandle = User32.RegisterDeviceNotificationW(HelperWindowHandle, ref dbi, DeviceNotificationFlags.WindowHandle); CheckError("Registering for device notifications."); while (User32.PeekMessage(out Message msg, HelperWindowHandle, 0, 0, PeekMessageFlags.PM_REMOVE)) { User32.TranslateMessage(ref msg); User32.DispatchMessage(ref msg); } Kernel32.SetLastError(0); CheckError("Creating helper window."); }
/// <inheritdoc /> protected override void SetupPlatform(Configurator config) { // todo: load libraries - if any // probably XInput // Initialize audio - Try to create WasApi - otherwise return the fake context so execution can go on. Audio = WasApiAudioContext.TryCreate() ?? (AudioContext) new NullAudioContext(); Engine.Log.Trace("Audio init complete.", MessageSource.Win32); PopulateKeyNames(); if (IsWindows10CreatorsUpdateOrGreaterWin32) { User32.SetProcessDpiAwarenessContext(DpiAwarenessContext.DpiAwarenessContextPerMonitorAwareV2); } else if (IsWindows81OrGreater) { User32.SetProcessDpiAwareness(ProcessDpiAwareness.ProcessPerMonitorDpiAware); } else { User32.SetProcessDPIAware(); } RegisterWindowClass(); CreateHelperWindow(); PollMonitors(); Engine.Log.Trace("Platform init complete.", MessageSource.Win32); var windowInitialSize = new Rect { Right = (int)config.HostSize.X, Bottom = (int)config.HostSize.Y }; Win32Window.GetFullWindowRect(Win32Window.DEFAULT_WINDOW_STYLE, Win32Window.DEFAULT_WINDOW_STYLE_EX, DEFAULT_DPI, ref windowInitialSize); int initialWidth = windowInitialSize.Right - windowInitialSize.Left; int initialHeight = windowInitialSize.Bottom - windowInitialSize.Top; IntPtr handle = User32.CreateWindowEx( Win32Window.DEFAULT_WINDOW_STYLE_EX, CLASS_NAME, config.HostTitle, Win32Window.DEFAULT_WINDOW_STYLE, (int)CreateWindowFlags.CW_USEDEFAULT, (int)CreateWindowFlags.CW_USEDEFAULT, // Position - default initialWidth, initialHeight, // Size - initial IntPtr.Zero, // No parent window IntPtr.Zero, // No window menu Kernel32.GetModuleHandle(null), IntPtr.Zero ); if (handle == IntPtr.Zero) { CheckError("Couldn't create window.", true); return; } Engine.Log.Trace("Window created.", MessageSource.Win32); // Create graphics context - OpenGL. GraphicsContext context = null; try { var wgl = new WglGraphicsContext(); wgl.Init(handle, this); if (wgl.Valid) { context = wgl; } } catch (Exception ex) { Engine.Log.Warning($"Couldn't create WGL context, falling back to MESA if possible.\n{ex}", MessageSource.Win32); } if (context == null) { try { var gallium = new GalliumGraphicsContext(); gallium.Init(handle, this); if (gallium.Valid) { context = gallium; } } catch (Exception ex) { Engine.SubmitError(new Exception("Couldn't create MESA context.", ex)); } } if (context == null) { Engine.SubmitError(new Exception("Couldn't create graphics context!")); return; } // Create Emotion representation of the window. var windowInstance = new Win32Window(handle, context, this); // Adjust window size to account for DPI scaling of the window frame and optionally DPI scaling of the content area. // This cannot be done until we know what monitor it was placed on - so it's done post creation. var rect = new Rect { Right = (int)config.HostSize.X, Bottom = (int)config.HostSize.Y }; rect.ClientToScreen(windowInstance.Handle); windowInstance.GetFullWindowRect(ref rect); User32.SetWindowPos(windowInstance.Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, WindowPositionFlags.SWP_NOACTIVATE | WindowPositionFlags.SWP_NOZORDER); Window = windowInstance; }
/// <inheritdoc /> public override IntPtr GetLibrarySymbolPtr(IntPtr library, string symbolName) { return(Kernel32.GetProcAddress(library, symbolName)); }
/// <inheritdoc /> public override IntPtr LoadLibrary(string path) { return(Kernel32.LoadLibrary(path)); }