Как прослушивать широковещательные сообщения Windows в .NET?

у меня есть объект (т.е. не форма), который хочет прослушивать широковещательные сообщения из Windows, например:

Каков механизм в .NET для настройки окна, отличного от WinForm, которое может прослушивать широковещательные сообщения?

т.е. Существует ли класс WindowsListener ?

Bonus Chatter

Раньше в других средах разработки фреймворк предоставлял функцию AllocateHwnd :

HWND listener = AllocateHWnd(ListenerWindowProc);

где ListenerWindowProc был моей оконной процедурой методом:

private void ListenerWindowProc(ref Message msg)
{
    switch (msg.msg)
    {
       case WM_SETTINGCHANGE: 
       {
          ...
       }
       break;
       case WM_POWERBROADCAST:
       {
          ...
       }
       break;
       case WM_THEMECHANGED: 
       {
          ...
       }
       break;
       ...
   }
   DefWindowProc(msg);
}

Секретным соусом была функция AllocateHwnd :

Псевдокод:

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)));
   }
}

С намного большим количеством секретного кода связанный с UtilWindowClass .

И когда вы закончите, вы должны DeallocateHwnd :

DeallocateHwnd(listenerWindow);

Я знаю, что где-то глубоко в платформе .NET они собираются ответить на WM_SETTINGCHANGE и обновить внутренние структуры данных .NET. . я бы украл этот код, но Reflector не находит ссылки на WM_SETTINGCHANGE ; предположительно потому, что декомпилированный код не показывает имя константы , а только константу 0x001A .

Обновление :

Примечание : этот объект должен быть автономным. Любой, кто использует этот класс, не должен изменять свое приложение, чтобы мой класс возвращал правильные данные. Он должен прослушивать широковещательные сообщения из самой Windows и не требовать от разработчика изменения своего приложения для прослушивания определенных сообщений для меня (т.е. он не должен нарушать инкапсуляцию сложной или усложняющей операции)

Например:

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);
    }

5
задан Ian Boyd 17 February 2012 в 16:33
поделиться