Question

je dois savoir quand ma demande un recieves WM_SETTINGCHANGE message (anciennement connu sous le nom WM_WININICHANGE ).

Le problème est que la pompe de message dans TApplication il envoie dans un trou noir (gestionnaire par défaut) avant que je puisse avoir une chance de le voir:

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;

La procédure CheckIniChange() ne jette pas tout état de cause, je peux gérer, ni ne Mouse.SettingChanged().

Et une fois le chemin de code atteint Default, il est envoyé dans le trou de vidange de DefWindowProc, de ne jamais être revu (depuis la première chose que l'WndProc n'est réglé le Message.Result à zéro.

i espérait affecter un gestionnaire à un événement TApplicationEvents.OnMessage:

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

Mais l'événement ne OnMessage est jeté pour les messages qui passent par la pompe de message. Étant donné que le message WM_SETTINGCHANGE est « manipulé », il ne voit jamais le

PeekMessage
TranslateMessage
DispatchMessage
système

.

Comment puis-je répondre aux fenêtres WM_SETTINGCHANGE de diffusion?

Était-ce utile?

La solution

Edit2: Pour les anciennes versions de l'interception habituelle message doit travailler ...

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

Edit: Oups! N'a pas vu qu'il était pour D5. Ce qui suit était D2007 +.

Utilisez un OnSettingChange dans votre application:

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

Vous pouvez tester avec ce code. Essayez de changer la hauteur ou le côté amarrage du ... 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;

Autres conseils

La réponse était à ma question, ce qui est dangereux, non documenté, l'utilisation de 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;

Vous le manipuler comme vous le feriez pour tout autre message. gestionnaire par défaut de TApplication volonté la route correctement si vous configurez un gestionnaire de messages pour lui:

// 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;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top