Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Обработка WM_POWERBROADCAST в потоке: проблемы и решения на Delphi

Delphi , ОС и Железо , Справочник по сообщениям

Оригинальный заголовок:

How to receive WM_POWERBROADCAST inside of a thread?

Описание проблемы

Пользователь сталкивает с трудностями в получении уведомления WM_POWERBROACAST от Windows внутри созданного потока. В стандартном приложении VCL Forms, работающем в главном потоке, уведомление получается корректно. Однако, когда компонент, обрабатывающий это сообщение, создается внутри потока, WM_POWERBROACAST не доставляется.

Контекст запроса

Предоставлен исходный код компонента TPowerMonitor, который обрабатывает WM_POWERBROACAST и связанные настройки питания. В коде используется AllocateHWnd для создания окна, в оконной процедуре которого обрабатывается сообщение. В потоке TDataThread также пытается обработать это сообщение, но безуспешно.

Подтвержденный ответ

Для получения WM_POWERBROACAST в потоке необходимо создать окно с оконной процедурой, которая будет обрабатывать это сообщение. В Windows, WM_POWERBROACAST не является посланным сообщением, его необходимо обрабатывать через оконную процедуру. Важно, чтобы поток имел цикл обработки сообщений, например, с помощью функций GetMessage, TranslateMessage, DispatchMessage.

Альтернативный ответ

Код, предоставленный в вопросе, пытается обработать WM_POWERBROACAST внутри потока, но использует DefWindowProc для необработанных сообщений, что неверно. Вместо этого, следует зарегистрировать собственную оконную процедуру с помощью RegisterClass и затем обработать WM_POWERBROACAST внутри этой процедуры.

Шаги для решения проблемы:

  1. Создать оконную процедуру для обработки WM_POWERBROACAST.
  2. В конструкторе потока TDataThread зарегистрировать эту оконную процедуру с помощью RegisterClass.
  3. В оконной процедуре обработать WM_POWERBROACAST.
  4. В цикле обработки сообщений потока Execute использовать GetMessage, TranslateMessage, DispatchMessage для обработки сообщений.
unit TDataThread;
interface
uses
  System.Classes, Winapi.Windows, Winapi.Messages;

type
  TDataThread = class(TThread)
  private
    FTitle: string;
    FWndClass: TWndClass;
    FWndProc: TWndProc;
    FWnd: HWND;
    procedure HandlePowerMessage(var Msg: TMessage);
  protected
    procedure Execute; override;
    procedure DoTerminate; override;
  public
    constructor Create(const Title: string); reintroduce;
  end;

implementation

constructor TDataThread.Create(const Title: string);
begin
  inherited Create(True);
  FTitle := Title;
  with FWndClass do
  begin
    Style := 0;
    lpfnWndProc := @HandlePowerMessage;
    cbWndExtra := 0;
    cbClsExtra := 0;
    hbrBackground := COLOR_WINDOW;
    hIcon := LoadIcon(NULL, IDI_INFORMATION);
    hCursor := LoadCursor(NULL, IDC_ARROW);
    hInstance := HInstance;
    lpszClassName := PChar(Self.ClassName);
  end;
end;

function TDataThread.HandlePowerMessage(var Msg: TMessage): LRESULT; stdcall;
begin
  if Msg.Msg = WM_POWERBROACAST then
  begin
    // Обработка сообщения WM_POWERBROACAST
    Result := 0;
  end
  else
    Result := DefWindowProc(Msg.HWnd, Msg.Msg, Msg.WParam, Msg.LParam);
end;

procedure TDataThread.Execute;
var
  Msg: TMsg;
begin
  if RegisterClass(FWndClass) = 0 then
    Exit;
  FWnd := CreateWindow(FWndClass.lpszClassName, PChar(FTitle), WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, 0, 0, HInstance, nil);
  if FWnd = 0 then
    Exit;
  while GetMessage(Msg, FWnd, 0, 0) > 0 do
  begin
    if Terminated then
      Break;
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end;
procedure TDataThread.DoTerminate;
begin
  if FWnd > 0 then
    DestroyWindow(FWnd);
  UnregisterClass(FWndClass.lpszClassName, HInstance);
end;
end;

Заключение

Следует заметить, что для корректной работы WM_POWERBROACAST необходимо, чтобы поток имел цикл обработки сообщений, и что AllocateHWnd не является подходящим способом для создания окна в потоке, предназначенном для приема этого сообщения.

Создано по материалам из источника по ссылке.

Пользователь пытается получить уведомление `WM_POWERBROADCAST` от Windows внутри созданного потока в среде разработки VCL Forms.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Справочник по сообщениям ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 11:38:14/0.0058808326721191/1