• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1770
  • Last Modified:

NativeWindow sample code

hi all,

I have several questions regarding the NativeWindow sample code from MSDN (attached with some changes).

1) what messages are passed to MyNativeWndow class? This class is instantiated as a button on the main form, but the overrided WndProc is never called.

2) how's the windows message dispatched and circle around? Is there an order that  determines which control received the message first and pass to the next control?

3) both MyNativeWindowListener and MyNativeWindow need the main form to be passed in as the parent form.  Is this a must to receive the windows messages?  If so, is it possible to acquire the parent form without explicitly pass it in constructors?  For example, use something like:

System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle

I've tried this (above code) but got 0 for the handler.

4) if it's possible to implicitly get the main form of the current process, can I call AssignHandle() method in NativeWindow object's constructor instead of in the HandleCreated event handler of the parent form?
using System;
using System.Windows.Forms;

namespace NativeWindowSample
{
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public partial class Form1 : 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());
        }

        public Form1()
        {
            InitializeComponent();
            this.Size = new System.Drawing.Size(300, 300);
            this.Text = "Form1";
            this.Name = "Form1";

            nwl = new MyNativeWindowListener(this);
            nw = new MyNativeWindow(this);
        }


    }

    // NativeWindow class to listen to operating system messages.
    [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;

        System.Diagnostics.Process process;

        public MyNativeWindowListener(Form1 parent)
        {
            parent.HandleCreated += new EventHandler(this.OnHandleCreated);
            parent.HandleDestroyed += new EventHandler(this.OnHandleDestroyed);
            this.parent = parent;
        }

        // Listen for the control's window creation and then hook into it.
        internal void OnHandleCreated(object sender, EventArgs e)
        {
            // Window is now created, assign handle to NativeWindow.
            // AssignHandle(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);
            process = System.Diagnostics.Process.GetCurrentProcess();
            process.WaitForInputIdle();
            
            IntPtr pt = process.MainWindowHandle;
            IntPtr pt2 = ((Form1)sender).Handle;
            IntPtr pt3 = parent.Handle;
            //AssignHandle(pt);
            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));
                    //System.Diagnostics.Debug.WriteLine("Listener received.");
                    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";

            // 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;

            // Create the actual window
            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)
        {
            // Listen for messages that are sent to the button window. Some messages are sent
            // to the parent window instead of the button's window.

            switch (m.Msg)
            {
                case WM_ACTIVATEAPP:
                    // Do something here in response to messages
                    //MessageBox.Show("Application activated.");
                    break;
            }
            base.WndProc(ref m);
        }
    }

}

Open in new window

0
CodingCat
Asked:
CodingCat
  • 4
  • 4
1 Solution
 
Bob LearnedCommented:
Ok, another question where I have to dig through code to find a way to answer a question.  Where did you get the NativeWindow code from MSDN?
0
 
CodingCatAuthor Commented:
0
 
Bob LearnedCommented:
Thank you!!

It would be good to know the bigger picture.  What is NativeWindow doing for you that an IMessageFilter can't.  

There is a little bit going on with the code from that MSDN article, which will take some time to figure out.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
CodingCatAuthor Commented:
I dont know what NativeWindow can that IMessageFilter cannot. I used NativeWindow for my project and it worked.  Would you please give me an example of using IMessageFilter to accomplish the same task shown in the NativeWindow sample code?  
0
 
Bob LearnedCommented:
I am not sure what that NativeWindow code is doing, and you didn't indicate where I could read about it.
0
 
CodingCatAuthor Commented:
what do you mean that I didn't indicate where to read about it? it's the MSDN link I gave in my response. Besides, I've posted the code (slightly modified, but functionally the same) with my question.
0
 
Bob LearnedCommented:
Aah, yes, you did...forgot about that one after I got back from vacation.  IMessageFilter is a little different approach, but can listen for messages, like WM_ACTIVATEAPP, but it is at the application level, instead of the form level.  Any class that has an PreFilterMessage method can implement IMessageFilter.

Here is an example of using IMessageFilter:

Using IMessageFilter class in C#
http://geekswithblogs.net/Jaggi/archive/2006/02/02/67999.aspx
public class TestMessageFilter : IMessageFilter
 {
  private Form1 FOwner; //instance of the form in which you want to handle this pre-processing
  const int WM_KEYUP         = 0x101;
  public TestMessageFilter(Form1 aOwner)
  {
   FOwner = aOwner;
  }

  public bool PreFilterMessage(ref Message m)
  {
    bool ret = true;
   if (m.Msg == WM_KEYUP)
   {          
      Keys key = (Keys)(int)m.WParam & Keys.KeyCode;
  if(key = =  Keys.Y)
 {
    if((int)Control.ModifierKeys == ((int)Keys.Control + (int)Keys.Alt))
     {
                //got it......
     }
     else
            { ret = false;
             } 
       
        }   
           
             return ret;
   }
   else
   {
    return false;
   } 
  }
 }
 }

Open in new window

0
 
CodingCatAuthor Commented:
not exactly the answer im looking for
0

Featured Post

Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now