protected void RegisterClass(string className) { _wndClass = WndClassEx.Build(); _wndClass.lpfnWndProc = WindowProc; _wndClass.lpszClassName = className; if (WindowMessageApiImports.RegisterClassEx(ref _wndClass) == 0) { Debug.WriteLine($"Failed to {nameof(RegisterClass)} '{className}': {Marshal.GetLastWin32Error()}"); } }
public virtual void Run() { int instance = Kernel.GetModuleHandle(null); WndClassEx wndclass = new WndClassEx(); Msg msg = new Msg(); String clName = "Entry Area"; Win32.WinCB wcb = new Win32.WinCB(this.CallBack); root = System.Runtime.InteropServices.GCHandle.Alloc(wcb); wndclass.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(wndclass); wndclass.style = ClassStyle.HRedraw | ClassStyle.VRedraw; wndclass.lpfnWndProc = wcb; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = instance; this.instance = instance; wndclass.hIcon = User.LoadIcon(0, IconID.Application); wndclass.hCursor = User.LoadCursor(0, CursorID.Arrow); wndclass.hbrBackground = GDI.GetStockObject(Brush.White); wndclass.lpszMenuName = null; wndclass.lpszClassName = clName; wndclass.hIconSm = User.LoadIcon(0, IconID.Application); if (User.RegisterClassExA(wndclass) == 0) { throw new System.ApplicationException("Unable to Register Entry Dialog"); } wnd = User.CreateWindowEx(0, clName, clName, WinStyle.OverlappedWindow, 0, 0, xDim, yDim, 0, 0, instance, 0); if (wnd == 0) { throw new System.ApplicationException(Error.GetSystemErrorMessage()); } User.ShowWindow(wnd, ShowWindow.ShowNormal); User.UpdateWindow(wnd); while (User.GetMessage(msg, 0, 0, 0) != 0) { User.TranslateMessage(msg); User.DispatchMessage(msg); } root.Free(); }
public static void CreateWindow(IntPtr hwndParent, WndProc handler, int width, int height, out IntPtr hwnd, out IntPtr hinstance) { const string WindowClass = "VeldridHwndWrapper"; hinstance = GetModuleHandle(null); var wndClass = new WndClassEx(); wndClass.cbSize = (uint)Marshal.SizeOf(wndClass); wndClass.hInstance = hinstance; wndClass.lpfnWndProc = handler; wndClass.lpszClassName = WindowClass; wndClass.hCursor = LoadCursor(IntPtr.Zero, IDC_ARROW); RegisterClassEx(ref wndClass); hwnd = CreateWindowEx(0, WindowClass, "", WS_CHILD | WS_VISIBLE, 0, 0, width, height, hwndParent, IntPtr.Zero, IntPtr.Zero, 0); }
// Public methods /////////////////////// public static void Start() { if (thread != null) { return; } thread = Thread.Run("event loop", () => { var moduleHandle = GetModuleHandle(IntPtr.Zero); wndProcDelegate = OnWndProc; var wndClass = WndClassEx.New(); wndClass.lpszClassName = CLASS_NAME; wndClass.lpfnWndProc = wndProcDelegate; wndClass.hInstance = moduleHandle; var classAtom = RegisterClassExW(ref wndClass); if (classAtom == IntPtr.Zero) { var lastError = Marshal.GetLastWin32Error(); Log.Error($"Could not register window class (code {lastError})"); return; } handle = CreateWindowExW( 0, classAtom, String.Empty, 0, 0, 0, 0, 0, HWND_MESSAGE, IntPtr.Zero, moduleHandle, IntPtr.Zero ); if (handle == IntPtr.Zero) { var lastError = Marshal.GetLastWin32Error(); Log.Error($"Could create window with class {classAtom} (code {lastError})"); return; } System.Windows.Forms.Application.Run(); }); }
/// <summary> /// Initializes a new instance of the <see cref="RenderForm" /> class. /// </summary> /// <param name="windowTitle"> (Optional) The window title. </param> /// <exception cref="Win32Exception"> Thrown when a Window 32 error condition occurs. </exception> public RenderForm(string windowTitle = "RenderForm") { _windowTitle = windowTitle; _rawKeyPipe = new Pipe <RawKeyEventHandler>(); _keyUpPipe = new Pipe <KeyEventHandler>(); _keyDownPipe = new Pipe <KeyEventHandler>(); _keyPressPipe = new Pipe <KeyPressEventHandler>(); _mouseMovePipe = new Pipe <MouseEventHandler>(); _mouseUpPipe = new Pipe <MouseEventHandler>(); _mouseDownPipe = new Pipe <MouseEventHandler>(); _mouseClickPipe = new Pipe <MouseEventHandler>(); _mouseWheelPipe = new Pipe <MouseEventHandler>(); _mouseRawInputPipe = new Pipe <MouseEventHandler>(); _wndClassEx = new WndClassEx { cbSize = Marshal.SizeOf <WndClassEx>(), style = ClassStyles.HorizontalRedraw | ClassStyles.VerticalRedraw | ClassStyles.DoubleClicks | ClassStyles.OwnDC, hbrBackground = (IntPtr)COLOR_WINDOW + 1, //null, cbClsExtra = 0, cbWndExtra = 0, hInstance = Kernel32.GetModuleHandle(null !), hIcon = Shell32.ExtractIcon(IntPtr.Zero, Assembly.GetExecutingAssembly().Location, 0), hCursor = User32.LoadCursor(IntPtr.Zero, IDC_ARROW), lpszMenuName = null !, lpszClassName = LP_CLASS_NAME, lpfnWndProc = WndProc, hIconSm = IntPtr.Zero }; ushort regResult = User32.RegisterClassEx(ref _wndClassEx); if (regResult == 0) { throw new Win32Exception( Kernel32.GetLastError(), $"{nameof(User32.RegisterClassEx)} failed with code {regResult}!"); } }
public static extern short RegisterClassEx([In] ref WndClassEx lpwcx);
static extern IntPtr RegisterClassExW(ref WndClassEx lpWndClass);
public bool Start() { if (!Running) { var readyEvent = new ManualResetEventSlim(); taskFactory.StartNew(() => { var processHandle = Process.GetCurrentProcess().Handle; var windowClass = new WndClassEx { lpszMenuName = null, hInstance = processHandle, cbSize = WndClassEx.Size, lpfnWndProc = windowCallback, lpszClassName = Guid.NewGuid().ToString() }; // Register the dummy window class var classAtom = RegisterClassEx(ref windowClass); // Check whether the class was registered successfully if (classAtom != 0u) { // Create the dummy window Handle = CreateWindowEx(0x08000000, classAtom, "", 0, -1, -1, -1, -1, IntPtr.Zero, IntPtr.Zero, processHandle, IntPtr.Zero); Running = Handle != IntPtr.Zero; // Unblock calling thread as everything is ready to go readyEvent.Set(); // If window has been created, initialize the message window loop if (Running) { Message message = new Message(); OnStarted?.Invoke(this, EventArgs.Empty); while (GetMessage(out message, IntPtr.Zero, 0, 0) != 0) { TranslateMessage(ref message); DispatchMessage(ref message); } OnShutdown?.Invoke(this, EventArgs.Empty); } } else { // Failed to create the dummy window class. Unblock calling thread readyEvent.Set(); } }); // Block calling thread untill we have the window creation result readyEvent.Wait(); } return(Running); }
private static extern ushort RegisterClassEx([In] ref WndClassEx lpwcx);
//public void ShowAnimate(bool show) //{ // //Don't add AWnd function, because: // //Rarely used. // //Api.AnimateWindow() works only with windows of current thread. // //Only programmers would need it, and they can call the API directly. //} /// <summary> /// Registers new window class in this process. /// </summary> /// <param name="className">Class name.</param> /// <param name="wndProc"> /// Delegate of a window procedure. See <msdn>Window Procedures</msdn>. /// /// Use null when you need a different delegate (method or target object) for each window instance; create windows with <see cref="CreateWindow(Native.WNDPROC, string, string, WS, WS2, int, int, int, int, AWnd, LPARAM, IntPtr, LPARAM)"/> or <see cref="CreateMessageOnlyWindow(Native.WNDPROC, string)"/>. /// If not null, it must be a static method; create windows with any other function, including API <msdn>CreateWindowEx</msdn>. /// </param> /// <param name="ex"> /// Can be used to specify more fields of <msdn>WNDCLASSEX</msdn> that is passed to API <msdn>RegisterClassEx</msdn>. /// Defaults: hCursor = arrow; hbrBackground = COLOR_BTNFACE+1; style = CS_GLOBALCLASS; others = 0/null/default. /// This function also adds CS_GLOBALCLASS style. /// </param> /// <exception cref="ArgumentException"><i>wndProc</i> is an instance method. Must be static method or null. If need instance method, use null here and pass <i>wndProc</i> to <see cref="CreateWindow"/>.</exception> /// <exception cref="InvalidOperationException">The class already registered with this function and different <i>wndProc</i> (another method or another target object).</exception> /// <exception cref="Win32Exception">Failed, for example if the class already exists and was registered not with this function.</exception> /// <remarks> /// Calls API <msdn>RegisterClassEx</msdn>. /// The window class is registered until this process ends. Don't need to unregister. /// If called next time for the same window class, does nothing if <i>wndProc</i> is equal to the previous (or both null). Then ignores <i>ex</i>. Throws exception if different. /// Thread-safe. /// Protects the <i>wndProc</i> delegate from GC. /// </remarks> public static unsafe void RegisterWindowClass(string className, Native.WNDPROC wndProc = null, WndClassEx ex = null) { if (wndProc?.Target != null) { throw new ArgumentException("wndProc must be static method or null. Use non-static wndProc with CreateWindow."); } lock (s_classes) { if (s_classes.TryGetValue(className, out var wpPrev)) { if (wpPrev != wndProc) { throw new InvalidOperationException("Window class already registered"); //another method or another target object } return; } var x = new Api.WNDCLASSEX(ex); fixed(char *pCN = className) { x.lpszClassName = pCN; if (wndProc != null) { x.lpfnWndProc = Marshal.GetFunctionPointerForDelegate(wndProc); } else { #if CW_CBT if (s_defWindowProc == default) { s_defWindowProc = Api.GetProcAddress("user32.dll", "DefWindowProcW"); } x.lpfnWndProc = s_defWindowProc; #else if (s_cwProcFP == default) { s_cwProcFP = Marshal.GetFunctionPointerForDelegate(s_cwProc); } x.lpfnWndProc = s_cwProcFP; #endif } x.style |= Api.CS_GLOBALCLASS; if (0 == Api.RegisterClassEx(x)) { throw new Win32Exception(); } //note: we don't return atom because: 1. Rarely used. 2. If assigned to an unused field, compiler may remove the function call. s_classes.Add(className, wndProc); } } }
public static extern ushort RegisterClassEx(ref WndClassEx lpWndClass);
public static extern int RegisterClassExA([In, Out] WndClassEx w);