У меня есть Object
(т.е. не форма), которая хочет прослушивать широковещательные сообщения из Windows, например ::
Каков механизм в .NET для настройки окна, отличного от WinForm, которое может прослушивать широковещательные сообщения?
т.е. Есть ли класс WindowsListener
?
Бонусная болтовня
В прежние времена в других средах разработки платформа обеспечивала функцию 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 Framework они будут отвечать на 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);
}