title: How to listen for Windows broadcast messages in .NET?
body: <p>i have an <code>Object</code> (i.e. not a form) that wants to listen for broadcast messages from Windows, e.g.:</p>
  
  <ul>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms725497%28v=vs.85%29.aspx" rel="nofollow"><code>WM_SETTINGCHANGE</code></a></li>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd388198%28v=vs.85%29.aspx" rel="nofollow"><code>WM_DWMCOLORIZATIONCOLORCHANGED</code></a></li>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd388199%28v=vs.85%29.aspx" rel="nofollow"><code>WM_DWMCOMPOSITIONCHANGED</code></a></li>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms632650%28v=vs.85%29.aspx" rel="nofollow"><code>WM_THEMECHANGED</code></a></li>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa373247%28v=vs.85%29.aspx" rel="nofollow"><code>WM_POWERBROADCAST</code></a></li>
  </ul>
  
  <p>What is the mechanism in .NET to setup a non-WinForm's window, that can listen for broadcast messages?</p>
  
  <p>i.e. Is there a <code>WindowsListener</code> class?</p>
  
  <h2>Bonus Chatter</h2>
  
  <p>In the olden days, in other development environments, the framework provided an <a href="http://function%20AllocateHWnd%28AMethod%3a%20TWndMethod%29%3a%20HWND;" rel="nofollow"><code>AllocateHwnd</code></a> function:</p>
  
  <pre><code>HWND listener = AllocateHWnd(ListenerWindowProc);
  </code></pre>
  
  <p>where <code>ListenerWindowProc</code> was my <em>window procedure</em> method:</p>
  
  <pre><code>private void ListenerWindowProc(ref Message msg)
  {
      switch (msg.msg)
      {
         case WM_SETTINGCHANGE: 
         {
            ...
         }
         break;
         case WM_POWERBROADCAST:
         {
            ...
         }
         break;
         case WM_THEMECHANGED: 
         {
            ...
         }
         break;
         ...
     }
     DefWindowProc(msg);
  }
  </code></pre>
  
  <p>The secret sauce was the <code>AllocateHwnd</code> function:</p>
  
  <p><strong>Pseudo-code:</strong></p>
  
  <pre><code>public static HWND AllocateHWnd(WndMethod method)
  {
     HWND result;
     WNDCLASS tempClass;
     Boolean classRegistered;
  
     UtilWindowClass.hInstance := HInstance;
     Boolean classRegistered = GetClassInfo(HInstance, UtilWindowClass.lpszClassName, tempClass);
     if (!classRegistered || (tempClass.lpfnWndProc != @DefWindowProc)
     {
        if classRegistered
        {
           UnregisterClass(utilWindowClass.lpszClassName, HInstance);
           RegisterClass(utilWindowClass);
        }
        result = CreateWindowEx(WS_EX_TOOLWINDOW, UtilWindowClass.lpszClassName,
              '', WS_POPUP, 0, 0, 0, 0, 0, 0, HInstance, null);
        if (!Method != null)
           SetWindowLong(result, GWL_WNDPROC, UInt32(MakeObjectInstance(Method)));
     }
  }
  </code></pre>
  
  <p>With a whole lot more secret code associated with <code>UtilWindowClass</code>. </p>
  
  <p>And when you were done you would <a href="http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_DeallocateHWnd.html" rel="nofollow">DeallocateHwnd</a>:</p>
  
  <pre><code>DeallocateHwnd(listenerWindow);
  </code></pre>
  
  <p>i know somewhere deep in the .NET framework they are going to respond to <code>WM_SETTINGCHANGE</code> and update internal .NET data structures. i would steal that code, but Reflector finds no reference to <code>WM_SETTINGCHANGE</code>; presumably because the decompiled code doesn't show the <em>constant name</em>, just the constant <strong>0x001A</strong>.</p>
  
  <p><strong>Update</strong>: </p>
  
  <p><strong>Note</strong>: This object should be self-contained. Anyone using the class should not have to modify their application in order for my class to return correct data. It should listen to broadcasts from Windows itself, and not require a developer to modify their application to listen for certain messages for me (i.e. it should not break encapsulation of the difficult or complication operation)</p>
  
  <p>For example:</p>
  
  <pre><code>public class FrobbingGrobber: IDisposable
  {
      private IntPtr hwnd = IntPtr.Zero;
  
      public FrobbingGrobber
      {
         _hwnd = AllocateHwnd(listenerWindowProc);
      }
  
      protected virtual void listenerWindowProc(ref Message msg)
      {
         switch (msg.msg)
         {
            case WM_DwmColorizationColorChanged, WM_DwmCompositionChanged: 
            {
                UpdateColorizationColor();
            }
            break;
         }
         DefWindowProc(msg);
      }
  
      public void UpdateColorizationColor()
      {
          NativeMethods.DwmGetColorizationColorParameters_UndocumentedExport137(ref _color);
      }
  
      public void Dispose()
      {
          Dispose(true);
      }
  
      protected void Dispose(Boolean safeToDisposeManagedObjects)
      {
         if (_hwnd != 0)
         {
            DeallocateHwnd(_hwnd);      
            _hwnd = 0;
         }
  
         if (safeToDisposeManagedObjects)
            GC.SuppressFinalize(this);
      }
  
      public ~FrobbingGrobber
      {
         //If the user forgot to call Dispose i could (correctly) leak a handle, 
         //or i could fix their mistake for them
         Dispose(false);
      }
  </code></pre>