Link to home
Start Free TrialLog in
Avatar of CodingCat
CodingCat

asked on

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

Avatar of Bob Learned
Bob Learned
Flag of United States of America image

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?
Avatar of CodingCat
CodingCat

ASKER

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.
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?  
I am not sure what that NativeWindow code is doing, and you didn't indicate where I could read about it.
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.
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
not exactly the answer im looking for