NativeWindow gives you a way to way to intercept the window messages (are you familiar with the Windows Message Pump?)
Aslo, this class have provided with some default impl on manipulating handles and create child handle/control.s
NativeWindow for Message Intercepting and Handle Manipulation
We will first start from the basic example of the NativeWindow. This is an example that is taken from the MSDN NativeWindow Class page.
The code is as below.
// NativeWindow class // please check // http://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow.aspx // Summary description for Form1. [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] public class Form1 : System.Windows.Forms.Form { private MyNativeWindowListener nwl; private MyNativeWindow nw; internal void ApplicationActivated(bool ApplicationActivated) { // The application has been activated or deactivated System.Diagnostics.Debug.WriteLine("Application Active = " + ApplicationActivated.ToString()); } private Form1() { this.Size = new System.Drawing.Size(300, 300); this.Text = "Form1"; nwl = new MyNativeWindowListener(this); nw = new MyNativeWindow(this); } // The main entry point for the application. [STAThread] static void Main() { Application.Run(new Form1()); } } [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] internal class MyNativeWindowListener : NativeWindow { // Constant value was found in the "windows.h" header file. private const int WM_ACTIVATEAPP = 0x001C; private Form1 parent; public MyNativeWindowListener(Form1 parent) { parent.HandleCreated += new EventHandler(this.OnHandleCreated); parent.HandleDestroyed += new EventHandler(this.OnHandleDestroyed); this.parent = parent; } internal void OnHandleCreated(object sender, EventArgs e) { // Window is now created, assign handle to NativeWindow. AssignHandle(((Form1)sender).Handle); } internal void OnHandleDestroyed(object sender, EventArgs e) { // Window was destroyed, release hook. ReleaseHandle(); } [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] protected override void WndProc(ref Message m) { // Listen for operating system messages switch (m.Msg) { case WM_ACTIVATEAPP: // Notify the form that this message was received. // Application is activated or deactivated, // based upon the WParam parameter. parent.ApplicationActivated(((int)m.WParam != 0)); break; } base.WndProc(ref m); } } // MyNativeWindow class to create a window given a class name. [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] internal class MyNativeWindow : NativeWindow { // Constant values were found in the "windows.h" header file. private const int WS_CHILD = 0x40000000, WS_VISIBLE = 0x10000000, WM_ACTIVATEAPP = 0x001C; private int windowHandle; public MyNativeWindow(Form parent) { CreateParams cp = new CreateParams(); // Fill in the CreateParams details. cp.Caption = "Click here"; cp.ClassName = "Button"; // the classname has some predefined enumerations so that it knows what type of Control/handle to create. // Set the position on the form cp.X = 100; cp.Y = 100; cp.Height = 100; cp.Width = 100; // Specify the form as the parent. cp.Parent = parent.Handle; // Create as a child of the specified parent cp.Style = WS_CHILD | WS_VISIBLE; this.CreateHandle(cp); } // Listen to when the handle changes to keep the variable in sync [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] protected override void OnHandleChange() { windowHandle = (int)this.Handle; } [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_ACTIVATEAPP: // DO someting here in response to messages break; } base.WndProc(ref m); } }
the first derived class to MyNativeWindowListener class intercept the calls to Form's. It assign/destroy the handle (the handle of the main form is assigned) so that the interceptin is done. it will listen to the WM_ACTIVATE call and active the main form.)
the second class MyNativeWindow, what it does is to cretae a child handle based on the main handled passed in, the main handle is the handle of the form's. and this shows how you can leverage the NativeWindow to manipulate the handles/Controls.
If you run this code, you will see the following as a result.
NativeWindow to provide message pump
There is a post - Message Pump in .Net windows Service where a method of using the NativeWindow to simulate the Messgae Pump is discussed. and here is the detailed code.
public class MessgePumpManager { private readonly Thread messagePump; private AutoResetEvent messagePumpRunning = new AutoResetEvent(false); public MessgePumpManager() { // start message pump in its own thread messagePump = new Thread(RunMessagePump) { Name = "ManualMessagePump" }; messagePump.Start(); messagePumpRunning.WaitOne(); } // the message pump thread private void RunMessagePump() { // Create control to handle windows messages MessageHandler messageHandler = new MessageHandler(); // Do something // like initialize a thirdparty library //DLL.Init(messageHandler.Handle); Console.WriteLine("Message Pump thrad Started"); messagePumpRunning.WaitOne(); Application.Run(); } } internal class MessageHandler : NativeWindow { public event EventHandler<MessageData> MessageReceived; public MessageHandler() { CreateHandle(new CreateParams()); } protected override void WndProc(ref Message msg) { // filter message here for your purposes EventHandler<MessageData> handler = MessageReceived; MessageData msgData = new MessageData(msg); if (handler != null) handler(this, msgData); base.WndProc(ref msg); } } // Struct cannot be inherited. class MessageData : EventArgs { private Message _message; public MessageData(Message message) { _message = message; } }
as you can see some third party or some component may rquires a windows message pump to work, what has shown above is that the message pump handle (denoted by the MessageHandler class - inherits from the NativeWindow class ) is passed to the Third party componet, which could be in native code and be able to consume the handle and reconstruct his own message pump out of it.
The current thread (the thread which enters MessagePumpManager will block until the third party component has done with the handle - a typical way of implementing the message pump).
References
相关推荐
This comprehensive overview covers the key points discussed in the preface and introduction of "C# 12 in a Nutshell." The book delves deeper into each of these topics, providing detailed explanations,...
The provided code snippet and description detail a custom `WebClient` implementation in C#. This class is designed to handle HTTP requests and responses, specifically focusing on GET and POST methods....
carry out additional actions which the scripts encapsulate for you especially on ESXi. If you want to run the unlocker directly the parameters are: Usage: ./Unlocker.Linux64 [-h] [-u] [target_...
Based on the provided information from the book "C# 3.0 With the .NET Framework 3.5 Unleashed," we can extract several key points and concepts that are essential for understanding the fundamentals of ...
carry out additional actions which the scripts encapsulate for you especially on ESXi. If you want to run the unlocker directly the parameters are: Usage: ./Unlocker.Linux64 [-h] [-u] [target_...
carry out additional actions which the scripts encapsulate for you especially on ESXi. If you want to run the unlocker directly the parameters are: Usage: ./Unlocker.Linux64 [-h] [-u] [target_...
The two appendices provide additional resources and a commentary on the guide itself, enhancing the learning experience and encouraging exploration beyond the textbook. In conclusion, the "MATLAB ...
You are monitoring a filesystem on a Solaris operating system using Veritas Volume Manager when the following kernel message appears: WARNING: msgcntx: mesg069: V-2-69: memory usage specified by the ...
- Models represent the data layer and encapsulate the application’s logic. They interact with the database through the Active Record pattern, handling data retrieval and storage operations. 2. **...
It will also act as a reference guide with useful examples on resolving problems with object-oriented code in Python, JavaScript, and C#. Table of Contents Chapter 1: Javascript Primer Chapter 2: ...
More advanced topics include programming with Threads with a practical example of a Folder Watcher--a program that watches directories for changes. Modern Windows programming requires some knowledge ...
mobile devices, and platforms.You'll strategize and handle a rich web UI using the advanced WebDriver API and learn techniques to handle real-time challenges in WebDriver. You'll perform different ...
Chapter 5 of the "计算机网络英文题库(附答案)chapter5.pdf" focuses on the Link Layer and Local Area Networks (LANs). Here, we will delve into the key concepts and知识点 related to this chapter. 1. A ...
Aristeidis has a strong background in various programming languages and technologies, with a focus on front-end development. He is passionate about sharing his knowledge and has contributed to ...
Written in C++, with the help of 30 core developers and 1,700 contributors, this portable middleware has evolved to encapsulate and augment a wide range of native OS capabilities essential to support...