vbAccelerator - Contents of code file: ActivateChangedSubclass.cs

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace vbAccelerator.Components.SubClassExamples
{

   // note that in this example I'm using Interfaces
   // to notify the caller of a change.  However, you
   // could equally use events for the notifications,
   // there is just a little more overhead that way.

   #region ActivationChange SubClass
   /// <summary>
   /// Activation state change type.
   /// </summary>
   public enum ActivationStateChangeType : int
   {
      /// <summary>
      /// The form is inactive
      /// </summary>
      WA_INACTIVE     = 0,
      /// <summary>
      /// The form is active
      /// </summary>
      WA_ACTIVE       = 1,
      /// <summary>
      /// The form has been clicked to make it active
      /// </summary>
      WA_CLICKACTIVE  = 2
   }

   /// <summary>
   /// Interface for receiving Activation State Change notifications
   /// </summary>
   public interface IActivateChangeNotify
   {
      /// <summary>
      /// Notifies of an Activation state change in the window
      /// </summary>
      /// <param name="changeType">Type of activation change</param>
      void ActivateChanged(ActivationStateChangeType changeType);
   }

   /// <summary>
   /// Class for notifying of Activation state changes
   /// for a Window.
   /// </summary>
   public class ActivateChangeSubclass :  
      System.Windows.Forms.NativeWindow, 
      IDisposable
   {
      /// <summary>
      /// Stores user defined data
      /// </summary>
      private object tag = null;
      /// <summary>
      /// Stores the notify interface object, if any
      /// </summary>
      private IActivateChangeNotify notify = null;

      /// <summary>
      /// Message send to a window when activation state
      /// changes
      /// </summary>
      private const int WM_ACTIVATE = 0x6;

      /// <summary>
      /// Processes window messages and notifies of any activation
      /// state changes.
      /// </summary>
      /// <param name="m"></param>
      protected override void WndProc(ref System.Windows.Forms.Message m)
      {
         // always perform default:
         base.WndProc(ref m);
         // If message is activate and a notifier
         // is in place then notify it:
         if (m.Msg == WM_ACTIVATE)
         {
            if (notify != null)
            {
               notify.ActivateChanged(
                  (ActivationStateChangeType)((int)m.WParam));
            }
         }
      }

      /// <summary>
      /// Gets/sets a user-defined object associated with the class
      /// </summary>
      public object Tag
      {
         get
         {
            return this.tag;
         }
         set
         {
            this.tag = value;
         }
      }
      
      /// <summary>
      /// Gets/sets the interface to notify of activation changes
      /// </summary>
      public IActivateChangeNotify Notify
      {
         get
         {
            return this.notify;
         }
         set
         {
            this.notify = value;
         }
      }

      /// <summary>
      /// Clears up resources associated with this object
      /// </summary>
      public void Dispose()
      {
         if (this.Handle != IntPtr.Zero)
         {
            this.ReleaseHandle();
         }
      }

      /// <summary>
      /// Creates a new instance of the ActivateChangeSubclass
      /// object and starts checking for Activate state changes
      /// </summary>
      /// <param name="handle">Handle of window to check for
      /// Activation State changes</param>
      /// <param name="tag">User defined data</param>
      /// <param name="notify">Object to receive Activtion state
      /// change notifications</param>
      public ActivateChangeSubclass(
         IntPtr handle, 
         object tag,
         IActivateChangeNotify notify
         )
      {
         this.AssignHandle(handle);
         this.tag= tag;
         this.notify = notify;
      }
   }
   #endregion
}