Delphi: how to respond to WM_SettingChange / WM_WinIniChange?

I need to know when my application receives a message WM_SETTINGCHANGE(formerly known as WM_WININICHANGE).

The problem is that the message pump in TApplication sends it through a black hole (default handler) before I can see it.

procedure TApplication.WndProc(var Message: TMessage);
...
begin
   Message.Result := 0;

   for I := 0 to FWindowHooks.Count - 1 do
      if TWindowHook(FWindowHooks[I]^)(Message) then Exit;

   CheckIniChange(Message);

   with Message do
      case Msg of
      WM_SETTINGCHANGE:
         begin
            Mouse.SettingChanged(wParam);
            Default;   <----------------------*poof* down the sink hole
         end;
      ...
      end;
      ...
end;

The procedure CheckIniChange()does not generate any event that I can handle, and not Mouse.SettingChanged().

And as soon as the code path is reached Default, it goes down through the drain hole DefWindowProc, which will never be visible (since the first thing WndProc does is set Message.Resultto zero.

I was hoping to assign a handler to the TApplicationEvents.OnMessage event:

procedure TdmGlobal.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
   case Msg.message of
   WM_SETTINGCHANGE:
      begin
         // Code
      end;
   end;
end;

OnMessage , . WM_SETTINGCHANGE "",

PeekMessage
TranslateMessage
DispatchMessage

.

Windows WM_SETTINGCHANGE?

+3
3

Edit2: ...

[...]
  private
    procedure WMSettingChange(var Message: TWMSettingChange); message WM_SETTINGCHANGE;
[...]
procedure TForm1.WMSettingChange(var Message: TWMSettingChange);
begin
  showMessage('SettingChange message intercept');
end;

: ! , D5. D2007 + .

OnSettingChange :

procedure TApplication.SettingChange(var Message: TWMSettingChange);
begin
  if Assigned(FOnSettingChange) then
    with Message do
      FOnSettingChange(Self, Flag, Section, Result);
end;

. TaskBar...

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnSettingChange := MySettingChange;
end;

procedure TForm1.MySettingChange(Sender: TObject; Flag: Integer;
  const Section: string; var Result: Integer);
begin
  showMessage('setting changed');
end;
+9

: , HookMainWindow:

procedure TdmGlobal.DataModuleCreate(Sender: TObject);
begin
   ...
   Application.HookMainWindow(SettingChangeHook);
end;

procedure TdmGlobal.DataModuleDestroy(Sender: TObject);
begin
   Application.UnhookMainWindow(SettingChangeHook);
end;

function TdmGlobal.SettingChangeHook(var Message: TMessage): Boolean;
begin
   case Message.Msg of
   WM_SETTINGCHANGE:
      begin
         //Handler code
      end;
   end;

   Result := False; //continue processing
end;
+2

You process it just like any other message. The default TApplication handler will send it correctly if you configure a message handler for it:

// interface
type
  TYourMainForm = class(TForm)
    // other stuff
  private
    procedure WMSettingChange(var Msg: TWMSettingChange); message WM_SETTINGCHANGE;
  end;

// implementation
procedure TYourMainForm.WMSettingChange(var Msg: TWMSettingChange); message WM_SETTINGCHANGE;
begin
  // Whatever handling here. TWMSettingChange is defined in Messages.pas
end;
+2
source

Source: https://habr.com/ru/post/1745162/


All Articles